This commit is contained in:
2025-10-01 10:43:55 +08:00
commit f91b09da9d
130 changed files with 1456 additions and 0 deletions

112
OpenCV/detect_weld.py Normal file
View File

@@ -0,0 +1,112 @@
import cv2
import numpy as np
import math
import os
def find_and_mask_weld_seam_v3(image_path):
"""
加载图像,使用更激进的预处理方法检测低对比度直线。
:param image_path: 输入图像的完整路径。
:return: None
"""
# --- 步骤 1: 加载图像 ---
image = cv2.imread(image_path)
if image is None:
print(f"错误: 无法加载图像 '{image_path}'")
return
visualization_image = image.copy()
height, width, _ = image.shape
image_center_x = width / 2
# --- 步骤 2: 图像预处理 (超强版) ---
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 2.1 高斯模糊以去除噪声
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
# 2.2 自适应阈值二值化 (关键步骤!)
# 这个操作对于光照不均、对比度低的区域效果非常好,能强制分离出边缘
# blocksize: 邻域大小,必须是奇数
# C: 从均值或加权均值中减去的常数,用于微调
binary_image = cv2.adaptiveThreshold(
blurred, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY_INV, 21, 5
)
# 使用THRESH_BINARY_INV是因为我们感兴趣的边缘是暗色背景下的亮色线条
# 2.3 形态学操作来清理和连接线条
# 创建一个垂直的结构元素,因为我们的目标是垂直线
kernel = np.ones((15, 1), np.uint8) # 强调垂直方向
# 使用“闭运算”来填充断开的线段中的小洞
closed = cv2.morphologyEx(binary_image, cv2.MORPH_CLOSE, kernel)
# --- 步骤 3: 霍夫直线变换 (直接在处理后的二值图上进行) ---
# Canny不再是必需的因为二值化已经完成了边缘提取
lines = cv2.HoughLinesP(
closed, # 在闭运算结果上检测
rho=1,
theta=np.pi / 180,
threshold=100, # 需要较高的阈值,因为线现在更连续了
minLineLength=int(height * 0.5), # 线至少要有一半图像高度那么长
maxLineGap=50 # 允许较大的间隙
)
# --- 步骤 4: 筛选最佳直线 (逻辑与之前类似) ---
best_line = None
max_length = 0
if lines is not None:
for line in lines:
x1, y1, x2, y2 = line[0]
# 角度过滤,寻找近乎垂直的线
angle = abs(math.degrees(math.atan2(y2 - y1, x2 - x1)))
if abs(angle - 90) < 5: # 检查角度是否在90度左右垂直
length = math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
if length > max_length:
max_length = length
best_line = line[0]
# --- 步骤 5: 处理和显示结果 ---
if best_line is not None:
bx1, by1, bx2, by2 = best_line
print(f"成功找到直线!起点:({bx1}, {by1}), 终点:({bx2}, {by2})")
cv2.line(visualization_image, (bx1, by1), (bx2, by2), (0, 0, 255), 3)
# 显示中间处理结果以供调试
cv2.imshow('1. Original Image', image)
cv2.imshow('2. Adaptive Threshold', binary_image)
cv2.imshow('3. Morphological Closing', closed) # 检查闭运算效果
cv2.imshow('4. Final Detection', visualization_image)
else:
print("未能在图像中找到符合条件的直线。")
cv2.imshow('1. Original Image', image)
cv2.imshow('2. Adaptive Threshold', binary_image)
cv2.imshow('3. Morphological Closing', closed)
cv2.waitKey(0)
cv2.destroyAllWindows()
# --- 主程序入口 ---
if __name__ == '__main__':
try:
script_dir = os.path.dirname(os.path.abspath(__file__))
except NameError:
script_dir = os.getcwd()
# 请确保你的图片路径正确
image_filename = 'data/test3/l2.jpeg'
image_path = os.path.join(script_dir, image_filename)
if not os.path.exists(image_path):
# 如果找不到,尝试直接使用文件名(假设图片和脚本在同一目录)
image_path = '13-l.bmp'
if not os.path.exists(image_path):
print(f"错误: 输入文件 '{image_path}' 不存在。")
else:
find_and_mask_weld_seam_v3(image_path)
else:
find_and_mask_weld_seam_v3(image_path)