在MATLAB中插入/填充真值网格中的缺失单元格

时间:2014-03-05 16:01:39

标签: matlab matrix interpolation

考虑下面的37x101矩阵: Original matrix

每个黑色单元格的值为1,其余单元格的值为0.我想通过三次样条插值填充“间隙”,以及将y轴从37缩放到181.后者可以通过使用interp1函数完成,如:

interp1(37,matrix,181,'pchip')

然而,结果现在沿y轴插值,但差距仍然存在: Interpolated

我不想沿x轴插值,因为我希望最终矩阵的尺寸为181 x 101.我只想用现有的单元格(181 x 101矩阵)填充间隙。

如何将原始矩阵(顶部)从37 x 101缩放到181 x 101(在第二个图像中没有“平滑”),以及使用某种样条插值填充间隙,就好像这样是一个适当的功能?

2 个答案:

答案 0 :(得分:1)

我认为这是一个位图,为什么不是一个钳位模糊?

I=yourmatrixhere

%gaussian blur
%    it looks like bump-to-bump distance is 3 empties
%    therefore hsize should be about 7
%    it looks like bump vertical size is about 4
%    therefore simga should be about 10

hsize=[3 3];
sigma = 10;
h=fspecial('gaussian',hsize,sigma)

I2=imfilter(I,h,'replicate');

此时您已将信息传播到相邻列,但您需要从连续“整理”到二进制。

%threshold
th = 0.25;

I3=zeros(size(I));
ind=find(I>=th);
I3(ind)=1;

此时,I3是您感兴趣的矩阵,可以进行“侵蚀”或插值。

答案 1 :(得分:1)

看起来您的真值网格有一个单独的值,其中每一行都有真值。如果true / 1值确实在图像中创建了一条线,我建议根据t对该线进行参数化,以便y = fy(t)x = fx(t)。如果您对此不熟悉,可以在youtube教程或谷歌上找到一些参数化信息。主要的想法是,如果你有,说一个看起来像这样的真值表:

Original Table

然后,您可以绘制每个像素相对于另一个变量t的位置,然后分别对每个像素使用interp1(...)。在我的例子中,我定义了x和y值如下:

n = 32;
rand('seed', 1982);
y_orig = 1:n;
x_orig = ceil(n*sin(y_orig/n*pi));

所以我可以作为:

t1 = linspace(0,1, n);
plot(t1,x_orig, 'r', 'linewidth', 3);
hold all
plot(t1,y_orig, 'b', 'linewidth', 3);
legend('X', 'Y')

enter image description here

请注意,我可以通过像这样使用interp1获得我想要的任何真值(如果你想在第5行和第6行之间找到值):

 desiredY = 5.5;
 t= 1:n;
 truthValue= interp1(t, x_orig, desiredY, 'cubic')

但是我们正在寻找一个新的图像,所以我选择了一个更方便的0和0之间的参数化。不幸的是,你手上可能没有x和y,所以我们需要将它们从图像中拉出来。假设每行中都有一个true / 1值,我们可以用max(...)拉出值:

[maxVals, x1] = max(data,[],2);
x1(maxVals == 0) = [];
y1 = find(maxVals ~= 0);

每行上的某种形式的find也可以使用。如果每行中都有真值,那么y1应该等于1:n。 max函数返回第二个返回值中维度2中max的索引。我使用接下来的两行来删除真值表为空的任何条目(max为零)然后y1 = 1:n减去那些空的条目。

沿着这条线获得大量积分的快速而肮脏的方法是:

t2 = linspace(0,1,1024);
x2 = interp1(t1, x1, t2, 'cubic');
y2 = interp1(t1, y1, t2, 'cubic');
然后我可以将原始的点/图像和这个新发现的细线一起绘制成这样:

imagesc(data);
hold all;
plot(x2,y2, 'linewidth', 2);
axis image
colormap(flipud(colormap(gray)));

要得到这个:

Truth Image with Curve on Top

最后,您可以通过缩放参数化来快速将其转换为新图像。为清晰起见,我的方法效率不高:

y2_scaled = floor((y2(:)-1)*scaleValue + 1);
x2_scaled = floor((x2(:)-1)*scaleValue + 1);

scaleValue = 2;
data2 = zeros(n*scaleValue);
for ind = 1:length(x2_scaled)
    data2(y2_scaled(ind),x2_scaled(ind)) = 1;
end

结果是:

Table Double Size

请注意,此表已连接所有点,现在每行中有多个true / 1。这是因为我为t2选择了一个非常小的步长。您可以通过选择更智能的t2,在每行中跳过多个值,或平均每行中每个索引的位置来解决此问题。或者忽略了这个问题。

要使用缩放值修复t2,您可以使用

t2 = linspace(0,1,n*scaleValue);

在上面的代码中每行只获得一个真/ 1。

另外,如果您只想缩放一个维度,可以这样做:

y2_scaled = floor((y2(:)-1)*scaleValue + 1);
x2_scaled = floor((x2(:)-1) + 1);

scaleValue = 2;
data2 = zeros(n*scaleValue,n);
for ind = 1:length(x2_scaled)
    data2(y2_scaled(ind),x2_scaled(ind)) = 1;
end