目录
num_pixels = np.sum(mask == 255)
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
c = max(contours, key=cv2.contourArea)
x, y, w, h = cv2.boundingRect(c)
M = cv2.moments(contours[0]) if contours else None
area = cv2.contourArea(contours[0]) if contours else 0
一、提前准备
1、树莓派4B 及 64位系统
2、提前安装opencv库 以及 numpy库
3、保存一张图片
二、代码详解
1、图像覆盖掩膜
# 这行指定了文件的编码格式为utf-8
# coding=utf-8
import cv2
import numpy as np
# 使用cv2.imread函数读取指定路径下的图片文件。第二个参数1表示读取彩色图像(BGR格式)
img = cv2.imread('/home/raspberry4B/Pictures/MD.jpg', 1)
# 将图像从BGR色彩空间转换为HSV色彩空间。HSV色彩空间更适用于颜色范围检测,因为它基于色调(H)、饱和度(S)和亮度(V)。
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# 定义一个NumPy数组,表示HSV色彩空间中颜色的下界。这里的数值代表色调、饱和度和亮度的最小值。
lower_range = np.array([101, 100, 100], dtype=np.uint8)
# 定义一个NumPy数组,表示HSV色彩空间中颜色的上界。这里的数值代表色调、饱和度和亮度的最大值。
upper_range = np.array([121, 255, 255], dtype=np.uint8)
# 使用cv2.inRange函数根据指定的HSV颜色范围创建一个掩码图像。该掩码图像中,属于指定颜色范围的像素值为255(白色),其他像素值为0(黑色)。
mask = cv2.inRange(hsv, lower_range, upper_range)
2、计算掩膜覆盖的像素
# 计算掩膜覆盖的像素
num_pixels = np.sum(mask == 255) # 或者 np.count_nonzero(mask)
print(f"Number of pixels in the mask: {num_pixels}")
num_pixels = np.sum(mask == 255)
- 功能: 计算掩码图像中像素值为255的总数,即在指定颜色范围内的像素数量。
- 参数:
mask == 255
: 生成一个与mask
大小相同的布尔数组,其中像素值为255的对应位置为True
。
- 结果: 返回符合条件的像素总数。
3、找到最大轮廓
# 使用OpenCV的findContours函数找到轮廓 通过寻找掩膜中所有非零像素的边界,您可以得到这些像素在图像中的位置。
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 假设我们只关心最大的轮廓(即最大的物体)
if contours:
c = max(contours, key=cv2.contourArea)
x, y, w, h = cv2.boundingRect(c)
print(f"Bounding box of the object: ({x}, {y}), ({w}, {h})")
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
- 功能: 使用
cv2.findContours
函数在掩码图像中找到轮廓。 - 参数:
mask
: 输入的二值图像。cv2.RETR_EXTERNAL
: 仅检测外部轮廓,不考虑嵌套轮廓。cv2.CHAIN_APPROX_SIMPLE
: 压缩水平、垂直和对角直线段,保留其端点。
- 结果: 返回的
contours
是一个包含所有轮廓的列表。
c = max(contours, key=cv2.contourArea)
- 功能: 找到最大的轮廓,即具有最大面积的轮廓。
- 参数:
contours
: 包含所有轮廓的列表。key=cv2.contourArea
: 使用轮廓面积作为比较的关键字。
x, y, w, h = cv2.boundingRect(c)
- 功能: 使用
cv2.boundingRect
函数为最大的轮廓计算边界框(bounding box)。 - 参数:
c
: 最大的轮廓。
- 结果: 返回边界框的左上角坐标
(x, y)
及其宽度w
和高度h
。
4、计算掩膜覆盖物体的质心
# 计算掩膜中物体的质心 质心是物体所有像素的加权平均位置
M = cv2.moments(contours[0]) if contours else None
if M != None:
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
print(f"Centroid of the object: ({cX}, {cY})")
M = cv2.moments(contours[0]) if contours else None
- 功能: 计算轮廓的几何矩(moments)。
- 参数:
contours[0]
: 使用第一个(最大)轮廓。
- 结果: 返回一个字典,包含计算出的所有几何矩。如果没有轮廓,返回
None
。
cX = int(M["m10"] / M["m00"])
- 功能: 计算物体的质心(centroid)。
- 参数:
M["m10"]
: 几何矩中的m10
,即第一阶的x方向矩。M["m00"]
: 几何矩中的m00
,即零阶矩(面积)。
- 结果: 计算出质心的x坐标
cX
。
5、计算掩膜物体的面积
# 计算掩膜中物体的面积 这可以通过计算掩膜中非零像素的数量来实现
area = cv2.contourArea(contours[0]) if contours else 0
print(f"Area of the object: {area}")
area = cv2.contourArea(contours[0]) if contours else 0
- 功能: 使用
cv2.contourArea
函数计算轮廓的面积。 - 参数:
contours[0]
: 使用第一个(最大)轮廓。
- 结果: 返回轮廓的面积。
6、主函数
# 使用cv2.imshow函数显示掩码图像,窗口标题为'mask'。
cv2.imshow('mask',mask)
# 使用cv2.imshow函数显示原始图像(经过缩放和色彩空间转换后),窗口标题为'image'。
cv2.imshow('image', img)
while(1):
#等待用户按键,按下‘q’就释放资源退出程序
key=cv2.waitKey(1)
if key&0XFF==ord('q'):
break
cv2.destroyAllWindows()
三、运行结果
四、完整代码
# 这行指定了文件的编码格式为utf-8
# coding=utf-8
import cv2
import numpy as np
# 使用cv2.imread函数读取指定路径下的图片文件。第二个参数1表示读取彩色图像(BGR格式)
img = cv2.imread('/home/raspberry4B/Pictures/MD.jpg', 1)
# 使用cv2.resize函数调整图像大小。这里,目标宽度和高度被设置为(0,0),表示将按照给定的缩放因子fx和fy来缩放图像。
# fx=0.2和fy=0.2表示图像在水平和垂直方向上都将缩小到原来的20%。
#img = cv2.resize(img, (0,0), fx=0.2, fy=0.2)
# 将图像从BGR色彩空间转换为HSV色彩空间。HSV色彩空间更适用于颜色范围检测,因为它基于色调(H)、饱和度(S)和亮度(V)。
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# 定义一个NumPy数组,表示HSV色彩空间中颜色的下界。这里的数值代表色调、饱和度和亮度的最小值。
lower_range = np.array([101, 100, 100], dtype=np.uint8)
# 定义一个NumPy数组,表示HSV色彩空间中颜色的上界。这里的数值代表色调、饱和度和亮度的最大值。
upper_range = np.array([121, 255, 255], dtype=np.uint8)
# 使用cv2.inRange函数根据指定的HSV颜色范围创建一个掩码图像。该掩码图像中,属于指定颜色范围的像素值为255(白色),其他像素值为0(黑色)。
mask = cv2.inRange(hsv, lower_range, upper_range)
# 计算掩膜覆盖的像素
num_pixels = np.sum(mask == 255) # 或者 np.count_nonzero(mask)
print(f"Number of pixels in the mask: {num_pixels}")
# 使用OpenCV的findContours函数找到轮廓 通过寻找掩膜中所有非零像素的边界,您可以得到这些像素在图像中的位置。
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 假设我们只关心最大的轮廓(即最大的物体)
if contours:
c = max(contours, key=cv2.contourArea)
x, y, w, h = cv2.boundingRect(c)
print(f"Bounding box of the object: ({x}, {y}), ({w}, {h})")
# 计算掩膜中物体的质心 质心是物体所有像素的加权平均位置
M = cv2.moments(contours[0]) if contours else None
if M != None:
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
print(f"Centroid of the object: ({cX}, {cY})")
# 计算掩膜中物体的面积 这可以通过计算掩膜中非零像素的数量来实现
area = cv2.contourArea(contours[0]) if contours else 0
print(f"Area of the object: {area}")
# 使用cv2.imshow函数显示掩码图像,窗口标题为'mask'。
cv2.imshow('mask',mask)
# 使用cv2.imshow函数显示原始图像(经过缩放和色彩空间转换后),窗口标题为'image'。
cv2.imshow('image', img)
while(1):
#等待用户按键,按下‘q’就释放资源退出程序
key=cv2.waitKey(1)
if key&0XFF==ord('q'):
break
cv2.destroyAllWindows()
五、完整代码贴出
持续更新中……