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

convert an image from Cartesian to Polar

我正在尝试将具有许多具有相同中心的圆的图像从笛卡尔坐标转换为极坐标(这样新图像将是圆而不是线而不是圆,请参见下图),这就是使用以下代码可以很好地解决问题:

[r, c] = size(img);
r=floor(r/2);
c=floor(c/2);
[X, Y] = meshgrid(-c:c-1,-r:r-1);
[theta, rho] = cart2pol(X, Y); 
subplot(221), imshow(img), axis on;
hold on;
subplot(221), plot(xCenter,yCenter, 'r+');
subplot(222), warp(theta, rho, zeros(size(theta)), img);
view(2), axis square;

问题是,我不明白为什么它会起作用? (显然这不是我的代码),我的意思是,当我使用函数 cart2pol 时,我什至不使用图像,它只是一些从 meshgrid 函数生成的向量 x 和 y .. 另一个问题是,我想以某种方式拥有一个新图像(不仅仅是为了能够使用 wrap 函数绘制它)这是原始图像但是由 theta 和 rho 坐标(意味着相同的像素但重新排列)...我什至不知道怎么问这个问题,最后我想要一个矩阵图像,这样我就可以对每一行求和并将矩阵转换为列向量...

您可以将图像视为二维矩阵,其中每个像素都有一个 X 和 Y 坐标

[(1,1)    (1,2)    (1,3)   ....   (1,c)]
[(2,1)    (2,2)    (2,3)   ....   (2,c)]
[(3,1)    (3,2)    (3,3)   ....   (3,c)]
[....     ....     ....    ....   .... ]
[(r,1)    (r,2)    (r,3)   ....   (r,c)]

在您发布的代码中,它使用图像的中心 floor(c/2)floor(r/2) 将这些 (X,Y) 坐标中的每一个映射到它的等效极坐标 (R, theta)作为参考点。

% Map pixel value at (1,1) to it's polar equivalent
[r,theta] = cart2pol(1 - floor(r/2),1 - floor(c/2));

因此,用于 (1,1) 的任何像素值现在都应该出现在 (r,theta) 处的新极坐标 space 中。重要的是要注意,要进行此转换,与图像中 实际 像素值有关的信息无关紧要,而我们只想对图像中的每个像素执行此转换。

所以首先我们找出图像的中心位置:

[r, c] = size(img);
r = floor(r / 2);
c = floor(c / 2);

然后我们计算出图像中每个点的(X,Y)坐标(在中心已经被减去之后

[X, Y] = meshgrid(-c:c-1,-r:r-1);

现在将所有这些笛卡尔点转换为极坐标

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

warp 现在所做的就是说 "display the value of img at (X,Y) at it's corresponding location in (theta, rho)"

warp(theta, rho, zeros(size(theta)), img);

现在您似乎想要一个尺寸为 [nTheta, nRho] 的新 2D 图像。为此,您可以使用 griddata 将分散的 (theta, rho) 图像(由上面的 warp 显示)插入到规则网格中。

% These is the spacing of your radius axis (columns)
rhoRange = linspace(0, max(rho(:)), 100);

% This is the spacing of your theta axis (rows)
thetaRange = linspace(-pi, pi, 100);

% Generate a grid of all (theta, rho) coordinates in your destination image
[T,R] = meshgrid(thetaRange, rhoRange);

% Now map the values in img to your new image domain
theta_rho_image = griddata(theta, rho, double(img), T, R);

查看 griddata 的所有 interpolation methods 以确定哪个最适合您的情况。

还有其他一些问题(例如中心的四舍五入)导致结果稍微不正确。下面提供了一个完整的示例

% Create an image of circles
radii = linspace(0, 40, 10);

rows = 100;
cols = 100;
img = zeros(rows, cols);

for k = 1:numel(radii)
    t = linspace(0, 2*pi, 1000);
    xx = round((cos(t) * radii(k)) + (cols / 2));
    yy = round((sin(t) * radii(k)) + (rows / 2));

    toremove = xx > cols | xx < 1 | yy > rows | yy < 1;

    inds = sub2ind(size(img), xx(~toremove), yy(~toremove));

    img(inds) = 1;
end

[r,c] = size(img);
center_row = r / 2;
center_col = c / 2;

[X,Y] = meshgrid((1:c) - center_col, (1:r) - center_row);

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

rhoRange = linspace(0, max(rho(:)), 1000);
thetaRange = linspace(-pi, pi, 1000);

[T, R] = meshgrid(thetaRange, rhoRange);

theta_rho_image = griddata(theta, rho, double(img), T, R);

figure
subplot(1,2,1);
imshow(img);
title('Original Image')

subplot(1,2,2);
imshow(theta_rho_image);
title('Polar Image')

结果