如何过滤图像中给定宽度的线条

How to filter given width of lines in a image?

本文关键字:何过滤 过滤 图像      更新时间:2023-10-16

我需要过滤图像中给定宽度的线条。

我正在编写一个程序来检测道路图像的线条。我发现了类似的东西,但无法理解其中的逻辑。我的功能必须做到这一点:我将发送图像行宽度的像素大小(例如30像素宽度),函数将仅过滤图像中的这些行。

我发现了那个代码:

void filterWidth(Mat image, int tau) // tau=width of line I want to filter
int aux = 0;
for (int j = 0; j < quad.rows; ++j)
{
    unsigned char *ptRowSrc = quad.ptr<uchar>(j);
    unsigned char *ptRowDst = quadDst.ptr<uchar>(j);
    for (int i = tau; i < quad.cols - tau; ++i)
    {
        if (ptRowSrc[i] != 0)
        {
            aux = 2 * ptRowSrc[i];
            aux += -ptRowSrc[i - tau];
            aux += -ptRowSrc[i + tau];
            aux += -abs((int)(ptRowSrc[i - tau] - ptRowSrc[i + tau]));
            aux = (aux < 0) ? (0) : (aux);
            aux = (aux > 255) ? (255) : (aux);
            ptRowDst[i] = (unsigned char)aux;
        }
    }
}

这个代码的数学解释是什么?这是怎么回事?

阅读有关卷积滤波器的信息。该代码是1维卷积滤波器的特殊情况(它只与当前处理线上的其他像素进行卷积)。

aux的值从当前像素值的2*开始,然后从该值减去其两侧距离τ处的像素。接下来,这两个像素的绝对也从中减去。最后,在存储在输出图像中之前,它被限制在0…255的范围内。

如果你有一个图像:

0011100

该卷积将使中心1获得值:

2 * 1
- 0
- 0
- abs(0 - 0)
= 2

第一个"1"将变为:

2 * 1
- 0
- 1
- abs(0 - 1)
= 0

第三个"1"也是如此(它是镜像)。

当然,0的值将始终保持零或变为负,这将被限制为0。

这是一个相当奇怪的过滤器。它在同一行上取三乘三的像素值,间隔为τ。将这些值设为Vl、V和Vr。

滤波器计算-Vl+2V-Vr,可以看作二阶导数,并推导|Vl-Vr|,可以看作一阶导数(也称为梯度)。二阶导数在最大配置(Vl<V>Vr)的情况下给出最大响应;在对称配置(Vl=Vr)的情况下,一阶导数给出最小响应。

因此,全局滤波器将给出对称最大值的最大响应(就像在黑暗背景上的浅色道路,垂直的,宽度小于2τ)

通过重新排列这些项,你可以看到滤波器也产生了左梯度和右梯度中最小的一个,V-Vm和V-Vp(箝位为零)。