首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在矩阵中绘制极点灰度值,而无需对每个for循环进行插值

在矩阵中绘制极点灰度值,而无需对每个for循环进行插值
EN

Stack Overflow用户
提问于 2016-05-12 17:33:16
回答 1查看 152关注 0票数 4

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

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

以下是这些转换之一的一个示例:

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

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

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

EN

回答 1

Stack Overflow用户

发布于 2016-11-22 19:47:47

使用图像处理工具箱

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

我只看到一个问题:包装。显然,θ= 2π= 0,但MATLAB不知道这一点。AFAIK,没有简单的方法告诉MATLAB这一点。

为什么这很重要?简单地说,像素间插值使用来自最近的N邻居的信息来查找中间颜色,而N取决于插值内核。当在图像中间的某个地方这样做时,没有问题,但在边缘,MATLAB必须知道左边缘等于右边缘。这不是标准的图像处理,我也不知道有什么功能可以做到这一点。

实现

现在,当忽略包装问题时,这是一种方法:

代码语言:javascript
复制
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

使用和绘制的图像:

Le精美绘制的512×960 PNG图像

现在,这两个图像看起来是一样的(真的找不到更合适的图像了),所以你必须相信我,512×960确实已经被重新缩放到1024×1024,并使用最近邻插值。

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

代码语言:javascript
复制
nearest : 0.008511 seconds.
bilinear: 0.019651 seconds.
bicubic : 0.025390 seconds.  <-- default kernel

但这在很大程度上取决于你的硬件;我相信imresize会将大量工作转移到图形处理器上,所以如果你有一个糟糕的图形处理器,它会更慢。

包装

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

首先,使用像before

  • horizontally一样的
  • 重新缩放图像将灰度数据的imresize() half和first half连接在一起。这意味着,您可以交换第一个和第二个半部分,以使middle.
  • rescale此中间图像中的左右边缘(0和2π)接触重新缩放的中间图像的中心垂直条带
  • 将其分割为两个等宽的条带
  • ,并将输出图像的边缘条带替换为您刚刚创建的两个条带

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

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37182879

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档