函数cv2.drawContours()被用来绘制轮廓。第一个参数是一张图片,可以是原图或者其他。第二个参数是轮廓,也可以说是cv2.findContours()找出来的点集,一个列表。第三个参数是对轮廓(第二个参数)的索引,当需要绘制独立轮廓时很有用,若要全部绘制可设为-1。接下来的参数是轮廓的颜色和厚度。
凸形形状的轮廓检测:凸形指图形内两点连线可能会在图形外,OpenCV中应用道格拉斯-普客算法检测凸形的轮廓,内置函数为:cv2.approxPolyDP(contours, epsilon, flag) 三个参数分别为轮廓点、轮廓线与轮廓的最大差异值、表示轮廓是否封闭的bool型变量flag。 最重要的当然是epsilon的值,他越小,代表这一新轮廓越接近旧的轮廓。
import cv2
import numpy as np
def edge_demo(image):
blurred = cv2.GaussianBlur(image, (3, 3), 0)
gray = cv2.cvtColor(blurred, cv2.COLOR_RGB2GRAY)
# xgrad = cv.Sobel(gray, cv.CV_16SC1, 1, 0) #x方向梯度
# ygrad = cv.Sobel(gray, cv.CV_16SC1, 0, 1) #y方向梯度
# edge_output = cv.Canny(xgrad, ygrad, 50, 150)
edge_output = cv2.Canny(gray, 220, 250)
return edge_output
def contour(img):
binary = edge_demo(img)
contours, hierarchy = cv2.findContours(binary,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
for i,contour in enumerate(contours):
cv2.drawContours(img, contours, -1, (0, 0, 255),2)
area = cv2.contourArea(contour)
print("轮廓个数: %s" % str(i))
print("area: %s"%area)
x,y,w,h = cv2.boundingRect(contour)
rate = min(w,h)/max(w,h)
print("横纵比例:%s"%str(rate))
mm = cv2.moments(contour)
print(type(mm))
cx = mm['m10']/mm['m00']
cy = mm['m01'] / mm['m00']
print("cx:%s" % str(np.int(cx)))
print("cy:%s" % str(np.int(cy)))
cv2.circle(img,(np.int(cx),np.int(cy)),6,(255,255,0),-1)
cv2.rectangle(img,(x-2,y-2),(x+w+2,y+h+2),(255,0,0),5)
cv2.imshow('img', img)
img = cv2.imread('14.jpg',1)
cv2.namedWindow('img', 0)
cv2.namedWindow('imgsrc', 0)
cv2.namedWindow('Canny Edge', 0)
cv2.resizeWindow('img', 480, 400)
cv2.resizeWindow('imgsrc', 480, 400)
cv2.resizeWindow('Canny Edge', 480, 400)
cv2.imshow('imgsrc', img)
#edge_demo(img)
contour(img)
cv2.waitKey(0)
cv2.destroyAllWindows()
area = cv2.contourArea(contour)
print("轮廓个数: %s" % str(i))
print("area: %s"%area)
横纵比例筛选:
x,y,w,h = cv2.boundingRect(contour)
rate = min(w,h)/max(w,h)
print("横纵比例:%s"%str(rate))
中心矩:
cx = mm['m10']/mm['m00']
cy = mm['m01']/mm['m00']
print("cx:%s" % str(np.int(cx)))
print("cy:%s" % str(np.int(cy)))
cv2.circle(img,(np.int(cx),np.int(cy)),6,(255,255,0),-1)
直接画出全部轮廓:
cv2.drawContours(binary, contours,-1, (0, 0, 255), 3)
判断图形个数:
import cv2
import numpy as np
def contour(img):
dst = cv2.GaussianBlur(img,(3,3),0)
gray = cv2.cvtColor(dst,cv2.COLOR_BGR2GRAY)
cv2.imshow('imgsrc', gray)
ret,binary = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV|cv2.THRESH_OTSU)
cv2.imshow("binary", binary)
contours, hierarchy = cv2.findContours(binary,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
#cv2.drawContours(img, contours,-1, (0, 0, 255), 3)
for i,contour in enumerate(contours):
cv2.drawContours(img,contours,i,(255,255,0),3)
approxcurve = cv2.approxPolyDP(contour, 4, False)
print(approxcurve.shape)
if approxcurve.shape[0] >10:
cv2.drawContours(img,contours,i,(255,255,0),3)
if approxcurve.shape[0] ==4:
cv2.drawContours(img, contours, i, (255, 0, 0), 3)
if approxcurve.shape[0] == 3:
cv2.drawContours(img, contours, i, (0, 255, 0), 3)
#print(i)
cv2.imshow('img', img)
img = cv2.imread('17.jpg',1)
cv2.imshow('imgsrc', img)
contour(img)
cv2.waitKey(0)
cv2.destroyAllWindows()