OpenCV实现类圆形液体区域自动分割及裁剪保存技术求助
解决方案:基于颜色阈值的类圆形区域分割
一、核心思路
放弃灰度图的边缘检测/正圆检测方案,改用HSV颜色空间阈值分割精准提取红/黄色目标,再通过轮廓筛选保留类圆形区域,最后实现单个区域的分割与独立保存。
二、分步实现代码与解释
1. 导入依赖库
import cv2 import numpy as np
2. 颜色阈值分割(去除白色背景)
白色背景在HSV空间的特征是低饱和度(S)+ 高亮度(V),红/黄色则有明确的色调(H)范围。通过HSV阈值生成目标区域掩码,直接过滤白色背景:
# 读取图像 img = cv2.imread('red.jpg') hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # 定义红/黄色的HSV阈值(根据实际图像微调) # 红色在HSV中跨0和180两个区间 lower_red1 = np.array([0, 40, 40]) upper_red1 = np.array([10, 255, 255]) lower_red2 = np.array([170, 40, 40]) upper_red2 = np.array([180, 255, 255]) # 黄色区间 lower_yellow = np.array([20, 40, 40]) upper_yellow = np.array([30, 255, 255]) # 合并红/黄色掩码 mask_red = cv2.bitwise_or(cv2.inRange(hsv, lower_red1, upper_red1), cv2.inRange(hsv, lower_red2, upper_red2)) mask_yellow = cv2.inRange(hsv, lower_yellow, upper_yellow) mask_target = cv2.bitwise_or(mask_red, mask_yellow) # 形态学操作去除噪点、填补空洞(核大小根据图像调整) kernel = np.ones((5,5), np.uint8) mask_target = cv2.morphologyEx(mask_target, cv2.MORPH_CLOSE, kernel) mask_target = cv2.morphologyEx(mask_target, cv2.MORPH_OPEN, kernel)
3. 轮廓筛选(保留类圆形区域)
通过面积和圆度筛选目标,排除背景噪点和非类圆形区域:
# 查找最外层轮廓 contours, _ = cv2.findContours(mask_target, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) valid_contours = [] for cnt in contours: # 过滤过小的噪点轮廓(面积阈值根据目标大小调整) area = cv2.contourArea(cnt) if area < 1000: continue # 计算圆度:圆度=4π*面积/(周长²),值越接近1越接近圆形 perimeter = cv2.arcLength(cnt, True) if perimeter == 0: continue circularity = 4 * np.pi * (area / (perimeter ** 2)) # 类圆形阈值,变形越大可适当降低(如0.5) if circularity > 0.7: valid_contours.append(cnt) # 可视化验证筛选结果 img_contour = img.copy() cv2.drawContours(img_contour, valid_contours, -1, (0,255,0), 3) cv2.imshow('Valid Contours', img_contour) cv2.waitKey(0) cv2.destroyAllWindows()
4. 分割单个区域并保存
为每个有效轮廓生成独立掩码,提取目标区域并裁剪保存:
# 遍历每个有效轮廓,分割保存 for idx, cnt in enumerate(valid_contours): # 创建仅包含当前轮廓的掩码 roi_mask = np.zeros_like(mask_target) cv2.drawContours(roi_mask, [cnt], -1, 255, -1) # 提取带颜色的目标区域 roi = cv2.bitwise_and(img, img, mask=roi_mask) # 裁剪出最小外接矩形区域(去除多余空白) x, y, w, h = cv2.boundingRect(cnt) roi_cropped = roi[y:y+h, x:x+w] # 保存文件 cv2.imwrite(f'target_{idx+1}.jpg', roi_cropped) print(f'已保存:target_{idx+1}.jpg')
三、关键细节说明
- HSV阈值调整:若目标与背景区分度不足,可使用
cv2.createTrackbar实时调整HSV参数,找到最优阈值。 - 圆度阈值:根据类圆形的变形程度调整,0.7适合轻微变形的目标,变形较大时可降至0.5左右。
- 之前代码的问题修正:
- findContours用灰度图丢失颜色信息,导致边缘检测受背景干扰;
- HoughCircles代码中
cv2.cvtColor(experiment, cv2.COLOR_GRAY2BGR)是错误转换,应为COLOR_BGR2GRAY,且该方法仅支持正圆,无法适配类圆形结构。
内容的提问来源于stack exchange,提问作者John C Lau
相关产品推荐
相关产品推荐

