matlab 将图像从笛卡尔转换为极坐标

34gzjxbg  于 2022-11-15  发布在  Matlab
关注(0)|答案(2)|浏览(215)

我想转换一个图像从笛卡尔到极轴,并使用它的OpenGL纹理。因此,我参考了下面的两篇文章,使用了MatLab。
Link 1Link 2
我的代码与Link 2的Anwser完全相同

% load image 
img = imread('my_image.png');

% convert pixel coordinates from cartesian to polar
[h,w,~] = size(img);
[X,Y] = meshgrid((1:w)-floor(w/2), (1:h)-floor(h/2));

[theta,rho] = cart2pol(X, Y);
Z = zeros(size(theta));

% show pixel locations (subsample to get less dense points)
XX = X(1:8:end,1:4:end);
YY = Y(1:8:end,1:4:end);
tt = theta(1:8:end,1:4:end);
rr = rho(1:8:end,1:4:end);

subplot(121), scatter(XX(:),YY(:),3,'filled'), axis ij image
subplot(122), scatter(tt(:),rr(:),3,'filled'), axis ij square tight

% show images
figure
subplot(121), imshow(img), axis on
subplot(122), warp(theta, rho, Z, img), view(2), axis square

结果正是我想要的,除了一件事,我非常满意。这是下面图片中的区域(红色圈出的区域)。考虑到对面(蓝色圈出的区域)不是,我认为这部分也应该填上。因为这个部分是空的,所以当它用作纹理时会有问题。我想知道我如何才能填补这一部分。谢谢。(与Link 2的答案代码如度数<->弧度和轴值差别不大。但我认为这并不重要。)

eqqqjvef

eqqqjvef1#

您在问题中显示的问题之所以会发生,是因为您的算法是错误的。
您所做的(推送):

  • 在源图像上抛出网格
  • 转变这些点
  • 试着把这些有色点画出来,让MatLab施点魔法,让它看起来像一幅密集的图画

反之亦然(拉):

  • 在输出上投掷网格
  • 向后转变
  • 对这些点的输入进行采样

这种区别被称为“推”(进入输出)和“拉”(来自输入)。只有才能给出正确的结果。
只需要很少的MatLab代码。您只需要pol2cartinterp2,以及一个meshgrid
使用interp2,您可以选择内插(线性、立方等)。最近邻插值法会留下可见的瑕疵。

im = im2single(imread("PQFax.jpg"));

% center of polar map, manually picked
cx = 10 + 409/2;
cy = 7 + 413/2;

% output parameters
radius = 212;
dRho = 1;
dTheta = 2*pi / (2*pi * radius);
Thetas = pi/2 - (0:dTheta:2*pi);
Rhos = (0:dRho:radius);

% polar mesh
[Theta, Rho] = meshgrid(Thetas, Rhos);

% transform...
[Xq,Yq] = pol2cart(Theta, Rho);

% translate to sit on the circle's center
Xq = Xq + cx;
Yq = Yq + cy;

% sample image at those points
Ro = interp2(im(:,:,1), Xq,Yq, "cubic");
Go = interp2(im(:,:,2), Xq,Yq, "cubic");
Bo = interp2(im(:,:,3), Xq,Yq, "cubic");
Vo = cat(3, Ro, Go, Bo);
Vo = imrotate(Vo, 180);
imshow(Vo)

反之亦然(从“丝带”获得一个“圆环”)非常相似。在圆环空间上抛出一个网格,减去中心,从笛卡儿变换到极轴,并使用这些来从“带状”图像采样到“圆环”图像。
我对OpenCV比对MatLab更熟悉。也许MatLab有类似OpenCV的warpPolar(),或者通用的remap()。无论如何,完全“手工”完成操作是微不足道的,但有足够的支持功能来减轻您手中的繁重工作(interp2、pol2cart、Meshgrid)。

xvw2m8pv

xvw2m8pv2#

1.-白色圆弧表示所使用的翻译POL-CART引入了重大错误。

2.-颠倒以下脚本可以解决您的问题。
这是一个从cart-poll开始的脚本,没有引入错误或忽略输入数据,这就是当翻译后出现如此宽的白色弧线明显正确时所发生的情况。

clear all;clc;close all

     clc,cla;
      format long;

      A=imread('shaffen dass.jpg');
      [sz1 sz2 sz3]=size(A);  
      szx=sz2;szy=sz1;
      A1=A(:,:,1);A2=A(:,:,2);A3=A(:,:,3);  % working with binary maps or grey scale images this wouldn't be necessary

      figure(1);imshow(A);
      hold all;
  Cx=floor(szx/2);Cy=floor(szy/2);
   plot(Cx,Cy,'co');                                                      % because observe image centre not centered

Rmin=80;Rmax=400;                                               % radius search range for imfindcircles
[centers, radii]=imfindcircles(A,[Rmin Rmax],...            % outer circle
    'ObjectPolarity','dark','Sensitivity',0.9);
h=viscircles(centers,radii);

hold all;                                                                  % inner circle
[centers2, radii2]=imfindcircles(A,[Rmin Rmax],...
    'ObjectPolarity','bright');
h=viscircles(centers2,radii2);

% L=floor(.5*(radii+radii2));                                      % this is NOT the length X that should have the resulting XY morphed graph
L=floor(2*pi*radii);                                                           % expected length of the morphed graph

cx=floor(.5*(centers(1)+centers2(1)));                      % coordinates of averaged circle centres
cy=floor(.5*(centers(2)+centers2(2)));

plot(cx,cy,'r*');                                                        % check avg centre circle is not aligned to figure centre
plot([cx 1],[cy 1],'r-.');

t=[45:360/L:404+1-360/L];                                                       % if step=1 then we only get 360 points but need an amount of L points
                                                                                % if angle step 1/L over minute waiting for for loop to finish
R=radii+5;x=R*sind(t)+cx;y=R*cosd(t)+cy;                  % build outer perimeter
hL1=plot(x,y,'m'); % axis equal;grid on;  

% hold all;
% plot(hL1.XData,hL1.YData,'ro');

x_ref=hL1.XData;y_ref=hL1.YData;

% Sx=zeros(ceil(R),1);Sy=zeros(ceil(R),1);
Sx={};Sy={};

for k=1:1:numel(hL1.XData)
    Lx=floor(linspace(x_ref(k),cx,ceil(R)));
    Ly=floor(linspace(y_ref(k),cy,ceil(R)));
    % plot(Lx,Ly,'go');    % check
    % plot([cx x(k)],[cy y(k)],'r');
%     L1=unique([Lx;Ly]','rows');
    Sx=[Sx Lx'];Sy=[Sy Ly'];
end

sx=cell2mat(Sx);sy=cell2mat(Sy);

[s1 s2]=size(sx);

B1=uint8(zeros(s1,s2));
B2=uint8(zeros(s1,s2));
B3=uint8(zeros(s1,s2));

for n=1:1:s2
    for k=1:1:s1
        B1(k,n)=A1(sx(k,n),sy(k,n)); 
        B2(k,n)=A2(sx(k,n),sy(k,n)); 
        B3(k,n)=A3(sx(k,n),sy(k,n)); 
    end
end

C=uint8(zeros(s1,s2,3));
C(:,:,1)=B1;
C(:,:,2)=B2;
C(:,:,3)=B3;
figure(2);imshow(C);

由此产生的

3.-让我知道如果你想要一些帮助写Poll-Cart从这个剧本。
问候
约翰·贝克

相关问题