import cv2
img = cv2.imread('opencv.jpg')
imggray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imggray,0,255,cv2.THRESH_OTSU)
#cv2.CHAIN_APPROX_NONE,所有的边界点都会被存储
#cv2.CHAIN_APPROX_SIMPLE只存储端点
contours,hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
# -1代表绘制所有轮廓
img1 = cv2.drawContours(img,contours,-1,(0,0,0),3)
cv2.imshow('img1',img1)
cv2.waitKey(0)
cv2.destroyAllWindows()
2.轮廓特征:
2.1 矩
#轮廓重心
cnt = contours[0]
M = cv2.moments(cnt)
print(M)
cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])
print (cx,cy)
{‘m00’: 165073.0, ‘m10’: 35573231.5, ‘m01’: 31611479.5, ‘m20’: 10221375184.333332, ‘m11’: 6812273832.25, ‘m02’: 8071464432.333333, ‘m30’: 3304059528335.75, ‘m21’: 1957393347799.8333, ‘m12’: 1739400585167.8333, ‘m03’: 2318528158187.75, ‘mu20’: 2555343796.083332, ‘mu11’: 0.0, ‘mu02’: 2017866108.083333, ‘mu30’: 0.0009765625, ‘mu21’: 0.00018310546875, ‘mu12’: 0.0, ‘mu03’: 0.0, ‘nu20’: 0.0937771975630983, ‘nu11’: 0.0, ‘nu02’: 0.07405259087393658, ‘nu30’: 8.82083976632943e-17, ‘nu21’: 1.653907456186768e-17, ‘nu12’: 0.0, ‘nu03’: 0.0}
215 191
#轮廓面积
area = cv2.contourArea(cnt)
print (area)
165073.0
#轮廓周长
perimeter = cv2.arcLength(cnt,True)
print (perimeter)
1628.0
#轮廓近似
img = cv2.imread('giao.jpg')
imggray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imggray,0,255,cv2.THRESH_OTSU)
contours,hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
cnt = contours[0]
epsilon = 0.1*cv2.arcLength(cnt,True)
approx = cv2.approxPolyDP(cnt,epsilon,True)
cv2.polylines(img,[approx],True,(0,0,255),2)
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
下边,第二幅图中的绿线是当 epsilon = 10% 时得到的近似轮廓,第三幅图是当 epsilon = 1% 时得到的近似轮廓。第三个参数设定弧线是否闭合。
#凸包img = cv2.imread('giao.jpg')
img2 = cv2.imread('giao.jpg')
imggray = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imggray,0,255,cv2.THRESH_OTSU)
contours,hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
cnt = contours[0]
hull = cv2.convexHull(cnt)
cv2.polylines(img2,[hull],True,(0,0,255),2)
cv2.imshow('img',img2)
cv2.waitKey(0)
cv2.destroyAllWindows()
对此可以参考链接:https://segmentfault.com/a/1190000015663722
#凸性检测
k = cv2.isContourConvex(cnt)
print (k)
False
#边界矩形,直边矩形
img3 = cv2.imread('str.jpg')
imggray = cv2.cvtColor(img3,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imggray,0,255,cv2.THRESH_OTSU)
contours,hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
cnt = contours[1]
#(x,y)为矩形左上角的坐标,(w,h)是矩形的宽和高。
x,y,w,h = cv2.boundingRect(cnt)
img4 = cv2.rectangle(img3,(x,y),(x+w,y+h),(0,255,0),2)
cv2.imshow('img',img4)
cv2.waitKey(0)
cv2.destroyAllWindows()
#最小外接矩形
import numpy as np
img3 = cv2.imread('str.jpg')
imggray = cv2.cvtColor(img3,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imggray,0,255,cv2.THRESH_OTSU)
contours,hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
cnt = contours[1]
rect = cv2.minAreaRect(cnt)
box = cv2.boxPoints(rect)
box = np.int0(box)
cv2.fillPoly(img3,[box],(0,0,255))
cv2.imshow('img',img3)
cv2.waitKey(0)
cv2.destroyAllWindows()
#最小外接圆
img3 = cv2.imread('str.jpg')
imggray = cv2.cvtColor(img3,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imggray,0,255,cv2.THRESH_OTSU)
contours,hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
cnt = contours[1]
(x,y),radius = cv2.minEnclosingCircle(cnt)
center = (int(x),int(y))
radius = int(radius)
img4 = cv2.circle(img3,center,radius,(0,255,0),2)
cv2.imshow('img',img4)
cv2.waitKey(0)
cv2.destroyAllWindows()
#椭圆拟合
img3 = cv2.imread('str.jpg')
imggray = cv2.cvtColor(img3,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imggray,0,255,cv2.THRESH_OTSU)
contours,hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
cnt = contours[1]
ellipse = cv2.fitEllipse(cnt)
im = cv2.ellipse(img3,ellipse,(0,255,0),2)
cv2.imshow('img',im)
cv2.waitKey(0)
cv2.destroyAllWindows()
#直线拟合
img3 = cv2.imread('str.jpg')
rows,cols = img3.shape[:2]
imggray = cv2.cvtColor(img3,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imggray,0,255,cv2.THRESH_OTSU)
contours,hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
cnt = contours[1]
[vx,vy,x,y] = cv2.fitLine(cnt, cv2.DIST_L2,0,0.01,0.01)
lefty = int((-x*vy/vx) + y)
righty = int(((cols-x)*vy/vx)+y)
img = cv2.line(img3,(cols-1,righty),(0,lefty),(0,255,0),2)
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
#宽高比
x,y,w,h = cv2.boundingRect(cnt)
aspect_ratio = float(w)/h
print (aspect_ratio)
area = cv2.contourArea(cnt)
x,y,w,h = cv2.boundingRect(cnt)
rect_area = w*h
extent = float(area)/rect_area
print (extent)
area = cv2.contourArea(cnt)
hull = cv2.convexHull(cnt)
hull_area = cv2.contourArea(hull)
solidity = float(area)/hull_area
print (solidity)
area = cv2.contourArea(cnt)
equi_diameter = np.sqrt(4*area/np.pi)
print (equi_diameter)
(x,y),(MA,ma),angle = cv2.fitEllipse(cnt)
print ((x,y),(MA,ma),angle)
img = cv2.imread('str.jpg',0)
mask = np.zeros(img.shape,np.uint8)
mask = cv2.drawContours(mask,[cnt],0,255,-1)
cv2.imshow('mask',mask)
cv2.waitKey(0)
cv2.destroyAllWindows()
min_val,max_val,min_loc,max_loc = cv2.minMaxLoc(img,mask=mask)
print (min_val,max_val,min_loc,max_loc)
mean_val = cv2.mean(img,mask=mask)
print (mean_val)
leftmost = tuple(cnt[cnt[:,:,0].argmin()][0])
rightmost = tuple(cnt[cnt[:,:,0].argmax()][0])
topmost = tuple(cnt[cnt[:,:,1].argmin()][0])
bottommost = tuple(cnt[cnt[:,:,1].argmax()][0])
print (leftmost,rightmost,topmost,bottommost)
#凸缺陷
import cv2
import numpy as np
img = cv2.imread('fb.jpg')
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(img_gray,0,255,cv2.THRESH_OTSU)
contours,hierarchy = cv2.findContours(thresh,2,1)
cnt = contours[6]
hull = cv2.convexHull(cnt,returnPoints=False)
defects = cv2.convexityDefects(cnt,hull)
for i in range(defects.shape[0]):
s,e,f,d = defects[i,0]
start = tuple(cnt[s][0])
end = tuple(cnt[e][0])
far = tuple(cnt[f][0])
cv2.line(img,start,end,[0,255,0],2)
cv2.circle(img,far,5,[0,0,255],-1)
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# Point Polygon Test
dist = cv2.pointPolygonTest(cnt,(50,50),True)
print (dist)
# 形状匹配
import cv2
import numpy as np
img = cv2.imread('fb.jpg')
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(img_gray,0,255,cv2.THRESH_OTSU)
contours,hierarchy = cv2.findContours(thresh,2,1)
cnt1 = contours[6]
img2 = cv2.imread('2.jpg',0)
ret, thresh2 = cv2.threshold(img2, 127, 255,0)
contours,hierarchy = cv2.findContours(thresh,2,1)
cnt2 = contours[0]
ret1 = cv2.matchShapes(cnt1,cnt2,1,0.0)
ret2 = cv2.matchShapes(cnt1,cnt1,1,0.0)
print (ret1,ret2)