本项目是一个基于传统图像处理算法(OpenCV)的柚子表皮缺陷检测demo,适用于工业流水线上对柚子(其他水果思路相同)的表面黑斑、腐烂等缺陷进行自动检测与好/坏果判定。
算法原理
由于大部分水果腐烂后缺陷区域呈现黑色,而正常果皮颜色与黑色在**饱和度(Saturation)**上有明显差异,因此整体检测流程如下:
RGB → HSI 颜色空间转换
- 自定义实现 RGB 到 HSI 的转换(见
header.py中rgb2hsi),提取 S(饱和度)通道图像。 - 黑斑区域饱和度显著低于正常果皮,便于分离。
- 自定义实现 RGB 到 HSI 的转换(见
S 通道阈值分割
- 对 S 通道做反二值化阈值分割(
cv2.THRESH_BINARY_INV),提取低饱和度的疑似缺陷区域。 - 阈值可通过窗口中的滑动条(Trackbar)实时调节。
- 对 S 通道做反二值化阈值分割(
提取水果主体 ROI
- 对原图灰度化、二值化后查找轮廓,取**最大面积轮廓的凸包(convexHull)**作为水果主体。
- 用凸包生成掩膜(mask),与阈值分割结果做按位与(
bitwise_and),只保留果皮范围内的缺陷,去除背景干扰。
缺陷占比计算与好坏判定
- 统计 ROI 内黑色(缺陷)像素个数
cont,计算凸包面积hull_area。 - 若
cont / hull_area <= 0.2(即缺陷占比不超过 20%),判定为好果(This is good),否则判定为坏果(This is bad),并将结果文字标注在原图上。
- 统计 ROI 内黑色(缺陷)像素个数
该"缺陷占比阈值 20%"可在
header.py的judge_ifgood中按实际需求调整。
环境要求
- Python 3.x(开发时使用 Python 3,无特殊版本要求)
- OpenCV(
opencv-python) - NumPy
安装步骤
克隆或下载本项目到本地:
从https://download.csdn.net/download/FL1623863129/88616127获取源码cdcode安装依赖:
pipinstallopencv-python numpy
运行步骤
确保待检测图片放在
youzi-picture/文件夹中(默认读取./youzi-picture/Image8.jpg,可在main.py第 6 行修改图片路径)。运行主程序:
python main.py运行后会弹出多个窗口,依次为:
img:原始图像hsi_img:HSI 转换后的 S 通道图像dst_Tri:S 通道阈值分割结果(窗口上带thre滑动条,可调阈值)roi:由最大轮廓凸包生成的 ROI 掩膜draw_img:ROI 内提取出的缺陷区域final_result:最终判定结果(图上标注 “This is good” / “This is bad”)
控制台会输出图像宽高、整体面积、凸包面积、黑色像素个数等信息。按任意键关闭窗口退出。
注意事项
- 图片路径:
main.py中图片路径为硬编码./youzi-picture/Image8.jpg,更换检测图片时需修改该行。 - 阈值调节:S 通道分割阈值默认 150,程序运行前可通过代码中
min_thre调整,运行时滑动条的修改不会重新触发分割(阈值分割只执行一次),如需交互式调节可将处理逻辑放入while循环(代码中已保留注释掉的循环框架)。 - 占比阈值:好/坏果判定阈值默认为缺陷占比 20%,位于
header.py的judge_ifgood方法中,可按行业标准调整。 - 单张检测:当前代码仅支持单张图片检测;接入工业相机时,只需将相机 SDK 采集的帧替换
cv2.imread部分即可。 - 依赖算法假设:本方案基于"缺陷呈黑色、与正常果皮饱和度差异大"的假设,若缺陷颜色与果皮接近,检测效果会下降。
文件夹结构
code/ ├── main.py # 主程序:读取图片、调用检测流程、显示各阶段结果 ├── header.py # Detect 类:封装 RGB→HSI 转换、轮廓查找、凸包提取、 │ # ROI 生成、黑色像素统计、好坏判定等核心算法 ├── README.md # 项目说明文档 ├── youzi-picture/ # 柚子测试图片(Image1.jpg ~ Image23.jpg)