任务要求🍉
1. 计算图像中夹子的总数。
2. 分别计算不同颜色夹子的个数。
3. 使用以下方法适应三张图片,并在每张图像上显示结果:
- 阈值方法
- HSV颜色空间
- 连通域分析
- 形态学图像处理
- Canny边缘检测
4. 在结果中显示计数后的数字,包括总数和每种颜色的个数。
请学生根据任务要求,编写代码实现夹子计数和颜色分类的功能。学生可以选择使用 Python 和 OpenCV 库来完成任务。他们需要适应三张提供的图像,并在每张图像上显示计数结果。建议学生使用阈值处理、HSV颜色空间转换、连通域分析、形态学图像处理和Canny边缘检测等方法来实现任务要求。
参考🍉
代码:
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 读取图像
img = cv2.imread('test2.jpg')
# 将图像转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 阈值处理
_, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
# 将图像转换为HSV颜色空间
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# 定义颜色范围 绿
lower_green = np.array([60, 50, 50])
upper_green = np.array([100, 255, 255])
# 定义颜色范围 蓝
lower_blue = np.array([90, 50, 50])
upper_blue = np.array([130, 255, 255])
# 定义颜色范围 红
lower_red1 = np.array([0, 50, 50])
upper_red1 = np.array([10, 255, 255])
# 定义颜色范围 红
lower_red2 = np.array([170, 50, 50])
upper_red2 = np.array([180, 255, 255])
# 定义颜色范围 黄
lower_yellow = np.array([20, 50, 50])
upper_yellow = np.array([40, 255, 255])
# 创建掩模
mask_green = cv2.inRange(hsv, lower_green, upper_green)
mask_blue = cv2.inRange(hsv, lower_blue, upper_blue)
mask_red1 = cv2.inRange(hsv, lower_red1, upper_red1)
mask_red2 = cv2.inRange(hsv, lower_red2, upper_red2)
mask_red = cv2.bitwise_or(mask_red1, mask_red2)
mask_yellow = cv2.inRange(hsv, lower_yellow, upper_yellow)
# 分割出绿色、蓝色、红色和黄色区域
green_segmented = cv2.bitwise_and(img, img, mask=mask_green)
blue_segmented = cv2.bitwise_and(img, img, mask=mask_blue)
red_segmented = cv2.bitwise_and(img, img, mask=mask_red)
yellow_segmented = cv2.bitwise_and(img, img, mask=mask_yellow)
# 统计连通域数量和面积
_, green_labels, green_stats, _ = cv2.connectedComponentsWithStats(mask_green, connectivity=8)
_, blue_labels, blue_stats, _ = cv2.connectedComponentsWithStats(mask_blue, connectivity=8)
_, red_labels, red_stats, _ = cv2.connectedComponentsWithStats(mask_red, connectivity=8)
_, yellow_labels, yellow_stats, _ = cv2.connectedComponentsWithStats(mask_yellow, connectivity=8)
# 定义像素数量阈值
threshold = 2000
# 筛选出像素数量达到阈值的连通域
green_filtered_labels = [label for label, area in enumerate(green_stats[:, cv2.CC_STAT_AREA]) if area >= threshold]
blue_filtered_labels = [label for label, area in enumerate(blue_stats[:, cv2.CC_STAT_AREA]) if area >= threshold]
red_filtered_labels = [label for label, area in enumerate(red_stats[:, cv2.CC_STAT_AREA]) if area >= threshold]
yellow_filtered_labels = [label for label, area in enumerate(yellow_stats[:, cv2.CC_STAT_AREA]) if area >= threshold]
# 绘制筛选后的连通域边界框
for label in green_filtered_labels:
x, y, w, h = green_stats[label, cv2.CC_STAT_LEFT], green_stats[label, cv2.CC_STAT_TOP], green_stats[label, cv2.CC_STAT_WIDTH], green_stats[label, cv2.CC_STAT_HEIGHT]
cv2.rectangle(green_segmented, (x, y), (x + w, y + h), (0, 255, 0), 2)
for label in blue_filtered_labels:
x, y, w, h = blue_stats[label, cv2.CC_STAT_LEFT], blue_stats[label, cv2.CC_STAT_TOP], blue_stats[label, cv2.CC_STAT_WIDTH], blue_stats[label, cv2.CC_STAT_HEIGHT]
cv2.rectangle(blue_segmented, (x, y), (x + w, y + h), (0, 0, 255), 2)
for label in red_filtered_labels:
x, y, w, h = red_stats[label, cv2.CC_STAT_LEFT], red_stats[label, cv2.CC_STAT_TOP], red_stats[label, cv2.CC_STAT_WIDTH], red_stats[label, cv2.CC_STAT_HEIGHT]
cv2.rectangle(red_segmented, (x, y), (x + w, y + h), (255, 0, 0), 2)
for label in yellow_filtered_labels:
x, y, w, h = yellow_stats[label, cv2.CC_STAT_LEFT], yellow_stats[label, cv2.CC_STAT_TOP], yellow_stats[label, cv2.CC_STAT_WIDTH], yellow_stats[label, cv2.CC_STAT_HEIGHT]
cv2.rectangle(yellow_segmented, (x, y), (x + w, y + h), (0, 255, 255), 2)
# print(len(g), len(b),len(r),len(y))
# 显示结果
fig, axs = plt.subplots(3, 2, figsize=(10, 10))
axs[0, 0].imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
axs[0, 0].set_title('Original Image')
axs[0, 1].imshow(thresh, cmap='gray')
axs[0, 1].set_title('Threshold Image')
axs[1, 0].imshow(cv2.cvtColor(green_segmented, cv2.COLOR_BGR2RGB))
axs[1, 0].set_title(f'Green Segmented ({len(green_filtered_labels)-1} regions)')
axs[1, 1].imshow(cv2.cvtColor(blue_segmented, cv2.COLOR_BGR2RGB))
axs[1, 1].set_title(f'Blue Segmented ({len(blue_filtered_labels)-1} regions)')
axs[2, 0].imshow(cv2.cvtColor(red_segmented, cv2.COLOR_BGR2RGB))
axs[2, 0].set_title(f'Red Segmented ({len(red_filtered_labels)-1} regions)')
axs[2, 1].imshow(cv2.cvtColor(yellow_segmented, cv2.COLOR_BGR2RGB))
axs[2, 1].set_title(f'Yellow Segmented ({len(yellow_filtered_labels)-1} regions)')
plt.tight_layout()
plt.show()