2019-7-26 opencv图像处理9-轮廓3(Contours)轮廓的特性(长宽比/范围/密实度/当量直径/方向/蒙板和像素点/最大小值/平均颜色和强度/极值点)

官网参见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]

内容概要

  • 长宽比
  • 范围(Extent)
  • 密实度(Solidity)
  • 当量直径(Equivalent Diameter)
  • 方向
  • 蒙板和像素点(Mask and Pixel Points)
  • 最大值,最小值和它们的位置
  • 平均颜色和平均强度(Mean Color or Mean Intensity)
  • 极值点(Extreme Points)

1.长宽比

这是对象矩形边界的宽度与高度之比。
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

2.范围(Extent)

范围是轮廓区域面积与边界矩形区域面积的比率。
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

3.密实度(Solidity)

密实度是轮廓区域面积与凸包面积的比率。
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

4.当量直径(Equivalent Diameter)

当量直径是与轮廓面积相等的圆的直径。

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)

5.方向

方向是指向对象的角度。

(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),旋转角度。

6.蒙板和像素点(Mask and Pixel Points)

有时候我们需要构成对象的所有像素点。

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。

7.最大值,最小值和它们的位置

我们可以使用蒙板图像来获得这些参数。

min_val, max_val, min_loc, max_loc = cv.minMaxLoc(imgray,mask = mask)

8.平均颜色和平均强度(Mean Color or Mean Intensity)

我们可以使用和上面相同的蒙板来获得物体的平均颜色和物体灰度图的平均强度。

mean_val = cv.mean(im,mask = mask)

9.极值点(Extreme Points)

极值点是对象最上面、最下面、最右边和最左边的点。

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)

2019-7-26 opencv图像处理9-轮廓3(Contours)轮廓的特性(长宽比/范围/密实度/当量直径/方向/蒙板和像素点/最大小值/平均颜色和强度/极值点)_第1张图片
结果如上图,4个红色点。

你可能感兴趣的:(IT,opencv)