7/29opencv-python学习笔记

图像平滑

导向滤波

导向滤波也是需要一张图片作为引导图片,来表明边缘,物体等信息,作为保持边缘滤波算法,可以采用自身作为导向图片。opencv 2中也暂不支持导向滤波, 同样在opencv-contrib-python包的ximgproc模块提供了导向滤波函。
导向滤波具体原理可以参考:https://blog.csdn.net/baimafujinji/article/details/74750283
opencv中导向滤波cv2.ximgproc.guidedFilter()的参数如下:

导向滤波
    cv2.ximgproc.guidedFilter(guide,src,radius,eps,dDepth)
        guide: 导向图片,单通道或三通道
        src: 输入图像对象矩阵,可以为单通道或多通道
        radius:用来计算卷积核的领域直径
        eps:规范化参数, eps的平方类似于双边滤波中的sigmaColor(颜色空间滤波器标准偏差值)
            (regularization term of Guided Filter. eps2 is similar to the sigma in the color space into bilateralFilter.)
        dDepth: 输出图片的数据深度

其代码使用和效果如下:

import cv2 as cv

src = cv.imread(r"D:\20200728204351.png")
dst = cv.ximgproc.guidedFilter(src,src,33,2,-1)
cv.imshow("img",src)
cv.imshow("dst",dst)
cv.waitKey(0)
cv.destroyAllWindows()

在这里插入图片描述

形态学处理

通过阈值化分割可以得到二值图,但往往会出现图像中物体形态不完整,变的残缺,可以通过形态学处理,使其变得丰满,或者去除掉多余的像素。常用的形态学处理算法包括:腐蚀,膨胀,开运算,闭运算,形态学梯度,顶帽运算和底帽运算。

腐蚀

腐蚀操作类似于中值平滑,也有一个核,但不进行卷积运算,而是取核中像素值的最小值代替锚点位置的像素值,这样就会使图像中较暗的区域面积增大,较亮的的区域面积减小。如果是一张黑底,白色前景的二值图,就会使白色的前景物体颜色变小,就像被腐蚀了一样。
行腐蚀操作的核,不仅可以是矩形,还可以是十字形和椭圆形,opencv提供getStructuringElement()函数来获得核,其参数如下:

kernel=cv2.getStructuringElement(shape,ksize,anchor)
        shape:核的形状
                cv2.MORPH_RECT: 矩形
                cv2.MORPH_CROSS: 十字形(以矩形的锚点为中心的十字架)
                cv2.MORPH_ELLIPSE:椭圆(矩形的内切椭圆)
                
        ksize: 核的大小,矩形的宽,高格式为(width,height)
        anchor: 核的锚点,默认值为(-1,-1),即核的中心点

opencv提供erode()函数进行腐蚀操作,其对应参数如下:

dst=cv2.erode(src,kernel,anchor,iterations,borderType,borderValue):
        src: 输入图像对象矩阵,为二值化图像
        kernel:进行腐蚀操作的核,可以通过函数getStructuringElement()获得
        anchor:锚点,默认为(-1,-1)
        iterations:腐蚀操作的次数,默认为1
        borderType: 边界种类,有默认值
        borderValue:边界值,有默认值

腐蚀操作的代码和效果如下:
可以看到第二组二值化图像中白色的opencv字体面积变小了,就像被腐蚀了。注意这是黑底白字,如果是白底黑字,效果会相反,字体反而会膨胀。

import cv2 as cv

img = cv.imread(r"C:\Users\Administrator\Desktop\logo.png")
img_cvt = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
ret,img_thr = cv.threshold(img_cvt,200,255,cv.THRESH_BINARY_INV)
kernel = cv.getStructuringElement(cv.MORPH_RECT,(3,5))
dst = cv.erode(img_thr,kernel,iterations=1)

cv.imshow("img",img)
cv.imshow("img_thr",img_thr)
cv.imshow("dst",dst)
cv.waitKey(0)
cv.destroyAllWindows()

在这里插入图片描述

在这里插入图片描述

膨胀

膨胀操作和腐蚀操作正好相反,是取核中像素值的最大值代替锚点位置的像素值,这样会使图像中较亮的区域增大,较暗的区域减小。如果是一张黑底,白色前景的二值图,就会使白色的前景物体颜色面积变大,就像膨胀了一样
opencv提供dilate()函数进行膨胀操作,其对应参数如下:

dst = cv2.dilate(src,kernel,anchor,iterations,borderType,borderValue)
        src: 输入图像对象矩阵,为二值化图像
        kernel:进行腐蚀操作的核,可以通过函数getStructuringElement()获得
        anchor:锚点,默认为(-1,-1)
        iterations:腐蚀操作的次数,默认为1
        borderType: 边界种类
        borderValue:边界值

膨胀操作的代码和效果如下:
可以看到二值化图像中白色的字体面积变大了,就像膨胀了
在这里插入图片描述

开运算,闭运算,顶帽,顶帽

开运算:先进行腐蚀操作,后进行膨胀操作,主要用来去除一些较亮的部分,即先腐蚀掉不要的部分,再进行膨胀。
闭运算:先进行膨胀操作,后进行腐蚀操作,主要用来去除一些较暗的部分。
形态学梯度:膨胀运算结果减去腐蚀运算结果,可以拿到轮廓信息。
顶帽运算:原图像减去开运算结果。
底帽运算:原图像减去闭运算结果。  
进行开运算,闭运算,顶帽运算,底帽运算,形态学梯度,opencv提供了一个统一的函数cv2.morphologyEx(),其对应参数如下:

dst = cv2.morphologyEx(src,op,kernel,anchor,iterations,borderType,borderValue)
        src: 输入图像对象矩阵,为二值化图像
        op: 形态学操作类型
            cv2.MORPH_OPEN    开运算
            cv2.MORPH_CLOSE   闭运算
            cv2.MORPH_GRADIENT 形态梯度
            cv2.MORPH_TOPHAT   顶帽运算
            cv2.MORPH_BLACKHAT  底帽运算
            
        kernel:进行腐蚀操作的核,可以通过函数getStructuringElement()获得
        anchor:锚点,默认为(-1,-1)
        iterations:腐蚀操作的次数,默认为1
        borderType: 边界种类
        borderValue:边界值

使用代码和对应效果如下:

import cv2 as cv
import matplotlib.pyplot as plt

img = cv.imread(r"D:\exologo2.png")
img_cvt = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
ret,img_thr = cv.threshold(img_cvt,200,255,cv.THRESH_BINARY_INV)
kernel = cv.getStructuringElement(cv.MORPH_RECT,(3,5))
open = cv.morphologyEx(img_thr,cv.MORPH_OPEN,kernel,iterations=1)
close = cv.morphologyEx(img_thr,cv.MORPH_CLOSE,kernel,iterations=1)
gradient = cv.morphologyEx(img_thr,cv.MORPH_GRADIENT,kernel,iterations=1)
tophat = cv.morphologyEx(img_thr,cv.MORPH_TOPHAT,kernel,iterations=1)
blackhat = cv.morphologyEx(img_thr,cv.MORPH_BLACKHAT,kernel,iterations=1)

images=[img_thr,open,close,gradient,tophat,blackhat]
titles=["img_thr","open","close","gradient","tophat","blackhat"]
for i in range(6):
    plt.subplot(2,3,i+1),plt.imshow(images[i],"gray")
    plt.title(titles[i])
    plt.xticks([]),    plt.yticks([])
plt.show()

在这里插入图片描述

subplot函数

在实际bai应用中,经常需要在一du个图形窗口中绘制若干个zhi独立的图形,这就需要对图形窗口进行分dao割。分割后的图形窗口由若干个绘图区组成,每一个绘图区可以建立独立的坐标系并绘制图形。同一图形窗口下的不同图形称为子图。

Matlab提供了subplot函数用来将当前窗口分割成若干个绘图区,每个区域代表一个独立的子图,也是一个独立的坐标系,可以通过subplot函数激活某一区,该区为活动区,所发出的绘图命令都是作用于该活动区域。调用格式:

subplot(m,n,p)或subplot(mnp)

该函数把当前窗口分成m×n个绘图区,m行,每行n个绘图区,区号按行优先编号。其中第p个区为当前活动区。每一个绘图区允许以不同的坐标系单独绘制图形。

例如:subplot(1,2,2)就是指一个FIGURE图形生成一行两列两个子图,subplot(1,2,2)后面一个2表示当前激活第二个子图。

应用实例

有如下一张中文图片,当我们进行字符切割时,常需要知道其中的汉字是否带下划线,方便进行后续处理。

import cv2 as cv

img = cv.imread(r"D:\jiege5.png")
img_cvt = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
ret,img_thr = cv.threshold(img_cvt,100,255,cv.THRESH_BINARY)
kernel = cv.getStructuringElement(cv.MORPH_RECT,(30,1)) #由于是1*30的矩阵,字体会被横向空隙的白色腐蚀掉,而下划线横向都是黑色,不会腐蚀
dst = cv.dilate(img_thr,kernel,iterations=1)  #由于是白底黑字,所有进行膨胀操作来去除黑色字体
cv.imshow("img_thr",img_thr)
cv.imshow("dst",dst)
cv.waitKey(0)
cv.destroyAllWindows()

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值