如何测量图像中白色物体在指定标线处的宽高?代码优化求助
问题解决:测量白色物体在中线处的宽度与高度
你当前代码打印的w和h是裁剪后图像的边界框尺寸,而非白色物体在中线位置的实际接触尺寸。以下是修复后的完整代码及关键修改说明:
修复后代码
import cv2 import numpy as np # 读取灰度图像 mask_ref = cv2.imread("/original_image.jpg", 0) hh, ww = mask_ref.shape[:2] # 获取图像中最大的外轮廓 contours = cv2.findContours(mask_ref, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) contours = contours[0] if len(contours) == 2 else contours[1] big_contour = max(contours, key=cv2.contourArea) # 补全原代码缺失的最小外接矩形计算(关键:获取旋转所需的角度、中心等参数) rect = cv2.minAreaRect(big_contour) center, (width, height), angle = rect # 旋转角度校正逻辑(保留原逻辑) if angle < -45 and width > height: angle = -(90 + angle) else: if angle > -45 and width > height: angle = -(-90 + angle) else: angle = -angle neg_angle = -angle # 生成旋转矩阵并校正图像 M = cv2.getRotationMatrix2D(center, neg_angle, scale=1.0) rectified = cv2.warpAffine(mask_ref, M, (ww, hh), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE) # 重新二值化确保图像为黑白两色 rectified = cv2.threshold(rectified, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1] # 获取校正后物体的边界框并裁剪 cntrs = cv2.findContours(rectified, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cntrs = cntrs[0] if len(cntrs) == 2 else cntrs[1] cntr = cntrs[0] x,y,w_crop,h_crop = cv2.boundingRect(cntr) crop = rectified[y:y+h_crop, x:x+w_crop] # 计算每行/每列的白色像素数量(对应物体在该行/列的尺寸) row_white_counts = np.count_nonzero(crop, axis=1) # 每行白色像素数=该行物体宽度 col_white_counts = np.count_nonzero(crop, axis=0) # 每列白色像素数=该列物体高度 # 确定中线位置 horizontal_mid_y = h_crop // 2 vertical_mid_x = w_crop // 2 # 获取中线处的目标尺寸 target_width = row_white_counts[horizontal_mid_y] target_height = col_white_counts[vertical_mid_x] # 绘制中线(修正原代码的线条起点/终点,确保覆盖整个图像) line_thickness = 2 cv2.line(crop, (0, horizontal_mid_y), (w_crop, horizontal_mid_y), (0, 0, 0), thickness=line_thickness) cv2.line(crop, (vertical_mid_x, 0), (vertical_mid_x, h_crop), (0, 0, 0), thickness=line_thickness) # 打印目标尺寸(替换原有的裁剪框尺寸输出) print(f"水平中线处白色物体宽度: {target_width}") print(f"垂直中线处白色物体高度: {target_height}") # 可选:显示处理后的图像 # cv2.imshow("Cropped with Midlines", crop) # cv2.waitKey(0) # cv2.destroyAllWindows()
关键修改点
- 补全缺失的外接矩形参数:原代码缺少
cv2.minAreaRect()调用,导致angle、center等变量未定义,这是代码运行的前提。 - 分离裁剪框与目标尺寸:将代表裁剪图像大小的变量重命名为
w_crop、h_crop,避免和物体在中线处的目标尺寸混淆。 - 计算中线处的实际尺寸:
- 利用
np.count_nonzero()统计每行/每列的白色像素数量,直接对应物体在该行/列的宽度/高度。 - 取中线位置的统计值,即为你需要的目标尺寸。
- 利用
- 修正中线绘制逻辑:原代码水平中线的起点错误,改为从图像左端到右端绘制,确保线条完整显示。
内容的提问来源于stack exchange,提问作者Curious G.
相关产品推荐
相关产品推荐

