一维边缘检测

8

与其检测2D图像的边缘,我想要单独检测图像每一行(即一条线)的边缘。这是从输入的1D向量中检测边缘,该向量的值是介于0到255之间的像素强度(如下图所示):

enter image description here

我想要检测主要的边缘,就像样本输入中显示的那样(如下图所示):

enter image description here

感谢大家的回复。如果您有任何新的想法(例如一维边缘检测),请在此分享。 - C graphics
3个回答

10

通过以下方法之一,可以实现所需结果:将2D Canny边缘检测器进行调整(使用Mathematica的代码):

首先,使用高斯导数滤波器计算空间导数,将sigma值相对于要检测的边缘的比例进行设置。取结果的绝对值。

d = Abs@GaussianFilter[data, {{10, 5}}, 1];

然后,自动确定一个阈值来将之前的导数值聚类成两组(在这里使用Otsu的方法)。
thrd = FindThreshold[d];

然后,检测导数值的步骤(进入/离开“死区”)。

steps = Flatten@Image`StepDetect[d, thrd]["NonzeroPositions"];

此时您已经有了边缘的端点:

ListLinePlot[data, Epilog -> {Red, PointSize[Large], Map[Point[{#, data[[#]]}] &, steps]}]

enter image description here

可选的——似乎这是您想要的——仅保留边缘的最低端。在这种情况下,将数据点聚类到边缘的末端是可行的,但我不确定它有多健壮。

t = FindThreshold@data[[steps]];
steps2 = Select[steps, data[[#]] <= t &];

ListLinePlot[data, Epilog -> {Red, PointSize[Large], Map[Point[{#, data[[#]]}] &, steps2]}]

enter image description here


2
鉴于这些边缘的良好对比度,有一个简单的解决方案可以稳健地工作:检测所有单调序列的像素值(严格递增或递减)。您将保留具有总高度超过阈值(在您的情况下为50)以拒绝噪声峰的序列。
作为副产品,您将获得起始点和结束点(虽然不完全是您期望的位置,但如果需要可以改进)。
条形码?

1
不完全准确,但您可以将其视为彩色条形码。 - C graphics

1

所以你正在寻找特定的斜率变化 - 即每个样本中Y值的某种变化?

难道不是简单地查看两个样本之间的Y值差异,如果其绝对值发生了超过某个限制的变化,则将其标记为边缘吗?


1
不过,这并不是一件简单的事情。请参考:http://en.wikipedia.org/wiki/Edge_detection (为什么边缘检测是一个非平凡的任务) - C graphics
@Cgraphics:根据您发布的图像,一个简单的高斯差分或导数算子应该可以很好地解决问题。如果您认为“这根本不简单”,请发布实际数据以便更好地帮助您。 - Niki
@nikie 这是实际的图像,然而它并不像应用一个简单的阈值那么简单。我们需要准确地检测边缘,而不仅仅是计数。 - C graphics

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接