滑动窗口函数内的操作(​​用于图像去噪)

时间:2013-06-26 15:59:53

标签: python image matlab window sliding

我正在进行图像去噪,试图在我的矩阵中保持连续的线条(有一些宽大处理)并删除与我之后没有真正连接的随机非零元素。我的问题详述如下:

我试图编写一个滑动窗口函数,它将搜索我的二维矩阵的行r并查找非零数字。
对于每个非零数字,该函数应查找行2x2和行r邻域(非零元素两侧的2个数字)内是否存在非零元素r+1(如果存在则r-1) 如果邻域为空,则行r中的原始元素应归零,否则应保留窗口中的所有非零元素。
为了使事情变得复杂,我也试图使滑动窗口变成圆形,这样当它到达行的末尾时,它不会被压缩,而是包含来自邻域中行的开头的数字。

对于所有行,我也只能保留一个“连接”元素,如果它以某种方式连接到第1行,那么我的矩阵中的连续行不能从第2行开始。

我在Matlab中用for - 循环编写了这个,并且在尝试操作窗口中的值时遇到了问题。除此之外,我的功能非常慢。有没有办法在Matlab或Python中执行此操作而不使用for - 循环,并且没有任何预先安装的工具箱?

示例Matlab代码:“test”是一个二进制矩阵(但不是所有我将看到的矩阵都是二进制)。它包含5行。这是我为第1行编写的虚拟代码。窗口操作(代码的第4行)不起作用,但希望这会让你知道我正在尝试做什么。此代码也省略了矩阵的边缘,因为我不确定制作此循环的最佳方法。

n=2 % size of neighborhood to look at
p=size(test,2) % length of row

for ii=1+n:p-n;
    if test(1,ii)==1;
        if sum(test(2,(ii-2:ii+2))+test(1,(ii-2:ii+2)))>=2;
           test(2,(ii-2:ii+2))=test(2,(ii-2:ii+2))*2;
        else;
           test(1,ii)=0;
        end;
    end;
end

var=test(2,:);
var(var==1)=0;
var(var>=2)=1;
test(2,:)=var;

Example matrix ("test"): (zeros replaced with '.' for better visualization)

. . . 1 . . 1 . . . . 1 1 1 . . . . . . . 
1 . . . 1 . 1 . . . 1 . . . . . . . . 1 .
. . . . . 1 1 1 . . . 1 . . . . . . 1 . .
. . 1 . . . . . 1 . . . . . . . . . . 1 .
. . . . . . . . . 1 . . . . . 1 . . . . .

Desired output: (zeros replaced with '.' for better visualization)

. . . 1 . . 1 . . . . 1 1 1 . . . . . . .
. . . . 1 . 1 . . . 1 . . . . . . . . . .
. . . . . 1 1 1 . . . 1 . . . . . . . . .
. . . . . . . . 1 . . . . . . . . . . . .
. . . . . . . . . 1 . . . . . . . . . . .

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

以下是我正在尝试做的想法的大纲:

步骤1:

通过对邻居的值求和,找到所有在3x5邻域中具有非零元素的矩阵位置。我们现在还不想包含当前元素,因此中间为零。输入矩阵为test

fil = [1 1 1 1 1; 1 1 0 1 1; 1 1 1 1 1];
A = conv2(test, fil, 'same');

第2步:

A现在包含值> 1,所以将它们全部更改为1,仅保留零值。

A(A > 0) = 1;

第3步:

现在您已经确定了所有具有有效邻域的元素,通过逐元素乘法将testA结合起来只留下那些test 中非零的元素都有非零邻居。

result = test .* A;

步骤0:

填充 - 上面应该按原样工作,但用零填充行和列。据我了解,你的填充要求是你想要圆形行和用零填充的列。

nCols = size(test, 2);
paddedTest = [zeros(1,nCols);...
              test(:, nCols-1:nCols), test, test(:,1:2);...
              zeros(1,nCols)];

这显然会通过自己的填充来改变您正在处理的矩阵的大小,因此您需要更改卷积参数,以便返回与test大小相同的矩阵。

A = conv2(paddedTest, fil, 'valid');

我现在没有Matlab可用来测试这个,但希望其他人能纠正我所犯的任何严重错误。