轮廓检测
在计算机视觉中,物体的轮廓检测也是一个比较重要的任务,也是其他与轮廓检测相关操作的基础.实现轮廓检测主要是应用了cv2.findContours()函数,该函数的依据理论详见文献-----Suzuki S, Be K. Topological structural analysis of digitized binary images by border following[J]. Computer Vision Graphics & Image Processing, 1985, 30(1):32-46.
这里介绍一下findContours()函数,该函数的输入有三个参数:输入图像,层次类型和轮廓逼近方法,这里所说的输入的图像是经过二值化处理后的图像.这个函数会修改输入的图像,建议使用img.copy()作为输入;该函数会返回三个值:修改后的图像,图像的轮廓以及其层次.详见
注:在opencv2中返回两个值:轮廓及其层次
算法实现
import cv2
import numpy as np
img = cv2.pyrDown(cv2.imread("/home/pandamax/techfort-pycv/chapter3/hammer.jpg", cv2.IMREAD_UNCHANGED))
ret, thresh = cv2.threshold(cv2.cvtColor(img.copy(), cv2.COLOR_BGR2GRAY) , 127, 255, cv2.THRESH_BINARY)
#ret=127
#print("thresh",thresh)
image, contours, hier = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cv2.imshow("image", image)
#print("contours",contours)
#c为轮廓点坐标
for c in contours:
# find bounding box coordinates:最小的矩形,把找到的形状包起来
x,y,w,h = cv2.boundingRect(c)#x,y是矩阵左点的坐标,w,h是矩阵的宽和高
print(w,h)
cv2.rectangle(img, (x,y), (x+w, y+h), (0, 255, 0), 2)
# find minimum area:带有旋转角
rect = cv2.minAreaRect(c)
# calculate coordinates of the minimum area rectangle
box = cv2.boxPoints(rect)
# normalize coordinates to integers
box = np.int0(box)
print("box",box)
# draw contours
cv2.drawContours(img, [box], 0, (0,0, 255), 3)
# calculate center and radius of minimum enclosing circle
(x,y),radius = cv2.minEnclosingCircle(c)
#print((x,y))
#print(radius)
# cast to integers
center = (int(x),int(y))#圆心
radius = int(radius)#半径
# draw the circle
img = cv2.circle(img,center,radius,(0,255,0),2)
cv2.drawContours(img, contours, -1, (255, 0, 0), 1)
# imshow组合waitKey
cv2.imshow("contours", img)
cv2.waitKey()
cv2.destroyAllWindows()
输入图片:
输出结果:
输出框分别是边界框(绿),最小矩形区域(红),最小闭圆的轮廓(蓝).