官网参见https://docs.opencv.org/3.4.1/d1/d32/tutorial_py_contour_properties.html
本章是在《轮廓特征》基础上的介绍,需要先获得图像的轮廓。
代码中反复出现的cnt通过以下方法获得。
img = cv2.imread('test.jpg',0)
ret,thresh = cv2.threshold(img,127,255,0)
im2,contours,hierarchy = cv2.findContours(thresh, 1, 2)
cnt = contours[0]
内容概要
这是对象矩形边界的宽度与高度之比。
A s p e c t R a t i o = W i d t h H e i g h t AspectRatio=\frac {Width} {Height} AspectRatio=HeightWidth
x,y,w,h = cv.boundingRect(cnt)
aspect_ratio = float(w)/h
cv.boundingRect()函数,查找矩形边界,在《轮廓特征》中已经介绍过。https://blog.csdn.net/weixin_42555985/article/details/97115338
范围是轮廓区域面积与边界矩形区域面积的比率。
E x t e n t = O b j e c t A r e a B o u n d i n g R e c t a n g l e A r e a Extent=\frac {Object Area} {Bounding Rectangle Area} Extent=BoundingRectangleAreaObjectArea
area = cv.contourArea(cnt)
x,y,w,h = cv.boundingRect(cnt)
rect_area = w*h
extent = float(area)/rect_area
cv.contourArea(cnt)函数,获取轮廓面积,在《轮廓特征》中已经介绍过。https://blog.csdn.net/weixin_42555985/article/details/97115338
密实度是轮廓区域面积与凸包面积的比率。
S o l i d i t y = C o n t o u r A r e a C o n v e x H u l l A r e a Solidity=\frac {Contour Area} {Convex Hull Area} Solidity=ConvexHullAreaContourArea
area = cv.contourArea(cnt)
hull = cv.convexHull(cnt)
hull_area = cv.contourArea(hull)
solidity = float(area)/hull_area
cv.convexHull(cnt)函数,获取凸包,在《轮廓特征》中已经介绍过。https://blog.csdn.net/weixin_42555985/article/details/97115338
当量直径是与轮廓面积相等的圆的直径。
E q u i v a l e n t D i a m e t e r = 4 × C o n t o u r A r e a π Equivalent Diameter=\sqrt \frac {4×Contour Area} {π} EquivalentDiameter=π4×ContourArea
area = cv.contourArea(cnt)
equi_diameter = np.sqrt(4*area/np.pi)
方向是指向对象的角度。
(x,y),(MA,ma),angle = cv.fitEllipse(cnt)
cv.fitEllipse(cnt)函数,获得拟合椭圆,在《轮廓特征》中已经介绍过。https://blog.csdn.net/weixin_42555985/article/details/97115338
不过但是返回值是一个结构体
ellipse = cv2.fitEllipse(cnt)
这里返回的是椭圆的中心坐标,短轴(Minor Axis)长轴(Major Axis),旋转角度。
有时候我们需要构成对象的所有像素点。
mask = np.zeros(imgray.shape,np.uint8)
cv.drawContours(mask,[cnt],0,255,-1)
pixelpoints = np.transpose(np.nonzero(mask))
#pixelpoints = cv.findNonZero(mask)
上面代码使用了2种方法,第1种方法使用了numpy 函数,第2种使用了OpenCV的 cv.findNonZero(mask)函数,结果是相同的。
2者的区别是numpy返回的坐标是(row, column),而opencv返回的坐标是(x,y)。通常2者可以互换, row = x 和column = y。
我们可以使用蒙板图像来获得这些参数。
min_val, max_val, min_loc, max_loc = cv.minMaxLoc(imgray,mask = mask)
我们可以使用和上面相同的蒙板来获得物体的平均颜色和物体灰度图的平均强度。
mean_val = cv.mean(im,mask = mask)
极值点是对象最上面、最下面、最右边和最左边的点。
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])
测试一下
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('5.jpg',0)
ret,thresh = cv2.threshold(img,127,255,0)
im2,contours,hierarchy = cv2.findContours(thresh, 1, 2)
cnt = contours[0]
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
img2 = cv2.imread('5.jpg')
cv2.circle(img2,leftmost,1, (0,0,255), -1)
cv2.circle(img2,rightmost,1, (0,0,255), -1)
cv2.circle(img2,topmost,1, (0,0,255), -1)
cv2.circle(img2,bottommost,1, (0,0,255), -1)
cv2.imshow('result2', img2)
cv2.waitKey(0)