OpenCV系列—本文底页有多个常用方法链接
cv2.findContours(img, mode, method)
mode:轮廓检索模式
method:轮廓逼近方法
import cv2
def cv_show(img, name):
cv2.imshow(name, img)
cv2.waitKey()
cv2.destroyAllWindows()
img = cv2.imread('DataPreprocessing/img/contours.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
cv_show(thresh, 'thresh')
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
draw_img = img.copy()
res = cv2.drawContours(draw_img, contours, -1, (0, 0, 255), 2)
cv_show(res, 'res')
“-1”表示显示所有轮廓,(B, G , R) = (0, 0, 255) 采用红色的显示全部轮廓,如下:
或者显示索引为1的轮廓,代码如下:
draw_img = img.copy()
res = cv2.drawContours(draw_img, contours, 1, (0, 0, 255), 2)
cv_show(res, 'res')
cnt = contours[0]
# 面积
print("面积: ", cv2.contourArea(cnt))
# 周长,True表示闭合的
print("周长: ", cv2.arcLength(cnt, True))
面积: 8500.5
周长: 437.9482651948929
contours2.png
原图 :
img = cv2.imread('DataPreprocessing/img/contours2.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
cnt = contours[0]
draw_img = img.copy()
res = cv2.drawContours(draw_img, [cnt], -1, (0, 0, 255), 2)
cv_show(res, 'res')
边缘检测:
原理:以这个弧线为例, A , B A,B A,B端连线,取弧线上一点 C C C离线段 A B AB AB的距离最大,判断 d 1 d_{1} d1是否小于设置的阈值 T T T, 不小于 T T T的,则以 A , C A,C A,C连接线段 A C AC AC,重复上面的操作,取得图中的 d 2 d_{2} d2,再同 T T T做比较,直至 d n d_{n} dn小于阈值得出线段为轮廓边缘。
img = cv2.imread('DataPreprocessing/img/contours.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
cnt = contours[0]
x, y, w, h = cv2.boundingRect(cnt)
img = cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv_show(img, 'img')
area = cv2.contourArea(cnt)
x, y, w, h = cv2.boundingRect(cnt)
rect_area = w * h
extent = float(area) / rect_area
print('轮廓面积与边界矩形比', extent)
轮廓面积与边界矩形比 0.5154317244724715
外接圆形:
(x, y), radius = cv2.minEnclosingCircle(cnt)
center = (int(x), int(y))
radius = int(radius)
img = cv2.circle(img, center, radius, (0, 255, 0), 2)
cv_show(img, 'img')