2

我想绘制找到绘制区域的深度并绘制边界我尝试使用Canny边缘检测,但是获得边缘并不好。有没有办法获得感兴趣边界的像素?边界线中的像素强度(灰度)与周围区域没有太大区别。感兴趣的区域是金属上的熔池。目的是找到熔池的深度。我尝试了 Canny 边缘检测,但似乎无法解决问题。是否有其他方法使用 python 来确定我在图 2 中用红色着色的熔池边界的边界坐标?原始图像 感兴趣区域(红色)Canny 边缘检测熔池正在移动。我想用python来获取熔池的深度变化。我有一堆图片原始图像 感兴趣的区域 Canny 边缘检测熔池 1熔池 2

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('image.tif',0)
edges = cv2.Canny(img,100,20)

plt.subplots(),plt.imshow(img,cmap = 'gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplots(),plt.imshow(edges,cmap = 'gray')
plt.title('Edge Image'), plt.xticks([]), plt.yticks([])

plt.show()
4

2 回答 2

2

我认为获得有关金属池所需信息的最佳方法是对其进行分段。由于图像嘈杂,我认为图形切割是更好的选择。

我使用垂直 Scharr 过滤估计池边界,并使用它们来计算图形弧权重。

沙尔

由此,我使用图像的上下边界作为图形切割算法的源和接收器(这些像素将属于不同的标签)。

执行第二次分割以获得没有池的水平线并计算它们的差异以获得最终结果。

beta必须调整参数,随着它的增加,它会更符合您的权重(嘈杂的边界)。我发现 50 得到了很好的结果,但你应该玩它。

import numpy as np
from skimage import io, filters, measure
import skimage.morphology as morph
import matplotlib.pyplot as plt
import maxflow


def normalize(im):
    im -= im.min()
    return im / im.max()


def graph_cut(weights):
    g = maxflow.GraphFloat()
    nodeids = g.add_grid_nodes(weights.shape)
    structure = maxflow.vonNeumann_structure(ndim=2, directed=True)

    g.add_grid_edges(nodeids, weights, structure=structure, symmetric=True)
    g.add_grid_tedges(nodeids[1, :], 0, 1e16)
    g.add_grid_tedges(nodeids[-1, :], 1e16, 0)
    g.maxflow()

    return g.get_grid_segments(nodeids)


def get_largest(label):
    label = measure.label(label)
    largest = label == np.argmax(np.bincount(label.flat)[1:])+1
    return largest 


def main():
    im = io.imread("example.png")
    im = filters.median(im, morph.disk(5))

    # pool segmentation
    beta = 50  # parameter

    aux = filters.scharr_v(im)  
    aux = normalize(np.abs(aux))
    weights = np.exp(-beta * aux)
    pool = graph_cut(weights) 
    # end

    # surface segmentation
    aux = np.abs(filters.scharr(im))
    aux = normalize(aux)
    weights = np.exp(-aux)
    surf = graph_cut(weights)
    # end

    # result
    res = pool ^ surf  # xor
    res = get_largest(res)
    contours = measure.find_contours(res, 0.5)

    fig, ax = plt.subplots()

    ax.imshow(im, cmap='gray')
    for contour in contours:
        ax.plot(contour[:, 1], contour[:, 0], linewidth=1, c = 'red')

    plt.show()


if __name__ == "__main__":
    main()

结果:

资源1

资源2

于 2020-07-30T21:08:05.770 回答
2

强大的水平低通滤波将提高信噪比并使顶部边缘易于检测。

在此处输入图像描述

请注意,原始图像的直接二值化效果更好。

在此处输入图像描述

自适应阈值也很有趣,尽管需要一些调整。

在此处输入图像描述

于 2020-07-29T06:56:08.363 回答