考虑下面的37x101矩阵:
每个黑色单元格的值为1,其余单元格的值为0.我想通过三次样条插值填充“间隙”,以及将y轴从37缩放到181.后者可以通过使用interp1函数完成,如:
interp1(37,matrix,181,'pchip')
然而,结果现在沿y轴插值,但差距仍然存在:
我不想沿x轴插值,因为我希望最终矩阵的尺寸为181 x 101.我只想用现有的单元格(181 x 101矩阵)填充间隙。
如何将原始矩阵(顶部)从37 x 101缩放到181 x 101(在第二个图像中没有“平滑”),以及使用某种样条插值填充间隙,就好像这样是一个适当的功能?
答案 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教程或谷歌上找到一些参数化信息。主要的想法是,如果你有,说一个看起来像这样的真值表:
然后,您可以绘制每个像素相对于另一个变量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')
请注意,我可以通过像这样使用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)));
要得到这个:
最后,您可以通过缩放参数化来快速将其转换为新图像。为清晰起见,我的方法效率不高:
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
结果是:
请注意,此表已连接所有点,现在每行中有多个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