一:获取图像的外接矩形boundingRect和几何距moments
import cv2 as cv
import numpy as np
def measure_object(image):
gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY) #转灰度图像
ret, binary = cv.threshold(gray,0,255,cv.THRESH_OTSU|cv.THRESH_BINARY_INV) #获取二值化图像
print("thresold value:",ret)
cv.imshow("binary image",binary)
outImage,contours,hireachy = cv.findContours(binary,cv.RETR_EXTERNAL,cv.CHAIN_APPROX_SIMPLE)
for i,contour in enumerate(contours):
area = cv.contourArea(contour) #获取每个轮廓面积
x,y,w,h = cv.boundingRect(contour) #获取轮廓的外接矩形
rate = min(w,h)/max(w,h) #获取外接矩形宽高比,可以起到一定的筛选作用
print("rectangle rate:%s"%rate)
mm = cv.moments(contour) #求取轮廓的几何距
print(type(mm))
print(mm)
cx = mm['m10']/mm['m00']
cy = mm['m01']/mm['m00']
cv.circle(image,(np.int(cx),np.int(cy)),2,(0,255,255),-1) #根据几何距获取的中心点,画出中心圆
cv.rectangle(image,(x,y),(x+w,y+h),(0,0,255),2) #根据轮廓外接矩形返回数据,画出外接矩形
print("contour area:",area)
cv.imshow("measure_object",image)
src = cv.imread("./dg.png") #读取图片
cv.namedWindow("input image",cv.WINDOW_AUTOSIZE) #创建GUI窗口,形式为自适应
cv.imshow("input image",src) #通过名字将图像和窗口联系
measure_object(src)
cv.waitKey(0) #等待用户操作,里面等待参数是毫秒,我们填写0,代表是永远,等待用户操作
cv.destroyAllWindows() #销毁所有窗口
mm-->{'m02': 3301.25, 'm12': 233530.03333333333, 'm30': 6934377.600000001, 'mu11': -10.721153846156085, 'm21': 1265395.2, 'nu02': 0.08336283484212434, 'm01': 252.5, 'mu30': -12.458842864260077, 'nu21': 0.003451665836783194, 'mu12': 11.46577909273492, 'nu12': 0.006828369938345303, 'mu02': 31.698717948717785, 'mu21': 5.795825115486707, 'm03': 43556.350000000006, 'nu30': -0.007419782588937784, 'm20': 97840.41666666666, 'm00': 19.5, 'm10': 1381.0, 'nu20': 0.09806301522275791, 'mu03': -11.52064431294275, 'm11': 17871.458333333332, 'nu03': -0.0068610445623109115, 'mu20': 37.2884615384537, 'nu11': -0.028195013402119877}
二:多边形逼近approxPolyDP
import cv2 as cv
import numpy as np
def measure_object(image):
gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY) #转灰度图像
ret, binary = cv.threshold(gray,0,255,cv.THRESH_OTSU|cv.THRESH_BINARY) #获取二值化图像
cv.imshow("binary image",binary)
dst = cv.cvtColor(binary,cv.COLOR_GRAY2BGR)
outImage,contours,hireachy = cv.findContours(binary,cv.RETR_EXTERNAL,cv.CHAIN_APPROX_SIMPLE)
for i,contour in enumerate(contours):
mm = cv.moments(contour) #求取轮廓的几何距
cx = mm['m10']/mm['m00']
cy = mm['m01']/mm['m00']
cv.circle(dst,(np.int(cx),np.int(cy)),2,(0,255,255),-1) #画出中心点
approxCurve = cv.approxPolyDP(contour,4,True) #4是与阈值的间隔大小,越小越易找出,True是是否找闭合图像
print(approxCurve.shape)
if approxCurve.shape[0] >= 7:
cv.drawContours(dst,contours,i,(0,255,0),2) #画出轮廓
elif approxCurve.shape[0] == 4:
cv.drawContours(dst,contours,i,(0,0,255),2)
else:
cv.drawContours(dst,contours,i,(255,0,0),2)
cv.imshow("measure_object",dst)
src = cv.imread("./lk.png") #读取图片
cv.namedWindow("input image",cv.WINDOW_AUTOSIZE) #创建GUI窗口,形式为自适应
cv.imshow("input image",src) #通过名字将图像和窗口联系
measure_object(src)
cv.waitKey(0) #等待用户操作,里面等待参数是毫秒,我们填写0,代表是永远,等待用户操作
cv.destroyAllWindows() #销毁所有窗口
相关知识补充
(一)相关函数方法
cv.contourArea(contour) #获取每个轮廓面积
cv.boundingRect(contour) #获取轮廓的外接矩形
cv.moments(contour) #求取轮廓的几何距
cv.arcLength(contour,True) #求取轮廓的周长,指定闭合
(二)approxPolyDP轮廓逼近方法
approxCurve = cv.approxPolyDP(contour,4,True) #4是与阈值的间隔大小,越小越易找出,True是是否找闭合图像
def approxPolyDP(curve, epsilon, closed, approxCurve=None): # real signature unknown; restored from __doc__
第一个参数curve:输入的点集,直接使用轮廓点集contour
第二个参数epsilon:指定的精度,也即是原始曲线与近似曲线之间的最大距离。
第三个参数closed:若为true,则说明近似曲线是闭合的,反之,若为false,则断开。
第四个参数approxCurve:输出的点集,当前点集是能最小包容指定点集的。画出来即是一个多边形;
返回值
approxCurve:输出的点集,当前点集是能最小包容指定点集的。画出来即是一个多边形;
print(approxCurve) #打印每个轮廓的特征点
print(approxCurve.shape) #打印该点集的shape,第一个数是代表了点的个数,也就是边长连接逼近数
[[[138 208]]
[[138 234]]
[[265 234]]
[[264 207]]]
(4, 1, 2) #矩形,四个点逼近图像
[[[124 154]]
[[124 183]]
[[325 183]]
[[325 154]]]
(4, 1, 2)
[[[ 61 125]]
[[ 9 279]]
[[114 280]]]
(3, 1, 2) #3是三角形
[[[123 102]]
[[111 118]]
[[117 128]]
[[129 131]]
[[139 124]]
[[141 114]]
[[134 104]]]
(7, 1, 2) #7,8,9都是圆形类
[[[303 78]]
[[291 87]]
[[289 99]]
[[298 111]]
[[310 113]]
[[322 105]]
[[324 91]]
[[314 79]]]
(8, 1, 2)
[[[308 28]]
[[298 35]]
[[295 48]]
[[303 59]]
[[314 61]]
[[325 54]]
[[327 39]]]
(7, 1, 2)
[[[198 21]]
[[165 38]]
[[153 75]]
[[170 107]]
[[185 116]]
[[210 119]]
[[244 100]]
[[254 63]]
[[235 31]]]
(9, 1, 2)
[[[ 27 21]]
[[ 27 87]]
[[101 87]]
[[101 21]]]
(4, 1, 2)
[[[418 15]]
[[416 190]]
[[454 192]]
[[455 16]]]
(4, 1, 2)
[[[359 14]]
[[346 58]]
[[345 138]]
[[356 190]]
[[363 192]]
[[374 156]]
[[376 82]]
[[369 24]]]
(8, 1, 2)