基于OpenCV 3.4.0与Python 3检测畸变图像中正方形右侧边
针对畸变图像中正方形清晰右侧边的检测方案
我明白你要抓的是那个始终清晰的右侧边,其他畸变的边完全可以忽略——之前用霍夫直线变换可能会抓到多余线条,咱们可以针对性优化流程,精准定位目标边:
第一步:预处理图像,突出清晰边缘特征
因为目标是黑色正方形的右侧边,先做灰度转换,再用Canny边缘检测,重点调整阈值只保留高对比度的清晰边缘(毕竟其他边是畸变模糊的,对比度会低很多):
import cv2 import numpy as np # 读取图像 temp = cv2.imread("images/macro/noF3.jpg") grTemp = cv2.cvtColor(temp, cv2.COLOR_BGR2GRAY) # Canny边缘检测,阈值可以根据你的实际图像微调 edges = cv2.Canny(grTemp, threshold1=50, threshold2=150)
第二步:限制检测范围,只关注右侧区域
既然右侧边始终清晰,咱们直接把检测范围锁定在图像右侧区域,避免其他畸变边干扰霍夫变换的结果:
height, width = grTemp.shape # 创建掩码,只保留右侧1/5的区域(比例可以根据正方形位置调整) mask = np.zeros_like(edges) mask[:, int(width*0.8):width] = 255 masked_edges = cv2.bitwise_and(edges, mask)
第三步:优化霍夫变换参数,筛选垂直边
正方形的右侧边接近垂直,咱们用概率霍夫变换,设置参数只抓符合长度、角度特征的线条:
# 概率霍夫变换,针对性设置参数 lines = cv2.HoughLinesP( masked_edges, rho=1, theta=np.pi/180, threshold=20, minLineLength=height*0.6, # 最小长度设为图像高度的60%,过滤短杂线 maxLineGap=5 ) # 筛选接近垂直的线条(x坐标变化极小,说明是竖线) target_edge = None if lines is not None: for line in lines: x1, y1, x2, y2 = line[0] if abs(x2 - x1) < 10: # 把ROI的偏移量加回去,还原到原图坐标 x1 += int(width*0.8) x2 += int(width*0.8) target_edge = (x1, y1, x2, y2) break # 把检测到的边画到原图上验证 if target_edge: cv2.line(temp, (target_edge[0], target_edge[1]), (target_edge[2], target_edge[3]), (0, 255, 0), 2) cv2.imshow("Detected Right Edge", temp) cv2.waitKey(0) cv2.destroyAllWindows()
备选方案:用轮廓检测直接定位
如果霍夫变换还是有干扰,试试二值化+轮廓检测,利用黑色正方形与背景的高对比度直接找边界:
# 二值化反转,把黑色正方形变成白色区域 _, binary = cv2.threshold(grTemp, 127, 255, cv2.THRESH_BINARY_INV) contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 遍历轮廓,找到正方形的右边缘 for cnt in contours: x, y, w, h = cv2.boundingRect(cnt) # 边界框的右边缘就是目标边 cv2.line(temp, (x+w, y), (x+w, y+h), (0, 0, 255), 2) cv2.imshow("Detected Edge via Contour", temp) cv2.waitKey(0) cv2.destroyAllWindows()
你可以根据自己图像的实际情况调整ROI比例、阈值这些参数,应该能精准抓到那个清晰的右侧边~
内容的提问来源于stack exchange,提问作者Facosenpai
相关产品推荐
相关产品推荐

