图像处理:如何实现堆叠皮革图像中的皮革数量精准统计
堆叠皮革计数鲁棒性方案
原方案问题分析
你当前使用的固定阈值二值化方法存在明显局限性:
- 固定的灰度范围
50-90无法适配不同光照、不同皮革颜色的输入图像,容易出现缝隙漏检或者背景误检 - 仅完成了初步二值化分割,没有配套的计数逻辑,无法直接输出层数结果
改进方案(基于垂直灰度投影法)
该方案利用堆叠皮革水平分层的特征,通过统计垂直方向的灰度突变计数层数,对光照、颜色波动的鲁棒性远高于固定阈值法。
实现代码
import cv2 import numpy as np def count_leather_layers(image_path): # 1. 读取图像并预处理 im = cv2.imread(image_path) # 裁剪感兴趣区域(可根据实际拍摄视角调整,排除无关背景干扰) h, w = im.shape[:2] roi = im[int(h*0.1):int(h*0.9), int(w*0.2):int(w*0.8)] # 转灰度 gray = cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY) # 自适应阈值二值化,适配局部光照变化 thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 15, 3) # 形态学闭运算,连接断裂的缝隙线条 kernel = np.ones((3,3), np.uint8) closed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=1) # 2. 计算垂直方向灰度投影 vertical_proj = np.sum(closed, axis=1) # 平滑投影曲线,减少噪声干扰 smoothed_proj = cv2.GaussianBlur(vertical_proj.reshape(-1,1), (1,15), 0).flatten() # 3. 检测投影曲线的峰值,每个峰值对应一层皮革的缝隙 peaks = [] threshold = np.max(smoothed_proj) * 0.2 # 峰值阈值,可根据实际情况微调 for i in range(1, len(smoothed_proj)-1): if smoothed_proj[i] > smoothed_proj[i-1] and smoothed_proj[i] > smoothed_proj[i+1] and smoothed_proj[i] > threshold: peaks.append(i) # 去重:合并相邻过近的峰值 filtered_peaks = [] min_distance = h * 0.03 # 最小层间距,按需调整 last_p = -min_distance for p in peaks: if p - last_p > min_distance: filtered_peaks.append(p) last_p = p # 层数 = 峰值数 + 1 layer_count = len(filtered_peaks) + 1 return layer_count # 测试 if __name__ == "__main__": count = count_leather_layers("替换为你的图像路径") print(f"检测到的皮革层数为:{count}")
优化建议
- 如果拍摄的堆叠皮革存在倾斜,可先通过霍夫直线检测计算倾斜角度,做仿射变换矫正为水平后再做投影计数,准确率会进一步提升
- 如果场景固定,可提前标定感兴趣区域,排除背景、周边杂物的干扰,进一步降低误检概率
内容的提问来源于stack exchange,提问作者IBHa
相关产品推荐
相关产品推荐

