OpenCV入门之OpenCV的基本操作3

电子说

1.3w人已加入

描述

6、图像的缩放、翻转、旋转、平移、透视

7、卷积操作:均值滤波、方盒滤波、高斯滤波、中值滤波、双边滤波

8、算子操作:sobel算子、scharr算子、拉普拉斯算子、Canny边缘检测

9、形态学操作:腐蚀、膨胀、开运算、闭运算、顶帽、黑帽


6、图像的缩放、翻转、旋转、平移、透视

OpenCV提供了一系列的api,cv.flip、cv.rotate、cv.resize、cv.warpAffine和cv.warpPerspective等,具体算法实现可查看OpenCV的源码。原理简单来说就是要找到像素变换前与变换后的位置坐标对应关系。

平移是物体位置的移动。如果知道在(x,y)方向上的位移,则将其设为(tx, ty),可以创建转换矩阵M,如下所示

计算机视觉

图像旋转角度为θ是通过以下形式的变换矩阵实现的:

计算机视觉

注:证明如下

计算机视觉

OpenCV提供了可缩放的旋转以及可调整的旋转中心,因此可以在任何位置旋转。修改后的变换矩阵为:

计算机视觉

其中

计算机视觉

可以通过cv2.getRotationMatrix2D来获得旋转矩阵,不需要手算。

对于透视变换,需要在输入图像上有4个点,在输出图像上需要相应的点。在这四个点中,其中三个不应共线。然后可以通过函数cv.getPerspectiveTransform找到变换矩阵。

def AffineTrans():
    img = cv2.imread('./images/test.jpg')
    # 图像变换尺寸
    # fx轴和fy轴的缩放比例,interpolation插值方式,cv2.INTER_LINEAR  #默认效果
    # cv2.INTER_NEAREST,cv2.INTER_AREA,cv2.INTER_CUBIC
    img_resize = cv2.resize(img,None,fx=0.5,fy=0.5,interpolation=cv2.INTER_AREA)


    # 图像翻转,flipCode=0:上下翻转,大于0左右翻转,小于0:上下加左右
    img_flip = cv2.flip(img,flipCode=1)
    # 图像旋转
    img_rotate = cv2.rotate(img,rotateCode=cv2.ROTATE_90_CLOCKWISE)


    h,w,c = img.shape
    # 图像平移
    # cv2.warpAffine(src,变换矩阵,输出图像大小,)
    # 变换矩阵,向右移动100个像素,向下移动100个像素
    M = np.float32([[1,0,100],
                    [0,1,100]])
    img_warp = cv2.warpAffine(img,M,dsize=(200,500))


    # 获得变换矩阵,(中心点,按逆时针旋转,scal:缩放比例)
    M_r = cv2.getRotationMatrix2D((300,250),15,1)
    img_rotate_ = cv2.warpAffine(img,M_r,(w,h))


    # 通过三个点确定旋转
    # 需要原图三个点和变换后的三个点对应的坐标
    src = np.float32([[100,200],[300,200],[200,400]])
    dst = np.float32([[200,300],[300,400],[300,500]])
    M1 = cv2.getAffineTransform(src,dst)
    img_r3 = cv2.warpAffine(img,M1,(w,h))


    # 透视变换
    src_p = np.float32([[100,100],[700,100],[100,300],[700,300]])
    dst_p = np.float32([[0,0],[720,0],[0,320],[720,320]])
    M_p = cv2.getPerspectiveTransform(src_p,dst_p)
    img_perspect = cv2.warpPerspective(img,M_p,(w,h))


    cv2.imshow("imshow", img_r3)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

7、卷积操作:均值滤波、方盒滤波、高斯滤波、中值滤波、双边滤波

图像滤波,就是在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制,可以把滤波器想象成一个包含加权系数的窗口,当使用这个滤波器平滑处理图像时,就把这个窗口放到图像之上,透过这个窗口来看我们得到的图像。

而对滤波处理的要求有两个,一是不能损坏图像的轮廓及边缘等重要信息;二是使图像清晰视觉效果好。

用神经网络中的话来说就是用不同的卷积核对图像进行卷积操作,以产生不同的效果。不同的是神经网络中的卷积核通过训练得到,而图像滤波是用已知的卷积核对图像进行卷积。

方盒滤波、均值滤波和中值滤波都可以起到平滑图像,滤去噪声的功能。 均值滤波采用线性的方法,平均整个窗口范围内的像素值 ,均值滤波本身存在着固有的缺陷,即它不能很好地保护图像细节,在图像去噪的同时也破坏了图像的细节部分,从而使图像变得模糊,不能很好地去除噪声点。

均值滤波对高斯噪声表现较好,对椒盐噪声表现较差 。中值滤波采用非线性的方法,它在平滑脉冲噪声方面非常有效,同时它可以保护图像尖锐的边缘,选择适当的点来替代污染点的值,所以处理效果好,对椒盐噪声表现较好,对高斯噪声表现较差。

假设:一个5*5的卷积核,均值滤波则为:

计算机视觉

中值滤波是选取图像中窗口大小范围内的像素点,将这些像素值排序,然后将位于中间位置的像素值作为当前像素点的像素值,让周围的像素值接近真实值,从而消除孤立的噪声点。假设3x3的串口大小,像素排序后为[1,2,5,5,6,7,8,9,11],取其中的中间值6作为卷积后的结果值。

注1:方盒滤波是OpenCV中提供的一个API

方盒滤波卷积核:

计算机视觉

参数a的作用:normalize = true, a = 1/W * H 此时为均值滤波

normalize = false, a=1 此时不进行均值化,输出的结果为25个元素之和。当normalize = true时,方盒滤波 ==平均滤波,一般情况下都使用均值滤波,所以在使用时直接调用均值滤波API

注2:高斯噪声和椒盐噪声

高斯噪声,顾名思义是指服从高斯分布(正态分布)的一类噪声,通常是因为不良照明和高温引起的传感器噪声。

椒盐噪声,通常是由图像传感器,传输信道,解压处理等产生的黑白相间的亮暗点噪声(椒-黑,盐-白)。

高斯滤波就是将为正态分布(“高斯分布”)的卷积核对图像进行卷积操作。

要产生一个高斯滤波模板,以模板的中心位置为坐标原点进行取样。模板在各个位置的坐标,如下图所示(x轴水平向右,y轴竖直向下),用数值代替上面(x, y),假定中心点的坐标为(0, 0),那么距离它周围的八个点的坐标如下:

计算机视觉

更远的点,依次类推,为了计算权重矩阵,需要设定σ的值,假定σ=1.5,则模糊半径为1的权重矩阵如下:

计算机视觉

这九个点的权重综合等于 0.4787147,如果只计算这 9 个点的加权平均,还必须让他们的权重之和等于1,因此上面的九个值还要分别除以 0.4787147,得到最终的权重矩阵:

计算机视觉

卷积后,中心点的值不一定最大,但是其比重是最大的,两边的值可能比较大,但是其比重较小。中心点的值与周围的加权平均了所以图像变模糊了。

双边滤波结合图像的空间邻近度和像素值相似度的一种折中处理,同时考虑空域信息和灰度相似性,可以保留边缘,同时可以对边缘内的区域进行平滑处理 。双边滤波器顾名思义比高斯滤波多了一个高斯方差sigma-d,它是基于空间分布的高斯滤波函数,所以在边缘附近,离的较远的像素不会太多影响到边缘上的像素值,这样就保证了边缘附近像素值的保存。但是由于保存了过多的高频信息,对于彩色图像里的高频噪声,双边滤波器不能够干净的滤掉,只能够对于低频信息进行较好的滤波。

公式中可以看到,因为边缘附近的灰度值差比较大,所以如果遇到边缘附近,灰度信息的权重比较大,所以中心点权重比较大,保留了边缘信息。

def Convolution():
    img = cv2.imread('./images/test.jpg')
    # 卷积核测试
    kernel_blur = np.ones([3,3],np.float32)/9
    kernel1 = np.array([[-1,-1,-1],[-1,8,-1],[-1,-1,-1]])
    kernel2 = np.array([[-2,1,0],[-1,1,1],[0,1,2]])
    kernel3 = np.array([[0,-1,0],[-1,5,-1],[0,-1,0]])
    new_img = cv2.filter2D(img,-1,kernel3)
    # 方盒滤波、均值滤波
    img_box = cv2.boxFilter(img,-1,(5,5),normalize=True)
    img_blur = cv2.blur(img,(5,5))


    # 高斯滤波 sigma越大越模糊标准差越大,ksize越大越模糊,适合雪花点
    img_gauss = cv2.GaussianBlur(img,ksize=(3,3),sigmaX=5)


    # 中值滤波,适合椒盐噪声
    img_median = cv2.medianBlur(img,ksize=3)


    # 双边滤波,灰度值两边进行高斯模糊吗,即保留边缘信息进行局部优化
    # sigmaColor:计算像素信息的sigma,sigmaSpace计算空间信息的sigma
    img_bilateral = cv2.bilateralFilter(img,d=7,sigmaColor=10,sigmaSpace=20)


    cv2.imshow("imshow", img_bilateral)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分