您的真值网格似乎只有一个,其中真值在每一行中。如果 true/1 值确实在图像中创建了一条线,我建议将这条线参数化为 t,以便 y = fy(t) 和 x = fx(t)。如果您对此不熟悉,可以在 youtube 教程或 google 上找到一些参数化信息。主要思想是,如果您有 ,请说出如下所示的真值表:
然后您可以绘制每个像素相对于另一个变量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')
但是我们正在寻找一个新的图像,所以我选择了一个更方便的参数化 t 介于 0 和 1 之间。不幸的是,您可能手头没有 x 和 y,因此我们需要将它们从图像中拉出。假设您在每一行中都有一个 true/1 值,我们可以使用 max(...) 抽出这些值:
[maxVals, x1] = max(data,[],2);
x1(maxVals == 0) = [];
y1 = find(maxVals ~= 0);
每行上的某种形式的find 也可以使用。如果每一行都有一个真值,那么y1 应该等于1:n。 max 函数在第二个返回值中返回最大维度 2 的索引。我使用接下来的两行删除真值表为空的所有条目(最大值为零),然后 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);
在上面的代码中每行只得到一个 true/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