Python+OpenCV图像处理实验

2021-01-20 10:53:00 浏览数 (1)

目录

1、灰度化功能

2、反转功能

3、通道分离功能

4、噪音、滤波功能

5、高斯双边滤波功能

6、均值偏移滤波功能

7、图像二值化功能

8、Canny边缘检测功能

9、直线检测功能

10、圆形检测功能

11、轮廓发现功能

12、人脸检测功能


这个项目是我在GitHub上看到的,和我之前的Python OpenCV实时图像处理,异曲同工,只不过是我对实时视频的处理,这个是图像处理,功能上感觉这个项目更加全面一些,特学习并分享~

该项目可实现图像的多样化处理,基本上包含了OpenCV模块常用的图像处理功能,非常适合初学者理解和应用,包括:灰度化功能、反转功能、通道分离功能、噪音滤波功能、高斯双边滤波功能、均值偏移滤波功能、图像二值化功能、Canny边缘检测功能、直线检测功能、圆形检测功能、轮廓发现功能和人脸检测功能。

1、灰度化功能

灰度化功能,效果如下所示:

实现代码如下所示:

代码语言:javascript复制
    # 灰度化
    def to_gray(self):
        src = self.cv_read_img(self.src_file)
        if src is None:
            return
        gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
        # print("类型", type(gray))
        # get_image_info(gray)
        self.decode_and_show_dst(gray)

2、反转功能

反转功能,按位取反,白变黑,黑变白,效果如下所示:

实现代码如下所示:

代码语言:javascript复制
    # 反转
    def bitwise_not(self):
        src = self.cv_read_img(self.src_file)
        if src is None:
            return
        dst = cv.bitwise_not(src)  
        self.decode_and_show_dst(dst)

3、通道分离功能

通道分离功能,效果如下所示:

实现代码如下所示:

代码语言:javascript复制
    # 通道分离
    def channels_split(self):
        src = self.cv_read_img(self.src_file)
        if src is None:
            return
        b, g, r = cv.split(src)
        merge_image = cv.merge([b, g, r])
        """创建三维数组,0维为B,1维为G,2维为R"""
        height, width, channels = src.shape
        img = np.zeros([height*2, width*2, channels], np.uint8)
        img[0:height, 0:width] = np.expand_dims(b, axis=2)
        img[0:height, width:width*2] = np.expand_dims(g, axis=2)
        img[height:height*2, 0:width] = np.expand_dims(r, axis=2)
        img[height:height*2, width:width*2] = merge_image

        self.decode_and_show_dst(img)

4、噪音、滤波功能

图像处理中噪声:主要有三种:

  • 椒盐噪声(Salt & Pepper):含有随机出现的黑白亮度值。
  • 脉冲噪声:只含有随机的正脉冲和负脉冲噪声。
  • 高斯噪声:含有亮度服从高斯或正态分布的噪声。高斯噪声是很多传感器噪声的模型,如摄像机的电子干扰噪声。

滤波器主要两类:线性和非线性

  • 线性滤波器:使用连续窗函数内像素加权和来实现滤波,同一模式的权重因子可以作用在每一个窗口内,即线性滤波器是空间不变的。

如果图像的不同部分使用不同的滤波权重因子,线性滤波器是空间可变的。因此可以使用卷积模板来实现滤波。线性滤波器对去除高斯噪声有很好的效果。常用的线性滤波器有均值滤波器和高斯平滑滤波器。

(1) 均值滤波器:最简单均值滤波器是局部均值运算,即每一个像素只用其局部邻域内所有值的平均值来置换。

(2) 高斯平滑滤波器是一类根据高斯函数的形状来选择权值的线性滤波器。 高斯平滑滤波器对去除服从正态分布的噪声是很有效的。

  • 非线性滤波器:

(1) 中值滤波器:均值滤波和高斯滤波运算主要问题是有可能模糊图像中尖锐不连续的部分。中值滤波器的基本思想使用像素点邻域灰度值的中值来代替该像素点的灰度值,它可以去除脉冲噪声、椒盐噪声同时保留图像边缘细节。中值滤波不依赖于邻域内与典型值差别很大的值,处理过程不进行加权运算。中值滤波在一定条件下可以克服线性滤波器所造成的图像细节模糊,而对滤除脉冲干扰很有效。

(2) 边缘保持滤波器:由于均值滤波:平滑图像外还可能导致图像边缘模糊和中值滤波:去除脉冲噪声的同时可能将图像中的线条细节滤除。边缘保持滤波器是在综合考虑了均值滤波器和中值滤波器的优缺点后发展起来的,它的特点是:滤波器在除噪声脉冲的同时,又不至于使图像边缘十分模糊。

过程:分别计算[i,j]的左上角子邻域、左下角子邻域、右上角子邻域、右下角子邻域的灰度分布均匀度V;然后取最小均匀度对应区域的均值作为该像素点的新灰度值。分布越均匀,均匀度V值越小。v=<(f(x, y) - f_(x, y))^2

噪音、滤波功能,效果如下所示:

实现代码如下所示:

代码语言:javascript复制
    def noise_and_blur(self):
        src = self.cv_read_img(self.src_file)
        if src is None:
            return

        # 加高斯噪声
        h, w, c = src.shape
        for row in range(h):
            for col in range(w):
                s = np.random.normal(0, 20, 3)  # normal(loc=0.0, scale=1.0, size=None),均值,标准差,大小

                b = src[row, col, 0]
                g = src[row, col, 1]
                r = src[row, col, 2]

                src[row, col, 0] = clamp(b   s[0])
                src[row, col, 1] = clamp(g   s[1])
                src[row, col, 2] = clamp(r   s[2])

        img = np.zeros([h * 2, w * 2, c], np.uint8)
        img[0:h, 0:w] = src

        # GaussianBlur(src, ksize, sigmaX, dst=None, sigmaY=None, borderType=None)
        # ksize表示卷积核大小,sigmaX,Y表示x,y方向上的标准差,这两者只需一个即可,并且ksize为大于0的奇数
        dst = cv.GaussianBlur(src, (5, 5), 0)  # 高斯模糊,sigmaX与ksize一个为0
        img[0:h, w:w*2] = dst

        self.decode_and_show_dst(img)

5、高斯双边滤波功能

高斯双边滤波功能,同时考虑空间与信息和灰度相似性,达到保边去噪的目的。双边滤波的核函数是空间域核与像素范围域核的综合结果:在图像的平坦区域,像素值变化很小,对应的像素范围域权重接近于1,此时空间域权重起主要作用,相当于进行高斯模糊;在图像的边缘区域,像素值变化很大,像素范围域权重变大,从而保持了边缘的信息。效果如下所示:

实现代码如下所示:

代码语言:javascript复制
    # 高斯双边滤波
    def bilateral_filter(self):
        src = self.cv_read_img(self.src_file)
        if src is None:
            return

        dst = cv.bilateralFilter(src, 0, 100, 15)
        self.decode_and_show_dst(dst)

6、均值偏移滤波功能

均值偏移滤波功能,效果如下所示:

实现代码如下所示:

代码语言:javascript复制
    # 均值偏移滤波
    def mean_shift_filter(self):
        src = self.cv_read_img(self.src_file)
        if src is None:
            return

        dst = cv.pyrMeanShiftFiltering(src, 10, 50)  # 均值偏移滤波
        self.decode_and_show_dst(dst)

7、图像二值化功能

图像二值化功能,效果如下所示:

实现代码如下所示:

代码语言:javascript复制
    # 图像二值化
    def threshold(self):
        src = self.cv_read_img(self.src_file)
        if src is None:
            return

        gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)

        # 这个函数的第一个参数就是原图像,原图像应该是灰度图。
        # 第二个参数就是用来对像素值进行分类的阈值。
        # 第三个参数就是当像素值高于(有时是小于)阈值时应该被赋予的新的像素值
        # 第四个参数来决定阈值方法,见threshold_simple()
        # ret, binary = cv.threshold(gray, 127, 255, cv.THRESH_BINARY)
        ret, dst = cv.threshold(gray, 127, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
        self.decode_and_show_dst(dst)

8、Canny边缘检测功能

Canny边缘检测功能,效果如下所示:

实现代码如下所示:

代码语言:javascript复制
    # Canny边缘检测
    def canny_edge(self):
        src = self.cv_read_img(self.src_file)
        if src is None:
            return

        blurred = cv.GaussianBlur(src, (3, 3), 0)
        gray = cv.cvtColor(blurred, cv.COLOR_BGR2GRAY)

        grad_x = cv.Sobel(gray, cv.CV_16SC1, 1, 0)
        grad_y = cv.Sobel(gray, cv.CV_16SC1, 0, 1)

        dst = cv.Canny(grad_x, grad_y, 30, 150)
        # dst = cv.Canny(gray, 50, 150)
        self.decode_and_show_dst(dst)

9、直线检测功能

直线检测功能,效果如下所示:

实现代码如下所示:

代码语言:javascript复制
    # 直线检测
    def hough_line(self):
        src = self.cv_read_img(self.src_file)
        if src is None:
            return

        gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
        edges = cv.Canny(gray, 50, 150, apertureSize=3)
        lines = cv.HoughLines(edges, 1, np.pi/180, 200)

        for line in lines:
            rho, theta = line[0]
            a = np.cos(theta)
            b = np.sin(theta)
            x0 = a * rho
            y0 = b * rho
            x1 = int(x0 1000*(-b))
            y1 = int(y0 1000*(a))
            x2 = int(x0-1000*(-b))
            y2 = int(y0-1000*(a))
            cv.line(src, (x1, y1), (x2, y2), (0, 0, 255), 2)

        self.decode_and_show_dst(src)

10、圆形检测功能

圆形检测功能,效果如下所示:

实现代码如下所示:

代码语言:javascript复制
    # 圆检测
    def hough_circles(self):
        src = self.cv_read_img(self.src_file)
        if src is None:
            return

        dst = cv.pyrMeanShiftFiltering(src, 10, 100)
        cimage = cv.cvtColor(dst, cv.COLOR_BGR2GRAY)
        circles = cv.HoughCircles(cimage, cv.HOUGH_GRADIENT, 1, 20, param1=50, param2=30, minRadius=0, maxRadius=0)
        circles = np.uint16(np.around(circles))
        for i in circles[0, :]:
            cv.circle(src, (i[0], i[1]), i[2], (0, 0, 255), 2)
            cv.circle(src, (i[0], i[1]), 2, (255, 0, 255), 2)

        self.decode_and_show_dst(src)

11、轮廓发现功能

轮廓发现功能,并进行覆盖,效果如下所示:

实现代码如下所示:

代码语言:javascript复制
    # 轮廓发现
    def find_contours(self):
        src = self.cv_read_img(self.src_file)
        if src is None:
            return

        dst = cv.GaussianBlur(src, (3, 3), 0)
        gray = cv.cvtColor(dst, cv.COLOR_BGR2GRAY)
        ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
        contous, heriachy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
        for i,contou in enumerate(contous):
            cv.drawContours(src, contous, i, (0, 0, 255), 1)

        # 轮廓
        self.decode_and_show_dst(src)

        # 轮廓覆盖
        for i,contou in enumerate(contous):
            cv.drawContours(src, contous, i, (0, 0, 255), -1)
        self.decode_and_show_dst(src)

12、人脸检测功能

人脸检测功能,效果如下所示:

实现代码如下所示:

代码语言:javascript复制
    #人脸识别 正脸 需要下载xml模型 haarcascade_frontalface_alt.xml
    def face_recognize(self):
        src = self.cv_read_img(self.src_file)
        if src is None:
            return

        gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
        face_cascade = cv.CascadeClassifier('haarcascade_frontalface_alt2.xml')
        faces = face_cascade.detectMultiScale(
            gray,
            scaleFactor=1.15,
            minNeighbors=3,
            minSize=(5, 5)
        )

        for (x, y, w, h) in faces:
            cv.rectangle(src, (x, y), (x   w, y   h), (0, 255, 0), 2)
        self.decode_and_show_dst(src)

请关注微信公众号,回复关键字: 图像处理实验,获取项目文件~

0 人点赞