【问题标题】:Python edge detection of low contrast image低对比度图像的Python边缘检测
【发布时间】:2020-11-18 10:25:26
【问题描述】:

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

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

【问题讨论】:

  • 图 1 中的红色涂鸦是您感兴趣的区域吗?
  • 嗨 JoOkuma,是的,这就是我想要检测的边界。你有什么建议吗?
  • 这似乎是一个具有挑战性的问题。您要将其应用于多个图像吗?您的感兴趣区域 (ROI) 的模式是否相同?额外的图片或这项任务的背景会增加您获得帮助的机会。
  • @JoOkuma 感谢您的建议!我已经改写了描述。
  • @MarkSetchell 感谢 cmets!我改写了描述。看看是不是更好。

标签: image-processing edge-detection


【解决方案1】:

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

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

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

【讨论】:

  • Yves,您能否添加您使用的过滤器内核/参数,以便其他人可以获得相同的效果。谢谢。
  • @MarkSetchell:抱歉,我使用了专有软件。
  • @YvesDaoust 我认为 OP 正在寻找他们用红色勾勒的小井,而不是大的水平边缘。
【解决方案2】:

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

我使用垂直 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()

结果:

【讨论】:

  • 致 OP:这个答案与您的问题有什么关系吗?如果是,我会删除我的。
  • @Yves Daoust 是的,这个答案与我的问题有关。
  • @JoOkuma 感谢您的回答!
猜你喜欢
  • 2020-12-16
  • 1970-01-01
  • 2021-07-05
  • 1970-01-01
  • 2020-10-11
  • 2015-04-24
  • 1970-01-01
  • 1970-01-01
  • 2010-12-01
相关资源
最近更新 更多