图像液滴计数技术求助:OpenCV检测误判间隙及复杂图像处理
液滴计数优化方案
问题分析
当前代码仅通过面积过滤区域,误将液滴间的间隙识别为目标,核心原因是二值图前景/背景可能反转,且缺乏形状特征维度的过滤,仅靠面积无法区分液滴与间隙的形态差异。
优化步骤
1. 修正二值化前景/背景
先确认液滴在二值图中的表现:若间隙被识别为白色前景,说明二值化颠倒了目标与背景,需反转图像让液滴成为白色前景:
import cv2 import numpy as np from skimage.measure import label, regionprops import matplotlib.pyplot as plt # 反转二值图,确保液滴为白色前景 img_morph = cv2.bitwise_not(img_morph)
2. 形态学操作预处理
用形态学操作消除噪声、填补液滴内部空洞,同时清除间隙中的小干扰点:
# 定义匹配液滴尺寸的椭圆结构元素 kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5)) # 闭运算:填补液滴内部小空洞 img_closed = cv2.morphologyEx(img_morph, cv2.MORPH_CLOSE, kernel) # 开运算:去除画面中的小噪声点 img_processed = cv2.morphologyEx(img_closed, cv2.MORPH_OPEN, kernel)
3. 多特征精准过滤区域
除面积外,加入形状特征过滤,精准识别液滴形态:
rbc_bw = label(img_processed) rbc_props = regionprops(rbc_bw) fig, ax = plt.subplots(figsize=(18, 8)) ax.imshow(img_processed, cmap='gray') rbc_count = 0 for prop in rbc_props: # 面积过滤:根据实际液滴尺寸调整阈值范围 if prop.area < 200 or prop.area > 2000: continue # 圆形度过滤:液滴接近圆形,过滤圆形度偏低的细长间隙 perimeter = prop.perimeter if perimeter == 0: continue circularity = 4 * np.pi * prop.area / (perimeter ** 2) if circularity < 0.5: continue # 宽高比过滤:液滴宽高比接近1,排除扁长/窄细的间隙 aspect_ratio = prop.major_axis_length / prop.minor_axis_length if aspect_ratio > 1.5 or aspect_ratio < 0.67: continue # 实心度过滤:液滴实心度高,排除空心/不规则的间隙区域 solidity = prop.area / prop.convex_area if solidity < 0.7: continue # 绘制识别框 y1, x1, y2, x2 = prop.bbox width = x2 - x1 height = y2 - y1 r = plt.Rectangle((x1, y1), width=width, height=height, color='b', fill=False) ax.add_patch(r) rbc_count += 1 print('液滴计数:', rbc_count) plt.show()
4. 复杂光照图像的额外优化
针对光照不均的高难度图像,替换固定阈值为自适应阈值,提升背景与液滴的区分度:
# 读取原始彩色图并转为灰度图 img_gray = cv2.cvtColor(original_img, cv2.COLOR_BGR2GRAY) # 自适应阈值处理,适配局部光照差异 img_morph = cv2.adaptiveThreshold(img_gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2)
关键说明
- 所有特征阈值(面积、圆形度等)需根据实际液滴的尺寸、形态调整,建议先统计正常液滴的特征范围再设定。
- 形态学操作的结构元素大小,需匹配液滴最小尺寸,避免过度腐蚀/膨胀破坏液滴形态。
内容的提问来源于stack exchange,提问作者Juju
相关产品推荐
相关产品推荐

