Python低对比度图像的边缘检测

Python edge detection of low contrast image

我想画 find 绘制区域的深度和绘制边界 我尝试使用 Canny 边缘检测,但它不太好获取边缘。有没有办法获得感兴趣边界的像素?边界线中的像素强度(灰度)与周围区域没有什么不同。 感兴趣的区域是金属上的熔池。目的是找到熔池的深度。我尝试了 Canny 边缘检测,但似乎无法解决问题。 我在图2中涂成红色的熔池边界的边界坐标是否有其他方法使用python?原始图像 Region of interest (in red) Canny 边缘检测 The melting pool is moving. I want to use python to get the depth change of the melting pool. I have bunch of images

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()

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

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

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

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

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

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

二次分割得到没有pool的水平线,计算它们的差值得到最终结果。

必须调整 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()

结果: