前言
opencv中的边缘检测和轮廓提取都是图像识别的重要部分
提示:以下是本篇文章正文内容,下面案例可供参考
一、边缘检测
Canny边缘检测算子是一个多级边缘检测算法,Canny的目标是找到一个最优的边缘检测算法,其评价标准为:低错误率、高定位性、最小响应。
Canny边缘检测步骤
Canny函数
Python:
edges = cv.Canny( image, threshold1, threshold2[, edges[, apertureSize[, L2gradient]]] )
image 源图像,需是单通道8位图像
edges 输出的边缘图像,需和源图像具有一样的大小和类型
threshold1 第一个滞后性阀值,double
threshold2 第二个滞后性阀值,double
apertureSize 应用Sobel算子孔径大小,默认值:3
L2gradient a flag, indicating whether a more accurate L 2 norm =(dI/dx) 2 +(dI/dy) 2 − − − − − − − − − − − − − − − − √ should be used to calculate the image gradient magnitude ( L2gradient=true ), or whether the default L 1 norm =|dI/dx|+|dI/dy| is enough ( L2gradient=false ).
import cv2 as cv
import numpy as npdef edge_demo(image):blurred = cv.GaussianBlur(image, (3, 3), 0) # 高斯模糊gray = cv.cvtColor(blurred,cv.COLOR_BGR2GRAY) # 灰路图像xgrad = cv.Sobel(gray, cv.CV_16SC1, 1, 0) # xGrodientygrad = cv.Sobel(gray, cv.CV_16SC1, 0, 1) # yGrodientedge_output = cv.Canny(xgrad, ygrad, 100, 150) # edgecv.imshow("Canny Edge",edge_output)# # 彩色边缘# dst = cv.bitwise_and(image, image, mask=edge_output)# cv.imshow("Color Edge", dst)src=cv.imread("D:\\1111.png")
cv.namedWindow("input image",cv.WINDOW_AUTOSIZE)
cv.imshow("input image",src)
edge_demo(src)
cv.waitKey(0)cv.destroyAllWindows()
二、轮廓提取
1.非边缘检测轮廓提取
先将图片进行高斯模糊,然后变成灰路图像,再将图片二值化,最后将图片进行轮廓提取。
代码如下(示例):
这个方法有一个缺点就是自动二值化的阙值会对轮廓提取产生影响,虽然可以自己定义阙值,但是不能每一章照片进行一次调节。
import cv2 as cv
def contours_demo(image):blurred = cv.GaussianBlur(image, (3, 3), 0)gray = cv.cvtColor(blurred, cv.COLOR_RGB2GRAY) # 灰路图像# ret , binary = cv.threshold(gray, 0, 255,cv.THRESH_BINARY| cv.THRESH_OTSU) # 图像二值化ret, binary = cv.threshold(gray, 68, 255, cv.THRESH_BINARY ) # 图像二值化cv.imshow("binary image",binary)contours, heriachy = cv.findContours(binary,cv.RETR_LIST,cv.CHAIN_APPROX_SIMPLE)for i, contour in enumerate(contours):cv.drawContours(image,contours,i,(0,0,255),6) #6的改为-1可以填充print(i)cv.imshow("detect contours", image)src=cv.imread("D:\\1111.png")
cv.namedWindow("input image",cv.WINDOW_AUTOSIZE)
#cv.imshow("input image",src)
contours_demo(src)
cv.waitKey(0)cv.destroyAllWindows()
2.边缘检测和轮廓调节
代码如下(示例):
import cv2 as cvdef edge_demo(image):blurred = cv.GaussianBlur(image, (3, 3), 0) # 高斯模糊gray = cv.cvtColor(blurred,cv.COLOR_BGR2GRAY) # 灰路图像xgrad = cv.Sobel(gray, cv.CV_16SC1, 1, 0) # xGrodientygrad = cv.Sobel(gray, cv.CV_16SC1, 0, 1) # yGrodientedge_output = cv.Canny(xgrad, ygrad, 100, 150) # edgereturn edge_outputdef contours_demo(image):# blurred = cv.GaussianBlur(image, (3, 3), 0)# gray = cv.cvtColor(blurred, cv.COLOR_RGB2GRAY) # 灰路图像# # ret , binary = cv.threshold(gray, 0, 255,cv.THRESH_BINARY| cv.THRESH_OTSU) # 图像二值化# ret, binary = cv.threshold(gray, 68, 255, cv.THRESH_BINARY ) # 图像二值化# cv.imshow("binary image",binary)binary = edge_demo(image)contours, heriachy = cv.findContours(binary,cv.RETR_LIST,cv.CHAIN_APPROX_SIMPLE)for i, contour in enumerate(contours):cv.drawContours(image,contours,i,(0,0,255),6) #6的改为-1可以填充print(i)cv.imshow("detect contours", image)src=cv.imread("D:\\1111.png")
cv.namedWindow("input image",cv.WINDOW_AUTOSIZE)
#cv.imshow("input image",src)
contours_demo(src)
cv.waitKey(0)cv.destroyAllWindows()
这样就可以避免掉方法一产生的问题,并且还可以很好的实现轮廓的提取
总结
鸣谢
https://blog.csdn.net/weixin_42261213/article/details/93990410
https://blog.csdn.net/miao0967020148/article/details/88623631