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

时间:2015-12-10 12:36:10

标签: c++ opencv math image-processing detection

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

我正在编写一个可以检测道路图像线的程序。我发现了类似的东西但却无法理解它的逻辑。我的功能必须这样做: 我将以像素大小(例如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;
        }
    }
}

该代码的数学解释是什么?这是如何工作的?

2 个答案:

答案 0 :(得分:1)

了解卷积滤镜。此代码是 1维卷积滤镜的特殊情况(它只与当前处理的线上的其他像素卷积)。

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

如果您有图片:

0011100

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

$("div").addClass(function(index, currentClass) {
var addedClass;
if (currentClass === "fu-icon1") {
    addedClass = "glyphicon glyphicon-ok-sign";
    $(".table tr").addClass("success");
} else if (currentClass === "fu-icon0") {
    addedClass = "glyphicon glyphicon-remove-sign";
    $(".table tr").addClass("danger");
}
return addedClass;
});

第一个&#39; 1&#39;将成为:

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

第三个&#39; 1&#39; (它是一个镜像)。

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

答案 1 :(得分:0)

这是一个相当奇怪的过滤器。它在同一条线上将像素值三乘三,具有tau间距。将这些值设为Vl,V和Vr。

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

因此,全局滤波器将为对称最大值提供最大响应(例如在深色背景上的光路,垂直,宽度小于2.tau)。

通过重新排列术语,您可以看到滤波器还产生最小的左右渐变,V - Vm和V - Vp(钳位为零)。