You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于OpenCV实现精准蚕卵计数?现有方法存缺陷

精准蚕卵计数的优化方案

针对你遇到的蚕卵计数难题——尤其是小尺寸、重叠椭圆/圆形卵的情况,我有几个针对性的优化方向,比单纯的轮廓检测鲁棒性更强:

一、优化距离变换+非极大值抑制(NMS)

你最初用的距离变换思路其实很适合处理圆形/椭圆目标,但参数调整和峰值过滤环节可以优化,尤其是针对小目标和重叠场景:

import cv2
import numpy as np

im = cv2.imread('eggs1.png')
gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
# 预处理:高斯模糊去噪,适配小目标
blurred = cv2.GaussianBlur(gray, (3, 3), 0)
# 自适应阈值,应对光照不均的情况
bw = cv2.adaptiveThreshold(blurred, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2)
# 形态学闭运算填补小缝隙,缩小核适配小卵
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (2, 2))
morph = cv2.morphologyEx(bw, cv2.MORPH_CLOSE, kernel)

# 距离变换提取目标中心
dist = cv2.distanceTransform(morph, cv2.DIST_L2, cv2.DIST_MASK_PRECISE)
# 非极大值抑制过滤重复峰值
local_max = cv2.dilate(dist, np.ones((3, 3), np.uint8))
peaks = np.where(dist == local_max, dist, 0)
# 阈值筛选有效峰值(降低阈值捕捉小卵)
peak_thresh = np.max(dist) * 0.3
peaks[peaks < peak_thresh] = 0

# 标记并计数峰值
peak_coords = np.argwhere(peaks > 0)
count = 0
for y, x in peak_coords:
    # 避免邻近峰值重复计数
    if cv2.contourArea(cv2.findContours((dist[y-2:y+2, x-2:x+2] > peak_thresh).astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0]) > 0:
        cv2.circle(im, (x, y), int(dist[y, x]), (255, 0, 0), 1)
        count += 1

print(f"计数结果:{count}")
cv2.imshow('Counted Eggs', im)
cv2.waitKey(0)
cv2.destroyAllWindows()

这个方案通过自适应阈值解决光照不均问题,缩小形态学核适配小卵,再用非极大值抑制过滤重叠区域的重复峰值,比原版本更精准。

二、分水岭算法分割重叠卵

如果你的图像中卵重叠非常严重,分水岭算法能有效分割粘连的目标:

import cv2
import numpy as np

im = cv2.imread('eggs_overlap.png')
gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
# 预处理去噪
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
thresh = cv2.threshold(blurred, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

# 确定背景:膨胀操作确保完全覆盖背景区域
kernel = np.ones((3, 3), np.uint8)
sure_bg = cv2.dilate(thresh, kernel, iterations=3)

# 确定前景:距离变换+阈值筛选目标中心
dist_transform = cv2.distanceTransform(thresh, cv2.DIST_L2, 5)
ret, sure_fg = cv2.threshold(dist_transform, 0.2 * dist_transform.max(), 255, 0)
sure_fg = np.uint8(sure_fg)

# 找到未知区域(卵的粘连部分)
unknown = cv2.subtract(sure_bg, sure_fg)

# 标记连通区域
ret, markers = cv2.connectedComponents(sure_fg)
# 给标记加1,避免背景被标记为0
markers = markers + 1
# 未知区域标记为0
markers[unknown == 255] = 0

# 应用分水岭算法分割
markers = cv2.watershed(im, markers)
im[markers == -1] = [255, 0, 0]  # 分割线标记为红色

# 计数:统计标记数量(减去背景和未知区域)
count = len(np.unique(markers)) - 2
print(f"计数结果:{count}")

cv2.imshow('Watershed Result', im)
cv2.waitKey(0)
cv2.destroyAllWindows()

分水岭的核心是区分确定前景、确定背景和未知区域,能把粘连的卵精准分开,适合重叠严重的场景。

三、轻量目标检测模型(适合批量复杂图像)

如果你的数据集有一定数量的标注图,用YOLOv8这类轻量模型会是长期最优解,它对小目标、重叠目标的检测精度远高于传统方法:

首先安装依赖:pip install ultralytics

然后编写代码:

from ultralytics import YOLO

# 加载预训练模型(可自行标注数据微调)
model = YOLO('yolov8n.pt')  # yolov8n是最小模型,适配小目标检测
# 若有标注数据,训练命令:model.train(data='eggs.yaml', epochs=50, imgsz=640)

# 预测并计数
results = model('eggs_test.png')
count = len(results[0].boxes)
print(f"计数结果:{count}")

# 可视化检测结果
results[0].show()

只需要用LabelImg工具标注几十张蚕卵图像,训练后模型就能精准识别各种复杂场景下的蚕卵,包括小尺寸、重叠的情况。

通用预处理技巧

不管用哪种方法,以下步骤能进一步提升效果:

  • 高斯模糊:去除图像噪声,避免误检测小噪点
  • 自适应阈值:代替OTSU阈值,应对光照不均匀的图像
  • 尺寸归一化:把图像缩放到固定尺寸,确保参数适配所有图像

内容的提问来源于stack exchange,提问作者Levi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:32:12