我的矩阵的灰色值介于0
和1
之间。对于矩阵中的每个条目,存在指示灰度值的位置的某些极坐标。我已经有Theta
和Rho
值(极值),两者都在单独的512×960矩阵中。每个C
和Theta
组合的灰度值(在一个名为Rho
的矩阵中)。我对X
和Y
也有同样的看法,因为我只使用pol2cart
进行转换。问题是我不能直接绘制这些值,因为它们还不适合新矩阵的“箱”。
我想要的是:将灰度值放在1024×1024大小的方阵中。我不能直接这样做,因为极坐标落在这个矩阵的网格之间。因此,我们现在使用插值,但这非常耗时,并且必须为每个数据集单独完成,尽管从原始矩阵到最后一个矩阵的转换将始终相同。因此,我想解决这个矩阵一次(分析或数字)并使用矩阵乘法或类似的东西在代码的每个循环中有效地应用操作。
这些转换之一的一个例子如下:
第一个矩阵中的零是网格,值1
(在网格之间)是落在四个网格点之间的灰度值,然后我想转换为第二个矩阵(不要介意点之间的视觉间距)。
对于每个数据集,我有数百个这样的矩阵,所以我想提高代码的效率。
背景:我现在正在使用TriScatteredInterp
进行插值。我们也尝试了scatteredInterpolant
,但速度较慢。我还发布了a related question,但决定拆分两个可能的解决方案,因为我在这里要求的解决方案也适用于非MATLAB代码,并且可能更快并且更平滑(没有连续弹出的数字) )执行代码。
答案 0 :(得分:3)
图片的工作方式与您拥有的数据略有不同。但是,将一个表示映射到另一个表示是相当简单的。
我看到的问题只有一个:包装。显然,θ=2π= 0,但MATLAB不知道。 AFAIK,没有简单的方法告诉MATLAB。
为什么这很重要?嗯,简单地说,像素间插值使用来自最近的N
个邻居的信息来找到中间颜色,N
取决于插值内核。当在图像中间的某处执行此操作时没有问题,但在边缘处,MATLAB必须知道左边缘等于右边缘。这不是标准的图像处理,我不知道任何能够做到这一点的功能。
现在,当忽略包装问题时,这是一种方法:
function resize_polar()
%% ORIGINAL IMAGE
% ==========================================================================
% Some random greyscale data
C = double(rgb2gray(imread('stars.png')))/255;
% Your current size, and desired size
sz_x = size(C,2); new_sz_x = 1024;
sz_y = size(C,1); new_sz_y = 1024;
% Ranges for teat and rho;
% replace with your actual values
rho_start = 0; theta_start = 0;
rho_end = 10; theta_end = 2*pi;
% Generate regularly spaced grid;
theta = linspace(theta_start, theta_end, sz_x);
rho = linspace(rho_start, rho_end, sz_y);
[theta, rho] = meshgrid(theta,rho);
% Make plot of generated data
plot_polar(theta, rho, C, 'Original image');
% Resize data
[theta,rho,C] = resize_polar_data(theta, rho, C, [new_sz_y new_sz_x]);
% Make plot of generated data
plot_polar(theta, rho, C, 'Rescaled image');
end
function [theta,rho,data] = resize_polar_data(theta,rho,data, new_dims)
% Create fake RGB image cube
IMG = cat(3, theta,rho,data);
% Rescale as if theta and rho are RG color data in the RGB
% image cube
IMG = imresize(IMG, new_dims, 'nearest');
% Split up the data again
theta = IMG(:,:,1);
rho = IMG(:,:,2);
data = IMG(:,:,3);
end
function plot_polar(theta, rho, data, label)
[X,Y] = pol2cart(theta, rho);
figure('renderer', 'opengl')
clf, hold on
surf(X,Y,zeros(size(X)), data, ...
'edgecolor', 'none');
colormap gray
title(label);
end
使用和绘制的图像:
现在,两者看起来一样(实际上并没有真正提出更合适的图像),所以你必须相信我已经将512×960重新调整为1024×1024,最近 - 邻居插值。
以下是一些简单内核的实际imresize()
操作的一些时序:
nearest : 0.008511 seconds.
bilinear: 0.019651 seconds.
bicubic : 0.025390 seconds. <-- default kernel
但这很大程度上取决于你的硬件;我相信imresize
可以为GPU卸载很多工作,所以如果你有一个糟糕的工作,它会慢一些。
如果包装问题对您非常重要,您可以修改上述功能以执行以下操作:
imresize()
之前的图像重新缩放图像imresize()
现在,这是一种蛮力方法:您正在重新缩放图像两次,并且第二轮图像的大部分像素将被丢弃。如果性能有问题,您当然可以将重新缩放仅应用于该中间图像的中心条带。但是,那将会有点复杂。