python+opencv 轮廓属性学习

x,y,w,h = cv.boundingRect(cnt)
area = cv.contourArea(cnt)

#面积,长度,长宽比。
# 如何让将指定轮廓的目标保存,消除不满足条件的轮廓

参考代码

# 找出轮廓的不同特征,如面积、周长、质心、边界盒等
# moments矩可以计算物体的质心、面积等特征;函数cv2.moments()提供了一个计算出所有力矩值的字典。

import cv2
import numpy as np

image = cv2.imread('opencv_logo.jpg') 
img = cv2.imread('opencv_logo.jpg', 0)# 0代表读取的方式,可以直接读取灰度图
ret, thresh = cv2.threshold(img, 127, 255, 0)  #127 阈值,255为最大值
contours, hierarchy = cv2.findContours(thresh, 1, 2) # 寻找轮廓,相当比matlab bwlable,然后直接可以根据轮廓提取属性
# print(contours)

cnt = contours[0]  # 第0个轮廓,轮廓cnt 的结构是三维的(523,1,2)
cv2.drawContours(image, cnt, -1, (255, 255, 255), -1) # 显示指定轮廓

# 求质心然后绘制圆形
M = cv2.moments(cnt)
# 力矩
print('力矩:', M)
# 质心
cx = int(M['m10'] / M['m00'])
cy = int(M['m01'] / M['m00'])
print('质心:', (cx, cy))
cv2.circle(image, (cx, cy), 3, (255, 255, 255), -1)

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

# 等高线周长也称为弧长。可以使用cv2.arcLength(cnt,True),True标识闭合区域,False表示曲线
perimeter = cv2.arcLength(cnt, True)
print('周长:', perimeter)

# 轮廓近似:它将一个轮廓形状近似为另一个具有较少顶点数的形状,具体取决于我们指定的精度。它是Douglas-Peucker算法的一个实现。
epsilon = 0.1 * cv2.arcLength(cnt, True)
# epsilon表示近似轮廓10%,True表示闭合区域
approx = cv2.approxPolyDP(cnt, epsilon, True)
print('近似轮廓:', approx)

# 凸包:cv2.convexHull()函数检查曲线的凸度缺陷并进行校正。
hull = cv2.convexHull(cnt)
print('凸包:', hull)

# 检查凸性,即检查曲线是否凸,cv2.isContourConvex()
k = cv2.isContourConvex(cnt)
print('检查是否凸:', k)

# 边框(边界矩形) cv2.boundingRect()计算得到直角矩形,(x,y)为矩形的左上角坐标,(w,h)为矩形的宽度和高度。)
x, y, w, h = cv2.boundingRect(cnt)
aspect_ratio = float(w) / h
print('宽高比: ', aspect_ratio)
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)

# cv2.minarearct(),旋转矩形(边界矩形是以最小面积绘制的,考虑了旋转。) (中心(x,y), 宽度高度(width, height), 旋转角度);
# 使用cv2.boxPoints()得到矩形的4个角点
# 两个矩形都显示在一个图像中。绿色矩形显示法线边界矩形。红色矩形是旋转的矩形。

rect = cv2.minAreaRect(cnt)
box = cv2.boxPoints(rect)
box = np.int0(box)
cv2.drawContours(image, [box], 0, (0, 0, 255), 2)

# cv2.minEnclosingCircle()面积最小外接圆
(x, y), radius = cv2.minEnclosingCircle(cnt)
center = (int(x), int(y))
radius = int(radius)
cv2.circle(image, center, radius, (0, 255, 0), 2)

# 拟合椭圆,返回椭圆内接的旋转矩形。
ellipse = cv2.fitEllipse(cnt)
cv2.ellipse(image, ellipse, (0, 255, 0), 2)

# 拟合线
rows, cols = img.shape[:2]
[vx, vy, x, y] = cv2.fitLine(cnt, cv2.DIST_L2, 0, 0.01, 0.01)
lefty = int((-x * vy / vx) + y)
righty = int(((cols - x) * vy / vx) + y)
cv2.line(image, (cols - 1, righty), (0, lefty), (0, 255, 0), 2)
cv2.imshow("img", image)
cv2.waitKey(0)

import cv2
import numpy as np

img = cv2.imread('opencv_logo.jpg', 0)
ret, thresh = cv2.threshold(img, 127, 255, 0)
contours, hierarchy = cv2.findContours(thresh, 1, 2)
# print(contours)

cnt = contours[0]

x, y, w, h = cv2.boundingRect(cnt)
aspect_ratio = float(w) / h
print('宽高比:', aspect_ratio)

area = cv2.contourArea(cnt)
x, y, w, h = cv2.boundingRect(cnt)
rect_area = w * h
extent = float(area) / rect_area
print('extent: ', extent)

area = cv2.contourArea(cnt)
hull = cv2.convexHull(cnt)
hull_area = cv2.contourArea(hull)
solidity = float(area) / hull_area
print('坚固性: ', solidity)

area = cv2.contourArea(cnt)
equi_diameter = np.sqrt(4 * area / np.pi)
print('等面积圆的直径:', equi_diameter)

(x, y), (MA, ma), angle = cv2.fitEllipse(cnt)
print('方向:', angle)
print('长轴,短轴:', MA, ma)

# Numpy以(行,列)格式给出坐标,OpenCV以(x,y)格式给出坐标。
imgray = img
mask = np.zeros(imgray.shape, np.uint8)
cv2.drawContours(mask, [cnt], 0, 255, -1)
pixelpoints = np.transpose(np.nonzero(mask))
# pixelpoints = cv2.findNonZero(mask)
print('遮罩mask: ', mask)
print('组成轮廓的所有像素点:', pixelpoints)

min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(imgray, mask=mask)
print('最小,最大,最小位置,最大位置:', min_val, max_val, min_loc, max_loc)

mean_val = cv2.mean(imgray, mask=mask)
print('平均颜色/平均强度:', mean_val)

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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值