十九 对象测量

找到轮廓之后,怎么测量弧长面积多边形拟合,中心距等等

原点矩就是几何图形的重心;
中心矩反映几何图形上点的分布规律,相当于将坐标原点移到重心上,此时的原点矩。

 

 

 二、相关函数

1、几何计算

(1)cv.contourArea(contour)  获取每个轮廓面积

(2)cv.boundingRect(contour)  获取轮廓的外接矩形

矩形边框(Bounding Rectangle)是说,用一个最小的矩形,把找到的形状包起来。还有一个带旋转的矩形,面积会更小,效果见下图

contour轮廓点的位置信息,是一个二值图;

返回四个值,分别是x,y,w,h;

x,y是矩阵左上点的坐标,w,h是矩阵的宽和高

 

然后利用cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)画出矩形

参数解释

第一个参数:img是原图

第二个参数:(x,y)是矩阵的左上点坐标

第三个参数:(x+w,y+h)是矩阵的右下点坐标

第四个参数:(0,255,0)是画线对应的rgb颜色

第五个参数:2是所画的线的宽度

(3)cv.moments(contour)  求取轮廓的图像矩

 

(4)cv.arcLength(contour,True)  求取轮廓的周长,指定闭合

2、approPolyDP轮廓逼近方法

def approxPolyDP(curve, epsilon, closed, approxCurve=None): # real signature unknown; restored from __doc__

第一个参数curve:输入的点集,直接使用轮廓点集contour

第二个参数epsilon:指定的精度,也即是原始曲线与近似曲线之间的最大距离

第三个参数closed:若为true,则说明近似曲线是闭合的,反之,若为false,则断开

第四个参数approxCurve:输出的点集,当前点集是能最小包容指定点集的。画出来即是一个多边形

  • 输出的点集,当前点集是能最小包容指定点集的。画出来即是一个多边形

  • approxCurve = cv.approxPolyDP(contour,4,True)   #4是与阈值的间隔大小,越小越易找出,True是是否找闭合图像
    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)

     

三、获取图像外接矩形boundingRect和几何矩moments

 

 1 import cv2 as cv
 2 import numpy as np
 3 
 4 def meaure(image):
 5     gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY)
 6     #全局自适应阈值 参数0可改为任意数字但不起作用,gray是灰度图,像素值最大是255,所以写255
 7     ret , binary = cv.threshold(gray,0,255,cv.THRESH_BINARY_INV|cv.THRESH_OTSU)
 8     print('threshold value',ret)
 9     cv.imshow('binary image',binary)
10     outimage,contours,hirachy = cv.findContours(binary,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)
11     for i , contour in enumerate(contours):
12         area = cv.contourArea(contour)  #获取每个轮廓的面积
13         x,y,w,h = cv.boundingRect(contour)
14         rate = min(w,h)/max(w,h)    #获得外接矩形的宽高比,可以起到一定的筛选作用
15         print('rectangle rate: %s'%rate)
16         mm = cv.moments(contour)    #求取轮廓的几何矩
17         print(type(mm))
18         print(mm)
19         cx = mm['m10']/mm['m00']    #重心坐标
20         cy = mm['m01']/mm['m00']    #重心坐标
21         cv.circle(image,(np.int(cx),np.int(cy)),2,(0,255,255),-1)   #半径是2,-1表示填充,画个圆点
22         cv.rectangle(image,(x,y),(x+w,y+h),(0,0,255),2)
23         print('contour area',area)
24     cv.imshow('measured_image',image)
25 img = cv.imread('contours.png')
26 cv.imshow('input_image',img)
27 meaure(img)
28 cv.waitKey(0)
29 cv.destroyAllWindows()
 1 threshold value 55.0
 2 rectangle rate: 0.7071290944123314
 3 <class 'dict'>
 4 {'nu21': 0.0, 'm00': 189588.0, 'mu02': 2116370844.0, 'm21': 3174612636832.0, 'm10': 49672056.0, 'mu12': 0.0, 'm20': 17253329548.0, 'm11': 9139658304.0, 'mu11': 0.0, 'nu03': 0.0, 'nu20': 0.11794171220400729, 'mu20': 4239250876.0, 'nu30': 0.0, 'nu11': 0.0, 'mu03': 0.0, 'nu12': 0.0, 'mu21': 0.0, 'm01': 34884192.0, 'm30': 6741739800600.0, 'm03': 2349275910240.0, 'mu30': 0.0, 'm02': 8535062172.0, 'nu02': 0.05888030888030888, 'm12': 2236186289064.0}
 5 contour area 189588.0
 6 rectangle rate: 0.2328767123287671
 7 <class 'dict'>
 8 {'nu21': 0.00012337159954486592, 'm00': 4638.5, 'mu02': 395646.24861073494, 'm21': 63361445232.433334, 'm10': 1068926.6666666665, 'mu12': -41552.704846039414, 'm20': 254451863.5833333, 'm11': 266174910.2083333, 'mu11': -657.9870841801167, 'nu03': -5.5731840906128935e-08, 'nu20': 0.3774605687931838, 'mu20': 8121321.660058409, 'nu30': 4.147758615136351e-05, 'nu11': -3.058174388962807e-05, 'mu03': -81.66712951660156, 'nu12': -2.835668094870454e-05, 'mu21': 180783.62808203697, 'm01': 1155042.1666666665, 'm30': 62380696103.3, 'm03': 71916234563.05, 'mu30': 60779.53545379639, 'm02': 288015007.4166666, 'nu02': 0.01838873822421945, 'm12': 66371716951.6}
 9 contour area 4638.5
10 rectangle rate: 0.15555555555555556
11 <class 'dict'>
12 {'nu21': 3.8371793569830693e-05, 'm00': 2678.5, 'mu02': 89193.07461163402, 'm21': 36282586368.316666, 'm10': 616088.3333333333, 'mu12': 2005.2493966259062, 'm20': 145711489.91666666, 'm11': 153407428.875, 'mu11': 322.1481836140156, 'nu03': -8.185951318082867e-08, 'nu20': 0.5580295542656055, 'mu20': 4003506.1685074866, 'nu30': -3.5402871905680954e-06, 'nu11': 4.490269272561691e-05, 'mu03': -30.394729614257812, 'nu12': 5.40056587103005e-06, 'mu21': 14247.584001541138, 'm01': 666951.3333333333, 'm30': 35357167196.200005, 'm03': 41418876646.700005, 'mu30': -1314.5212783813477, 'm02': 166161278.5833333, 'nu02': 0.012432195574127027, 'm12': 38219324350.316666}
13 contour area 2678.5
14 rectangle rate: 0.1572052401746725
15 <class 'dict'>
16 {'nu21': -5.0325287139101995e-16, 'm00': 7978.0, 'mu02': 814035.5000000596, 'm21': 106182743120.5, 'm10': 2042368.0, 'mu12': -1.5228986740112305e-05, 'm20': 557389727.6666666, 'm11': 389071104.0, 'mu11': 5.960464477539063e-08, 'nu03': -2.68401531408544e-15, 'nu20': 0.5427233689755546, 'mu20': 34543519.66666669, 'nu30': 5.36803062817088e-15, 'nu11': 9.364660558983717e-16, 'mu03': -1.52587890625e-05, 'nu12': -2.6787730966751167e-15, 'mu21': -2.86102294921875e-06, 'm01': 1519809.0, 'm30': 160378052352.0, 'm03': 55619469850.5, 'mu30': 3.0517578125e-05, 'm02': 290337650.0, 'nu02': 0.012789550494243657, 'm12': 74326438400.0}
17 contour area 7978.0
18 rectangle rate: 0.6910112359550562
19 <class 'dict'>
20 {'nu21': 0.012773324262564329, 'm00': 11273.5, 'mu02': 20750773.8061198, 'm21': 17397875250.05, 'm10': 823135.1666666666, 'mu12': -351678.8153767586, 'm20': 67251828.58333333, 'm11': 210835642.2083333, 'mu11': -3017.880377650261, 'nu03': -0.03671091137116082, 'nu20': 0.05626305607377813, 'mu20': 7150573.196509272, 'nu30': -8.927214266694102e-06, 'nu11': -2.3745673003470692e-05, 'mu03': -495384129.6209717, 'nu12': -2.606149258816397e-05, 'mu21': 172365705.06794214, 'm01': 2887605.5, 'm30': 5954474083.55, 'm03': 204900612520.65002, 'mu30': -120465.55381679535, 'm02': 760384917.9166666, 'nu02': 0.1632738968112304, 'm12': 55517645149.51666}
21 contour area 11273.5
22 rectangle rate: 1.0
23 <class 'dict'>
24 {'nu21': -0.00012249343654428105, 'm00': 937.0, 'mu02': 71058.39887940139, 'm21': 2608467731.1666665, 'm10': 135997.16666666666, 'mu12': 5936.621304638684, 'm20': 19807560.666666664, 'm11': 17909800.0, 'mu11': -243.08831376582384, 'nu03': 0.00011619106641937682, 'nu20': 0.07834979461427596, 'mu20': 68788.69082770124, 'nu30': -0.00022638241437502373, 'nu11': -0.00027687573680371845, 'mu03': 3122.63853597641, 'nu12': 0.00022089728041426173, 'mu21': -3292.0149297602475, 'm01': 123397.5, 'm30': 2894852254.65, 'm03': 2168205818.75, 'mu30': -6084.034451007843, 'm02': 16321798.0, 'nu02': 0.08093497478772188, 'm12': 2368904858.633333}
25 contour area 937.0
26 rectangle rate: 0.9767441860465116
27 <class 'dict'>
28 {'nu21': 6.394444079962859e-05, 'm00': 1337.5, 'mu02': 143608.10929387622, 'm21': 17579855687.9, 'm10': 466171.8333333333, 'mu12': 2721.5148126482964, 'm20': 162620703.91666666, 'm11': 50394767.125, 'mu11': -5.531905494630337, 'nu03': -6.349478218615885e-05, 'nu20': 0.07899706959873945, 'mu20': 141318.35153687, 'nu30': -4.34086448861369e-05, 'nu11': -3.0923395201008077e-06, 'mu03': -4154.057602882385, 'nu12': 4.159836159363943e-05, 'mu21': 4183.47589077428, 'm01': 144588.3333333333, 'm30': 56778276750.950005, 'm03': 1736279429.2, 'mu30': -2839.9500732421875, 'm02': 15774102.416666666, 'nu02': 0.0802770459848727, 'm12': 5497902267.733334}
29 contour area 1337.5
30 rectangle rate: 1.0
31 <class 'dict'>
32 {'nu21': 0.00017643873342657596, 'm00': 1171.5, 'mu02': 108556.00897472398, 'm21': 7454198465.65, 'm10': 414346.8333333333, 'mu12': 11056.098625324667, 'm20': 146660034.25, 'm11': 21059689.791666664, 'mu11': 35.98085905984044, 'nu03': -0.00019657490281580083, 'nu20': 0.08019241081548555, 'mu20': 110057.04696020484, 'nu30': -0.0002541097288689007, 'nu11': 2.621723834062283e-05, 'mu03': -9233.870977252722, 'nu12': 0.00023536732516071226, 'mu21': 8287.998500894755, 'm01': 59542.83333333333, 'm30': 51949902144.450005, 'm03': 170360064.45000002, 'mu30': -11936.500625610352, 'm02': 3134888.9166666665, 'nu02': 0.07909868844053526, 'm12': 1108790894.15}
33 contour area 1171.5
34 rectangle rate: 0.9827586206896551
35 <class 'dict'>
36 {'nu21': -5.9617117618475176e-05, 'm00': 10188.0, 'mu02': 8080978.927321911, 'm21': 44361328538.15, 'm10': 2369605.833333333, 'mu12': 65883.69320464134, 'm20': 559585560.1666666, 'm11': 187859907.5833333, 'mu11': -6170.492562055588, 'nu03': 5.789763072450438e-05, 'nu20': 0.08135089273197578, 'mu20': 8443843.895822525, 'nu30': -6.649191036488463e-06, 'nu11': -5.944864503802395e-05, 'mu03': 606573.080696106, 'nu12': 6.288623516809079e-06, 'mu21': -624587.5391366482, 'm01': 807720.6666666666, 'm30': 134080649922.85, 'm03': 6999607777.200001, 'mu30': -69661.23208618164, 'm02': 72118344.0, 'nu02': 0.0778549269736214, 'm12': 16772943834.616667}
37 contour area 10188.0
38 rectangle rate: 0.9069767441860465
39 <class 'dict'>
40 {'nu21': 2.5029581296177077e-06, 'm00': 6468.0, 'mu02': 3195020.3257575743, 'm21': 2470652874.1666665, 'm10': 485015.3333333333, 'mu12': -51429.50591498613, 'm20': 40173096.0, 'm11': 29828671.666666664, 'mu11': -296.2417027428746, 'nu03': 3.7404301111953477e-06, 'nu20': 0.09091174159972219, 'mu20': 3803294.891706176, 'nu30': -7.103004931735946e-07, 'nu11': -7.081188784375375e-06, 'mu03': 12584.80737566948, 'nu12': -1.528577011835907e-05, 'mu21': 8421.289796680212, 'm01': 397789.0, 'm30': 3582848603.8, 'm03': 2094094606.5, 'mu30': -2389.830746650696, 'm02': 27659474.333333332, 'nu02': 0.07637190134652665, 'm12': 2074010642.2666667}
41 contour area 6468.0
42 rectangle rate: 0.22885572139303484
43 <class 'dict'>
44 {'nu21': 5.8846255461310086e-06, 'm00': 8996.5, 'mu02': 29965362.62111345, 'm21': 256564644068.48334, 'm10': 4439805.333333333, 'mu12': 212314.99474525452, 'm20': 2192577070.9166665, 'm11': 519527440.5416666, 'mu11': -3233.247374713421, 'nu03': -2.842289825086851e-06, 'nu20': 0.018743698111458488, 'mu20': 1517058.9236574173, 'nu30': -1.4152503746804512e-07, 'nu11': -3.9947698646528944e-05, 'mu03': -21819.87815475464, 'nu12': 2.765646741919632e-05, 'mu21': 45175.48184904456, 'm01': 1052739.3333333333, 'm30': 1083542072586.7001, 'm03': 24934332010.7, 'mu30': -1086.46875, 'm02': 153153280.5833333, 'nu02': 0.37023064958903834, 'm12': 75581154283.31667}
45 contour area 8996.5
46 rectangle rate: 0.19117647058823528
47 <class 'dict'>
48 {'nu21': 4.9640674350614795e-06, 'm00': 6161.5, 'mu02': 16228397.796561554, 'm21': 120405497566.23334, 'm10': 2520171.833333333, 'mu12': 189011.2604341507, 'm20': 1031361607.9166666, 'm11': 294213998.7916666, 'mu11': 1439.863492667675, 'nu03': -0.00013813884205259537, 'nu20': 0.014827896369745835, 'mu20': 562927.4773755074, 'nu30': -2.1518071719240386e-06, 'nu11': 3.7926993287653485e-05, 'mu03': -411653.62416648865, 'nu12': 6.342661674397237e-05, 'mu21': 14792.916459165514, 'm01': 719312.3333333333, 'm30': 422307195112.95, 'm03': 15486711827.2, 'mu30': -6412.3834228515625, 'm02': 100203117.08333333, 'nu02': 0.42746714354095977, 'm12': 40985524515.4}
49 contour area 6161.5

 

 

 四、多边形逼近approxPolyDP

 

 1 import cv2 as cv
 2 import numpy as np
 3 
 4 def measure(image):
 5     #变成灰度图像,通过大律法得到二值图像
 6     gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY)
 7     ret , binary = cv.threshold(gray,0,255,cv.THRESH_BINARY|cv.THRESH_OTSU)
 8     cv.imshow('binary image',binary)
 9     #将二值图像变成bgr,因为后面要用各种颜色画轮廓,所以需要变成BGR
10     dst = cv.cvtColor(binary,cv.COLOR_GRAY2BGR)
11     cv.imshow('binary_to_bgr',dst)
12     #寻找轮廓
13     outimage,contours,hireachy = cv.findContours(binary,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)
14     for i,contour in enumerate(contours):
15         mm = cv.moments(contour)    #求的是每个轮廓的几何矩
16         cx = mm['m10']/mm['m00']    #重心坐标x
17         cy = mm['m01']/mm['m00']    #重心坐标y
18         cv.circle(dst,(np.int(cx),np.int(cy)),2,(0,255,255),-1)     #画重心点,填充的方法
19         #多边形逼近
20         #arg:
21         #   每个轮廓的位置信息contour
22         #   4是与阈值的间隔大小,越小就越容易找出,True是 是否找闭合图像
23         approxcure = cv.approxPolyDP(contour,4,True)
24         print(approxcure.shape)     #每个轮廓的信息
25 
26         if approxcure.shape[0] >= 7:        #>=7 就都是圆了
27             cv.drawContours(dst,contours,i,(0,0,255),2)
28         elif approxcure.shape[0] == 4:      #4说明有四个点,是矩形;3是三个点,三角形
29             cv.drawContours(dst,contours,i,(0,255,0),2)
30         else:
31             cv.drawContours(dst,contours,i,(255,0,0),2)
32     cv.imshow('measure_image',dst)
33 
34 img = cv.imread('contours.png')
35 cv.imshow('input_image',img)
36 measure(img)
37 cv.waitKey(0)
38 cv.destroyAllWindows()
 1 (4, 1, 2)
 2 (4, 1, 2)
 3 (4, 1, 2)
 4 (3, 1, 2)
 5 (7, 1, 2)
 6 (8, 1, 2)
 7 (8, 1, 2)
 8 (13, 1, 2)
 9 (4, 1, 2)
10 (4, 1, 2)
11 (9, 1, 2)
12 (4, 1, 2)

 

 

 

 

posted @ 2018-11-01 14:38  Austin_anheqiao  阅读(505)  评论(0编辑  收藏  举报