轮廓发现
使基于图像边缘提取的基础寻找对象轮廓的方法,所以便于提取的阈值选定会影响最终轮廓发现的结果
API介绍:
findContours 发现轮廓
drawContours 绘制轮廓
from matplotlib import pyplot as plt
from cv2 import cv2 as cv
import numpy as np
# canny边缘提取
def edge_demo(image):
blurred = cv.GaussianBlur(image,(3,3),0) # 高斯降噪,适度
gray = cv.cvtColor(blurred,cv.COLOR_BGR2GRAY)
# 求梯度
xgrd = cv.Sobel(gray,cv.CV_16SC1,1,0)
ygrd = cv.Sobel(gray,cv.CV_16SC1,0,1)
egde_output = cv.Canny(xgrd,ygrd,50,150) # 50低阈值,150高阈值
#egde_output = cv.Canny(gray,50,150) # 都可使用
cv.imshow('canny_edge',egde_output)
return egde_output
'''
# 输出彩色图
dst = cv.bitwise_and(image,image,mask=egde_output)
cv.imshow('color edge',dst)
'''
def contours_demo(image):
'''
dst = cv.GaussianBlur(image,(3,3),0) # 高斯模糊 消除外边的噪声
gray = cv.cvtColor(dst,cv.COLOR_RGB2GRAY) # 转换成二值图像
ret,binary = cv.threshold(gray,0,255,cv.THRESH_BINARY|cv.THRESH_OTSU)
cv.imshow('binary image',binary)
'''
# 用canny获取二值图像
binary = edge_demo(image)
#contours, heriachy = cv.findContours(binary, cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE) # 这个轮廓里面会有噪声,下面则没有
contours, heriachy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE # 注意 我的版本只有两个返回参数,具体看函数说明是返回几个参数
for i,contour in enumerate(contours):
cv.drawContours(image,contours,i,(0,0,255),2)
#cv.drawContours(image,contours,i,(0,0,255),-1)#轮廓填充
#print(i)
cv.imshow('detect image',image)
#cv.imwrite('C:\\pictures\\Test paper\\5.jpg',image)
if __name__ == "__main__":
filepath = "C:\\pictures\\others\\measure2.jpg"
img = cv.imread(filepath) # blue green red
cv.namedWindow("input image",cv.WINDOW_AUTOSIZE)
cv.imshow("input image",img)
contours_demo(img)
cv.waitKey(0)
cv.destroyAllWindows()
结果如下: