如何利用OpenCV获取钢材灰度图像的头尾裁剪点?
钢材灰度图像头尾裁剪点定位优化方案
问题背景
需要对存在灰度分布不均问题的钢材灰度图像进行头部/尾部裁剪,当前通过cv2.adaptiveThreshold提取轮廓,再用以下代码拟合轮廓:
epsilon = 0.0005 * cv2.arcLength(contour, True) approx = cv2.approxPolyDP(contour, epsilon, True)
随后基于斜率筛选拟合点,但效果不理想,目标是定位图像左右两侧的特征裁剪点。
原始图像说明:钢材灰度图,存在灰度不均现象,边缘区域模糊
目标裁剪点说明:图像左右两侧的两个特征点,用于确定头尾裁剪边界
改进步骤
1. 预处理:消除灰度不均影响
先通过CLAHE(限制对比度自适应直方图均衡化)处理图像,强化边缘对比度,解决灰度分布不均问题:
import cv2 import numpy as np # 读取灰度图像 gray_img = cv2.imread("steel_img.jpg", cv2.IMREAD_GRAYSCALE) # 应用CLAHE clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8)) equalized_img = clahe.apply(gray_img)
2. 轮廓提取与筛选:聚焦主体
提取轮廓后,通过面积筛选排除噪声,只保留钢材主体的轮廓:
# 自适应阈值二值化 thresh = cv2.adaptiveThreshold(equalized_img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2) # 提取外部轮廓 contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 按面积降序排序,取面积最大的轮廓(对应钢材主体) main_contour = sorted(contours, key=cv2.contourArea, reverse=True)[0]
3. 裁剪点定位:替代斜率筛选
方法一:最小外接矩形法
通过最小外接矩形直接获取边界点,适配钢材的任意摆放角度:
# 计算最小外接矩形 rect = cv2.minAreaRect(main_contour) box = cv2.boxPoints(rect) box = np.int0(box) # 提取x坐标最小(左点)和最大(右点)的点 left_point = min(box, key=lambda p: p[0]) right_point = max(box, key=lambda p: p[0])
方法二:边缘直线拟合
如果钢材边缘近似直线,对轮廓点做直线拟合后取端点:
# 提取轮廓的x、y坐标数组 x_coords = main_contour[:, 0, 0] y_coords = main_contour[:, 0, 1] # 一阶多项式拟合直线 fit = np.polyfit(x_coords, y_coords, 1) line_func = np.poly1d(fit) # 取x极值对应的点作为裁剪点 left_point = (x_coords.min(), int(line_func(x_coords.min()))) right_point = (x_coords.max(), int(line_func(x_coords.max())))
4. 后处理:优化点的稳定性
对多帧图像或同一图像的多行轮廓点取均值,或通过长宽比验证点的合理性,避免噪声干扰。
内容的提问来源于stack exchange,提问作者Mumu
相关产品推荐
相关产品推荐

