基于OpenCV C++的二值化图像垂直像素距离测量方法求助
OpenCV实现带宽度设置的垂直像素距离测量(多样本采集)
核心思路
和ImageJ里的测量逻辑一致:在图像宽度方向选N个采样点,每个采样点对应一段横向宽度的垂直条带,检测条带内上下边缘的y坐标差,就是你要的垂直像素距离。
具体实现步骤(Python版)
假设你处理的是灰度图(彩色图先转灰度):
- 设置基础参数
先定义采样点数量、测量宽度(红线两端的横向范围),还有可选的预处理参数:
import cv2 import numpy as np img = cv2.imread("your_image.png", 0) # 0表示读为灰度图 sample_count = 5 # 宽度方向采集5个样本 measure_width = 10 # 测量宽度,对应红线两端的横向像素数
- 生成采样位置
均匀分布在图像宽度上,避免边缘:
img_width = img.shape[1] # 计算每个采样点的x坐标,避开左右各measure_width/2的边缘 sample_xs = np.linspace(measure_width//2, img_width - measure_width//2, sample_count, dtype=int)
- 逐个采样并计算垂直距离
对每个采样点,取横向宽度为measure_width的垂直条带,通过垂直投影找边缘(适合高对比度图像,比Canny更简单):
distances = [] for x in sample_xs: # 提取当前采样点的垂直条带(x-measure_width//2 到 x+measure_width//2) strip = img[:, x - measure_width//2 : x + measure_width//2] # 垂直方向求和,得到每一行的总亮度(如果是暗背景亮边缘,就取最小值位置) vertical_proj = np.sum(strip, axis=1) # 找上下边缘:这里假设边缘是亮度突变点,比如从暗到亮再到暗 threshold = np.mean(vertical_proj) * 1.2 # 可根据实际图像调整 upper_y = np.argmax(vertical_proj > threshold) lower_y = len(vertical_proj) - np.argmax(np.flip(vertical_proj) > threshold) - 1 # 计算距离 distance = lower_y - upper_y distances.append(distance) # 可选:在原图上画出测量线 cv2.line(img, (x, upper_y), (x, lower_y), 255, 1)
- 输出结果
打印每个采样点的距离,或者计算平均值:
print("各采样点垂直距离:", distances) print("平均距离:", np.mean(distances)) cv2.imwrite("measured_image.png", img)
优化建议
- 如果图像噪点多,先做高斯模糊:
img = cv2.GaussianBlur(img, (3,3), 0) - 边缘检测也可以用Canny:对条带做Canny后,找y方向的非零像素极值,逻辑类似
- 采样点可以自定义位置,比如手动选几个关键x坐标,不用均匀分布
内容的提问来源于stack exchange,提问作者b1063n
相关产品推荐
相关产品推荐

