You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于OpenCV检测透射电镜下弯曲网格的节点坐标

TEM网格图片节点坐标检测问题

我有多张透射电镜(TEM)下的网格图片,想要获取网格节点(交叉点)的坐标。参考数独网格或普通直线检测教程实现时,因为线条弯曲、和背景颜色相近,检测结果不理想。

我的实现代码

import cv2
import numpy as np

image = cv2.imread("test.png")
original = image.copy()
cv2.imshow("Image", image)

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv2.imshow("gray", gray)

blur = cv2.GaussianBlur(gray, (5, 5), 0)
cv2.imshow("blur", blur)

ret, thresh = cv2.threshold(blur, 32, 255, cv2.THRESH_BINARY)
cv2.imshow("thresh", thresh)
low_threshold = 50
high_threshold = 150
edges = cv2.Canny(thresh, low_threshold, high_threshold)

cv2.imshow("edges", edges)
rho = 1  # 霍夫网格的像素距离分辨率
theta = np.pi / 180  # 霍夫网格的弧度角度分辨率
threshold = 30  # 霍夫网格单元格的最小投票数
min_line_length = 50 # 构成线条的最小像素数
max_line_gap = 250  # 可连接线段之间的最大像素间隙
line_image = np.copy(image) * 0  # 创建空白画布用于绘制线条

# 在边缘检测图像上运行霍夫变换
# 输出"lines"是包含检测线段端点的数组
lines = cv2.HoughLinesP(edges, rho, theta, threshold,
                        np.array([]), min_line_length, max_line_gap)
print(lines)
for line in lines:
    for x1,y1,x2,y2 in line:
        cv2.line(line_image,(x1,y1),(x2,y2),(255,0,0),1)
cv2.imshow('result',line_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

现有处理结果

  • 网格原图
    网格原图

  • 灰度化、高斯模糊及阈值处理后的结果
    预处理后图像

  • Canny边缘检测结果
    Canny边缘检测结果

  • 霍夫线变换后的最终结果
    霍夫线变换结果


优化解决方案

针对线条弯曲、背景对比度低的问题,可通过调整预处理和检测策略改善结果:

1. 改进预处理流程

替换固定阈值为自适应阈值,适配背景不均匀的图像;增加形态学操作强化网格线条:

# 替换原固定阈值处理步骤
thresh = cv2.adaptiveThreshold(blur, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2)

# 形态学闭运算填补线条间隙
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)

2. 调整边缘检测参数

降低Canny高阈值并缩小高低阈值比例(建议1:2),保留更多弱边缘:

low_threshold = 30
high_threshold = 60
edges = cv2.Canny(thresh, low_threshold, high_threshold)

3. 优化霍夫线检测参数

减小max_line_gap避免误连无关线段,降低threshold检测更多短线条:

threshold = 20
min_line_length = 30
max_line_gap = 50
lines = cv2.HoughLinesP(edges, rho, theta, threshold,
                        np.array([]), min_line_length, max_line_gap)

4. 提取网格节点坐标

分离水平/垂直线条,计算所有线对的交点并去重:

# 分离水平和垂直线条
horizontal_lines = []
vertical_lines = []
for line in lines:
    x1, y1, x2, y2 = line[0]
    angle = np.arctan2(y2-y1, x2-x1) * 180 / np.pi
    # 允许10度以内的角度偏差
    if abs(angle) < 10 or abs(angle) > 170:
        horizontal_lines.append(line[0])
    elif abs(angle - 90) < 10 or abs(angle +90) <10:
        vertical_lines.append(line[0])

# 计算两条线段的交点
def line_intersection(line1, line2):
    x1,y1,x2,y2 = line1
    x3,y3,x4,y4 = line2
    denom = (x1-x2)*(y3-y4) - (y1-y2)*(x3-x4)
    if denom == 0:
        return None  # 平行无交点
    t_num = (x1-x3)*(y3-y4) - (y1-y3)*(x3-x4)
    u_num = (x1-x3)*(y1-y2) - (y1-y3)*(x1-x2)
    t = t_num / denom
    u = u_num / denom
    if 0<=t<=1 and 0<=u<=1:
        x = x1 + t*(x2-x1)
        y = y1 + t*(y2-y1)
        return (int(x), int(y))
    return None

# 计算所有水平与垂直线的交点并去重
intersections = []
for h_line in horizontal_lines:
    for v_line in vertical_lines:
        pt = line_intersection(h_line, v_line)
        if pt is not None:
            intersections.append(pt)
intersections = list(set(intersections))

print("网格节点坐标:", intersections)

内容的提问来源于stack exchange,提问作者Xuanhao Wang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 06:54:45