OpenCV 形态学操作

canny边缘检测

        canny边缘检测算法是John F.Canny于1986年开发出来的一个多边缘检测算法,也被很多人认为是边缘检测的最优算法,最优边缘检测的三个主要标准是:
        低错误率:标识出尽可能多的实际边缘,同时尽可能的减少噪声产生的误报。
        高定位性:标识出的边缘要与图像中的实际边缘尽可能接近。
        最小响应:图像中的边缘只能标注一次。

Canny边缘检测的一般步骤:
        去噪:边缘检测容易受到噪声影响,在进行边缘检测前通常需要先进行去噪,一般用高斯滤波去除噪声。
        计算梯度:对平滑后的图像采用sobel算子计算梯度和方向。
        非极大值抑制:在获取了梯度和方向后,遍历图像,去除所有不是边界的点。
                实现方法:逐个遍历像素点,判断当前像素点是否是周围像素点中具有相同方向梯度的最大值。如果是,保留该点;否则,它被抑制。

import cv2
import numpy as np

img = cv2.imread('./dog.jpg')

#cv2.Canny(image, threshold1, threshold2[, edges[, apertureSize[, L2gradient]]])
dog1=cv2.Canny(img,100,200)
dog2=cv2.Canny(img,110,210)
dog3=cv2.Canny(img,130,150)


cv2.imshow('img',img)
cv2.imshow('dog',np.vstack((dog1,dog2,dog3)))
cv2.waitKey(0)
cv2.destroyAllWindows()

查找轮廓

图像轮廓是具有相同颜色或灰度的连续的曲线,轮廓在形状分析和物体检测和识别中很有用。
轮廓的作用:
        用于图形分析
        物体的识别和检测
注意点:
        为了检测的准确性,需要先对图像进行二值化或Canny操作。
        画轮廓时会修改输入图像,如果之后像继续使用原始图像,应该将原始图像储存到其他变量中。

#findContours(image,mode,method[,contours[,hierarchy[,offset]]])

###mode 查找轮廓的方式
#####RETR_EXTERAL=0,表示只检测外围轮廓
#####RETR_LIST=1,检测的轮廓不建立等级关系,即检测所有轮廓,较为常用。
#####RETR_CCOMP=2,每层最多两级,从小到大,从里到外。
#####RETR_TREE=3,按照树型存储轮廓,从大到小,从右到左

###method 轮廓近似方法也叫ApproximationMode
#####CHAIN_APPROX_NONE 保存所有轮廓上的点
#####CHAIN_APPROX_SIMPLE,只保存角点,比如四边形,只保留四边形的4个角,存储信息少,比较常用

###返回contour和hierarchy即轮廓和层级
import cv2
import numpy as np

#读取图片
img=cv2.imread('./cat.jpg')

#变成单通道的黑白图片
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

#二值化,注意有两个返回值,阈值和结果
ret,binary=cv2.threshold(gray,160,255,cv2.THRESH_BINARY)

#查找轮廓,新版本返回两个结果,分别是轮廓和层级
contours, hierarchy=cv2.findContours(binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

# #contour是list 不是ndarry,里面放的是ndarry表示一个contour
# print(type(contours))
# print(contours)
# print(hierarchy)



# cv2.imshow('img',img)
# cv2.imshow('gray',gray)
# cv2.imshow('binary',binary)

cv2.waitKey(0)
cv2.destroyAllWindows()

绘制轮廓

import cv2
import numpy as np

#读取图片
img=cv2.imread('./cat.jpg')

#变成单通道的黑白图片
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

#二值化,注意有两个返回值,阈值和结果
ret,binary=cv2.threshold(gray,160,255,cv2.THRESH_BINARY)

#查找轮廓,新版本返回两个结果,分别是轮廓和层级
contours, hierarchy=cv2.findContours(binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

###########################################################################################
#绘制轮廓会直接修改原图。
#如果想保持原图不变,建议copy一份
#image 要绘制的轮廓图像
#contours 轮廓点
#contourIdx 要绘制的轮廓编号,-1表示绘制所有轮廓
#color 轮廓的颜色,如(0,0,255)表示红色
#thickness线宽,-1表示全填充
img_copy=img.copy()
cv2.drawContours(img_copy,contours,-1,(0,0,255),1)

##########################################################################################

cv2.imshow('img',img)
cv2.imshow('img_copy',img_copy)
# cv2.imshow('gray',gray)
cv2.imshow('binary',binary)

cv2.waitKey(0)
cv2.destroyAllWindows()

腐蚀操作

import cv2
import numpy as np

#导入图片
img=cv2.imread('./big.jpg')
#滤波
filt1=cv2.bilateralFilter(img,21,sigmaColor=50,sigmaSpace=500)

#二值化操作是对灰度图像操作,把dog变成灰度图像。
gray=cv2.cvtColor(filt1,cv2.COLOR_BGR2GRAY)

#滤波
filt12=cv2.bilateralFilter(gray,21,sigmaColor=50,sigmaSpace=500)

#自适应阈值二值化只有一个返回值。
bina=cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,49,0)

#定义核
kernel=np.ones((3,3),np.uint8)
dst=cv2.erode(bina,kernel,iterations=1)


cv2.imshow('img',img)
cv2.imshow('dst',dst)
cv2.imshow('big2',np.vstack((gray,bina)))
cv2.waitKey(0)
cv2.destroyAllWindows()

获取形态学卷积核

opencv提供了获取卷积核的api,不需要我们手工创建卷积核。

#getStructuringElement(shape,ksize[,anchor])
###shape是指卷积核的形状,注意不是指长宽,是指卷积核中1形成的形状。
#####MORPH_RECT卷积核中的1是矩形,常用。
#####MORPH_ELLIPSE 椭圆
#####MORPH_CROSS 十字
import cv2
import numpy as np

###################获取卷积核###########################
#矩形
#kernel=cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))

#椭圆
#kernel=cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))

#十字
kernel=cv2.getStructuringElement(cv2.MORPH_CROSS,(5,5))

print(kernel)

########################################################

#导入图片
img=cv2.imread('./big.jpg')

#变成灰度图像。
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

#自适应阈值二值化只有一个返回值。
bina=cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,49,0)

#腐蚀
dst=cv2.erode(bina,kernel,iterations=1)

cv2.imshow('dst',dst)
cv2.imshow('big2',np.vstack((gray,bina)))
cv2.waitKey(0)
cv2.destroyAllWindows()

开运算和闭运算

开运算

##################################################################################################
#开运算和闭运算都是腐蚀和膨胀的基本应用
#开运算=腐蚀+膨胀
#morphologyEx(img,MORPH_OPEN,kernel)
###MORPH_OPEN 表示形态学的开运算
###kernel 如果噪点比较多,会选择大一点的kernel,如果噪点比较小,可以选择小点的kernel。
##################################################################################################
import cv2
import numpy as np

#开运算=腐蚀+膨胀
#开运算提供了另一种去除噪声的思路
img=cv2.imread('./xhx.jpg')
kernel=cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))

# #先腐蚀
# dst=cv2.erode(img,kernel,iterations=2)

# #膨胀
# dst=cv2.dilate(dst,kernel,iterations=2)

#调用opencv提供的api
dst=cv2.morphologyEx(img,cv2.MORPH_OPEN,kernel,iterations=2)



cv2.imshow('img',np.hstack((img,dst)))
cv2.waitKey(0)
cv2.destroyAllWindows()

闭运算

#闭运算=膨胀+腐蚀
import cv2
import numpy as np

#开运算=腐蚀+膨胀
#闭运算可以去除图形内部的噪声
img=cv2.imread('./xh.jpg')
kernel=cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))

#调用opencv提供的api
dst=cv2.morphologyEx(img,cv2.MORPH_CLOSE,kernel,iterations=2)

cv2.imshow('img',np.hstack((img,dst)))
cv2.waitKey(0)
cv2.destroyAllWindows()

膨胀操作

        膨胀是腐蚀的相反操作,基本原理是只要保证卷积核的锚点是非零值,周边无论是0还是非0值,都会变成非零值

import cv2
import numpy as np

#导入图片
img=cv2.imread('./xhx.jpg')

#获取卷积核
kernel=cv2.getStructuringElement(cv2.MORPH_CROSS,(5,5))

#膨胀
dst=cv2.dilate(img,kernel,iterations=1)

cv2.imshow('big2',np.vstack((img,dst)))
cv2.waitKey(0)
cv2.destroyAllWindows()

形态学梯度和顶帽黑帽操作

梯度=原图-腐蚀

#腐蚀之后原图边缘变小了,原图-腐蚀就可以得到腐蚀掉的部分,即边缘
import cv2
import numpy as np

img=cv2.imread('./xh.jpg')
kernel=cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))


#调用opencv提供的api
dst=cv2.morphologyEx(img,cv2.MORPH_GRADIENT,kernel,iterations=1)



cv2.imshow('img',np.hstack((img,dst)))
cv2.waitKey(0)
cv2.destroyAllWindows()

顶帽=原图-开运算

#开运算的效果是去除图像外的噪点,原图-开运算就得到了去掉的噪点。
import cv2
import numpy as np

img=cv2.imread('./xh.jpg')
kernel=cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))


#调用opencv提供的api
dst=cv2.morphologyEx(img,cv2.MORPH_TOPHAT,kernel,iterations=3)



cv2.imshow('img',np.hstack((img,dst)))
cv2.waitKey(0)
cv2.destroyAllWindows()

黑帽=原图-闭运算

#闭运算可以将图形内部的噪点去掉,那么原图-闭运算的结果就是图形内部的噪点
import cv2
import numpy as np

img=cv2.imread('./xh.jpg')
kernel=cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))


#调用opencv提供的api
dst=cv2.morphologyEx(img,cv2.MORPH_BLACKHAT,kernel,iterations=3)



cv2.imshow('img',np.hstack((img,dst)))
cv2.waitKey(0)
cv2.destroyAllWindows()

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值