我需要过滤图像中给定的线条宽度。
我正在编写一个可以检测道路图像线的程序。我发现了类似的东西但却无法理解它的逻辑。我的功能必须这样做: 我将以像素大小(例如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;
}
}
}
该代码的数学解释是什么?这是如何工作的?
答案 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(钳位为零)。