传统图像处理Opencv分割不同颜色的夹子

任务要求🍉


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()

运行结果:  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大气层煮月亮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值