轮廓特征之矩、面积、周长

轮廓特征

查找轮廓的不同特征,例如矩、面积、周等。

  1. 图像矩

    原始矩

    对于二维连续函数 f ( x , p + q ) f(x,p+q) 阶的矩被定义为
    M p q = x p y q f ( x , y ) d x d y M _ { p q } = \int _ { - \infty } ^ { \infty } \int _ { - \infty } ^ { \infty } x ^ { p } y ^ { q } f ( x , y ) d x d y
    图像矩

    对于 p , q p,q =0,1,2…对于灰度图像的像素的强度 I ( x , y ) I(x,y) ,原始图像的矩 M i j M_{ij} 被计算为
    M p q = x y x p y q I ( x , y ) M_ { p q} = \sum _ { x } \sum _ { y } x ^ { p } y ^ { q } I ( x , y )
    图像中心矩
    中心矩被定义为
    M u p q = x y ( x x ˉ ) p ( y y ˉ ) q I ( x , y ) {Mu} _ { p q } = \sum _ { x } \sum _ { y } ( x - \bar { x } ) ^ { p } ( y - \bar { y } ) ^ { q } I ( x , y )
    标准化的中心距

    标准化中心距的定义:
    N u p q = M u p q M 00 ( p + q ) / 2 + 1 \mathrm { Nu } _ { p q } = \frac { \mathrm { Mu } _ { pq } } { \mathrm { M } _ { 00 } ^ { ( p+ q ) / 2 + 1 } }
    图像矩作用

    • 二值图像的面积或灰度图像的像素总和,可以表示为:$ M_{00}$

    • 图像的几何中心可以表示为:
      { x ˉ , y ˉ } = { M 10 M 00 , M 01 M 00 } \{ \bar { x } , \bar { y } \} = \left\{ \frac { M _ { 10 } } { M _ { 00 } } , \frac { M _ { 01 } } { M _ { 00 } } \right\}

    函数 cv2.moments() 会将计算得到的矩以一个字典的形式返回。如下:

   cv2.moments(cnt)

参数

cnt:findContours函数返回的轮廓参数

例:

   import cv2 
   import numpy as np
   import matplotlib.pyplot as plt

   img = cv2.imread("my_mask.png")
   # BGR转灰度图像
   img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
   # 二值化
   ret,thresh = cv2.threshold(img_gray,12,255,0)
   plt.imshow(thresh)
   # 查找轮廓
   image,contours,hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
   # 绘制轮廓
   img = cv2.drawContours(img,contours,-1,(0,255,0),3)
   cnt = contours[0]
   M = cv2.moments(cnt)
   # 查看矩
   print(M)
   # 求面积
   print(M['m00'])
   # 计算轮廓几何中心
   cx = int(M['m10']/M['m00'])
   cy = int(M['m01']/M['m00'])
   print(cx,cy)
   # 将中心标记为红色
   img[cy,cx]=(0,0,255)
   # 显示图像
   cv2.imshow('img',img) # 在原图上绘制轮廓
   cv2.waitKey(0)
   cv2.destroyAllWindows()

输出结果:

   矩:
   {'m00': 118836.5, 'm10': 40229442.666666664, 'm01': 30592125.5, 'm20': 15292343026.916666, 'm11': 10355876833.791666, 'm02': 8703205239.083332, 'm30': 6309976487782.301, 'm21': 3936335965411.1, 'm12': 2946102101582.433, 'm03': 2666709947918.0503, 'mu20': 1673563802.7673512, 'mu11': -403928.8841228485, 'mu02': 827862708.734909, 'mu30': 48344.759765625, 'mu21': -104247829.05792236, 'mu12': 34335401.97906494, 'mu03': 6479782.6591796875, 'nu20': 0.11850660846509918, 'nu11': -2.8602579739916363e-05, 'nu02': 0.058621727910628446, 'nu30': 9.930583684466686e-09, 'nu21': -2.1413733265042987e-05, 'nu12': 7.052896412060584e-06, 'nu03': 1.3310237607157145e-06}
   M00:
   118836.5
   图像几何中心:
   338 257

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uBtdND9C-1582442951636)(C:\Users\67231\Desktop\ImageSegmentation\img.png)]

轮廓面积

轮廓的面积可以使用函数 cv2.contourArea() 计算得到,也可以使用矩(0 阶矩),M['m00']

   area = cv2.contourArea(cnt)

轮廓周长

也被称为弧长。可以使用函数 cv2.arcLength() 计算得到。这个函数的第二参数可以用来指定对象的形状是闭合的(True),还是打开的(一条曲线)。

   perimeter = cv2.arcLength(cnt,True)

例:求矩形的面积,周长,几何中心。

   import cv2 
   import numpy as np
   import matplotlib.pyplot as plt

   # 图像:利用Pohtoshp绘制的一个100*100像素大小的黄色矩形
   img = cv2.imread("square.jpg")

   # BGR转灰度图像
   img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

   # 二值化,注意图像的灰度:黄色区域218,白色区域为255
   ret,thresh = cv2.threshold(img_gray,220,255,0)
   # thresh = cv2.Canny(img,100,200)

   # 查找轮廓
   image,contours,hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
   # print(hierarchy)

   # 绘制轮廓
   img = cv2.drawContours(img,contours,1,(255,204,102),5)
   # print(contours)

   # 选择矩形轮廓,矩形实际大小为100*100像素
   cnt = contours[1]

   # 查看矩
   M = cv2.moments(cnt)
   # print(M)

   # 求矩形面积
   print('矩形面积:',M['m00'])
   area = cv2.contourArea(cnt)
   print('矩形面积:',area)

   # 求矩形的周长
   perimeter = cv2.arcLength(cnt,True)
   print('矩形的周长',perimeter)

   # 计算图像几何中心
   cx = int(M['m10']/M['m00'])
   cy = int(M['m01']/M['m00'])


   print('矩形几何中心:',cx,cy)

   # 由于一个像素很难看清,将中心附近5*5的区域标记天蓝色
   color = (255,204,102)
   for i in range(5):
       for j in range(5):
           img[cy-2+i,cx-2+j] = color

   # 显示图像
   cv2.namedWindow('img',cv2.WINDOW_NORMAL)
   cv2.imshow('img',img ) # 在原图上绘制轮廓
   cv2.waitKey(0)
   cv2.destroyAllWindows()

输出结果:

   矩形面积: 10199.0
   矩形面积: 10199.0
   矩形的周长 401.65685415267944
   矩形几何中心: 392 280

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LsvqwqlD-1582442951637)(C:\Users\67231\Desktop\ImageSegmentation\矩形面积,周长.png)]

发布了82 篇原创文章 · 获赞 39 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qq_28368377/article/details/104460965