gpt4 book ai didi

matlab - 在矩阵中绘制极坐标灰度值而不对每个 for 循环进行插值

转载 作者:太空宇宙 更新时间:2023-11-03 20:01:31 26 4
gpt4 key购买 nike

我有一个灰度值介于 01 之间的矩阵。对于矩阵中的每个条目,都有特定的极坐标指示灰度值的位置。我已经有了 ThetaRho 值(极坐标),它们都在单独的 512×960 矩阵中。以及每个 ThetaRho 组合的灰度值(在名为 C 的矩阵中)。 XY 也是一样的,因为我只是使用 pol2cart 进行转换。问题是我无法直接绘制这些值,因为它们还不适合新矩阵的“箱子”。

我想要的是:将灰度值放在一个大小为 1024×1024 的方阵中。我不能直接这样做,因为极坐标落在这个矩阵的网格之间。因此,我们现在使用插值,但这非常耗时,而且必须对每个数据集分别进行,尽管从原始矩阵到最终矩阵的转换总是相同的。因此,我想一次解决这个矩阵(解析或数值)并使用矩阵乘法或类似的东西在代码的每个循环中有效地应用操作。

这些转换之一可能如下所示的示例:

enter image description here

第一个矩阵中的零是网格,值1(在网格之间)是落在四个网格点之间的灰度值,然后我想转换为第二个矩阵(不要介意点之间的视觉间距)。

对于每个数据集,我都有数百个这样的矩阵,所以我想让代码更高效。

背景:我现在使用 TriScatteredInterp 进行插值。我们也尝试了 scatteredInterpolant,但速度较慢。我还发布了a related question ,但决定拆分这两种可能的解决方案,因为我在这里要求的解决方案也适用于非 MATLAB 代码,并且可能会更快并且使代码执行更顺畅(不会连续弹出数字)。

最佳答案

使用图像处理工具箱

图像的工作方式与您拥有的数据略有不同。但是,将一种表示映射到另一种表示相当简单。

我只看到一个问题:包装。显然,θ = 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 PNG图片 stars made with MS Paint

The original

The rescaled image

现在,这两个看起来一样(真的想不出更合适的图像),所以你必须相信我,512×960 确实已重新调整为 1024×1024,最近-邻域插值。

以下是一些简单内核的实际 imresize() 操作的一些时序:

nearest : 0.008511 seconds.
bilinear: 0.019651 seconds.
bicubic : 0.025390 seconds. <-- default kernel

但这在很大程度上取决于您的硬件;我相信 imresize 将大量工作卸载到 GPU,所以如果你有一个糟糕的 GPU,它会更慢。

包装

如果包装问题对您来说真的很重要,您可以修改上面的函数来执行以下操作:

  • 首先,像以前一样使用imresize()重新缩放图像
  • 水平连接灰度数据的第二部分和第一部分。意思是,你交换前半部分和后半部分,使左右边缘(0 和 2π)在中间接触。
  • 使用 imresize() 重新缩放此中间图像
  • 提取重新缩放的中间图像的中心垂直 strip
  • 把它分成两个等宽的 strip
  • 并用您刚刚创建的两个 strip 替换输出图像的边缘 strip

现在,这是一种蛮力方法:您将图像重新缩放两次,第二轮图像的大部分像素将被丢弃。如果性能有问题,您当然可以仅将重新缩放应用于该中间图像的中央 strip 。但是,好吧,这会有点复杂。

关于matlab - 在矩阵中绘制极坐标灰度值而不对每个 for 循环进行插值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37182879/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com