Поверните изображение по осям X, Y и Z в Matlab

Я пытаюсь повернуть изображение по трем осям в Matlab. Я использовал функцию rotx, roty, rotz для создания матрицы вращения, но я не знаю, как ее использовать. Рассматривают ли эти методы центральную точку в качестве источника?


person David Clifte    schedule 30.08.2015    source источник
comment
Я читал документацию, не обращая внимания. Я не знаю, как применить в обработке изображений! Изображение не является вектором 3 на N.   -  person David Clifte    schedule 30.08.2015
comment
rotx, roty и rotz являются частью Mapping Toolbox.... так что не полагайтесь на них, чтобы получить ответ. Однако, когда вы вращаете изображение, это 2D-проекция, поэтому одна из 3D-осей должна быть установлена ​​на ноль... так что в этом случае изображение будет на плоскости z = 0? Это важно, прежде чем я напишу ответ.   -  person rayryeng    schedule 30.08.2015
comment
@rayryeng Я думаю, вы могли бы так предположить и дать такой ответ - в любом случае это было бы недалеко.   -  person anon01    schedule 31.08.2015
comment
@anon0909 - Конечно. Это интересный вопрос, и я испытываю желание ответить на него, но видя, что уже есть 4 близких голоса, это немного обескураживает.   -  person rayryeng    schedule 31.08.2015
comment
@rayryeng Наверное, я их еще не вижу :)   -  person anon01    schedule 31.08.2015
comment
@anon0909 - Ой :) Извини, лол. На самом деле... позвольте мне написать ответ. Это не будет выглядеть особо, так как изображение будет на плоскости z = 0, но что, черт возьми, верно?   -  person rayryeng    schedule 31.08.2015
comment
@ anon0909 - посмотри на мой ответ.   -  person rayryeng    schedule 31.08.2015


Ответы (1)


Поскольку изображение представляет собой 2D-проекцию из 3D-мира, для одной из 3D-плоскостей необходимо установить значение 0, если вы хотите, чтобы это работало. Я собираюсь предположить, что плоскость z равна 0, поэтому изображение лежит плоско на плоскости z = 0.

По сути... что-то вроде этого, используя изображение cameraman.tif. Вот как это выглядит изначально:

введите описание изображения здесь

Вот как это выглядит в 3D. Во-первых, загрузите изображение, сгенерируйте (x,y) пары для каждой интенсивности в изображении. Это делается с помощью meshgrid. Как только вы это сделаете, используйте scatter для построения каждой точки, предполагая z = 0, и сделайте цвет каждой точки фактической интенсивностью, наблюдаемой в координате изображения. Однако вы увидите это только в 2D-перспективе, так как scatter естественно 2D. Чтобы сделать это 3D, измените вид камеры так, чтобы вы смотрели на изображение с 3D-представлением MATLAB по умолчанию, затем добавьте некоторые элементы, такие как метки и сетку, а также поменяйте местами координату y, поскольку координаты y для изображений положительны. вниз:

%// Load in the image
im = imread('cameraman.tif');

%// Generate coordinates and unravel into a single vector
[X,Y] = meshgrid(1:size(im,2), 1:size(im,1));
x_coord = X(:); y_coord = Y(:);

%// Plot the image as a scatter plot
scatter(x_coord, y_coord, 2, repmat(double(im(:)), 1, 3)/255);
view(3); grid; xlabel('Columns'); ylabel('Rows');
axis ij

Мы получаем это:

введите описание изображения здесь

Однако это относится только к изображениям в градациях серого. Если вы хотите сделать то же самое с цветом, вам нужно изменить способ указания цвета каждой точки. Это просто сделать, извлекая красную, зеленую и синюю плоскости и помещая их в один столбец в цветовой матрице в качестве четвертого аргумента. В частности, команда scatter теперь выглядит так:

red = reshape(im(:,:,1), [], 1);
green = reshape(im(:,:,2), [], 1);
blue = reshape(im(:,:,3), [], 1);
scatter(x_coord, y_coord, 2, double([red green blue])/255);

Итак, теперь у нас есть это, что вам просто нужно сделать, это взять координаты X и Y, которые были сгенерированы на предыдущем шаге, и повернуть каждую из них с помощью матрицы вращения. Имейте в виду, что координата Z состоит из нулей.

Существует матрица вращения, определенная относительно каждой оси, с которой вы хотите вращать точки. Матрица вращения для каждой оси показана ниже:

Источник: Википедия

Таким образом, нужно просто взять распутанные координаты выше, применить их к матрице вращения, а затем использовать эти новые координаты и нанести точки на график. Имейте в виду, что для координат изображения ось y является положительной, направленной вниз, поэтому вращение по часовой стрелке соответствует положительным углам, а вращение против часовой стрелки — отрицательным углам.

Чтобы повернуть 3D-точку, предполагая, что начало координат находится на (x,y,z) = (0,0,0) (что также и в нашем случае), это просто умножение матриц:

Pout = R*P;

P — это вектор 3 x 1 из (x,y,z) точек, а Pout — выходной вектор (также 3 x 1), который вращается. Поэтому, если вы хотите сделать это для всех наших точек, вам нужно преобразовать P в матрицу 3 x N, где N — общее количество пикселей в изображении, применить R*P, а затем использовать полученные точки в качестве входных данных в scatter.

Мы можем показать, что происходит, когда мы вращаем каждую ось независимо.

x-ось

Сначала создайте матрицу поворота для оси x для заданного угла поворота theta:

theta = pi/3; %// 60 degree rotation for example
Rx = [1 0 0; 0 cos(theta) -sin(theta); 0 sin(theta) cos(theta)];

Теперь, когда вы закончили, поверните точки:

Pout = Rx*[x_coord.'; y_coord.'; zeros(1,numel(x_coord))];

Как только вы закончите, позвоните scatter с этими новыми точками. Вместо этого я вызову scatter3, так как он предназначен для 3D-точек, и мне также нужно будет повернуть камеру, чтобы все было правильно видно:

scatter3(Pout(1,:), Pout(2,:), Pout(3,:), 2, repmat(double(im(:)), 1, 3)/255);
axis ij; xlabel('Columns'); ylabel('Rows');
view(-105, 35);

Если у вас есть цветные изображения, убедитесь, что вы изменили четвертый аргумент на то, о чем я говорил в начале этого поста.

Мы получаем это:

введите описание изображения здесь

Ось x здесь представляет собой столбцы, и вращение подобно воображению книги, лежащей плоско на плоскости z = 0 и открывающей страницу из книги. Стержнем книги будет ось x или столбцы.

y-ось

Вы делаете то же самое, но с другой матрицей вращения. Однако, чтобы дать вам лучшую перспективу вращения таким образом, мне нужно немного изменить угол камеры:

theta = pi/3; %// 60 degree rotation for example
Ry = [cos(theta) 0 sin(theta); 0 1 0; -sin(theta) 0 cos(theta)];
Pout = Ry*[x_coord.'; y_coord.'; zeros(1,numel(x_coord))];
scatter3(Pout(1,:), Pout(2,:), Pout(3,:), 2, repmat(double(im(:)), 1, 3)/255);
axis ij; xlabel('Columns'); ylabel('Rows');
view(5,30); %// Change camera angle so that you're looking at the x plane better

Вот что мы получаем:

введите описание изображения здесь

Тот же эффект, но ось вращения изменилась. Корешок книги теперь расположен по строкам, а не по столбцам.

z-ось

Этот довольно доброкачественный. Это должно иметь эффект вращения листа бумаги на столе без возвышения:

theta = pi/3; %// 60 degree rotation for example
Rz = [cos(theta) -sin(theta) 0; sin(theta) cos(theta) 0; 0 0 1];
Pout = Rz*[x_coord.'; y_coord.'; zeros(1,numel(x_coord))];
scatter3(Pout(1,:), Pout(2,:), Pout(3,:), 2, repmat(double(im(:)), 1, 3)/255);
axis ij; xlabel('Columns'); ylabel('Rows');

.... и:

введите описание изображения здесь


Надеюсь, этого будет более чем достаточно для начала. Удачи!

person rayryeng    schedule 31.08.2015
comment
Это очень хороший ответ - person Stewie Griffin; 31.08.2015
comment
@StewieGriffin - Ха-ха, спасибо :) - person rayryeng; 31.08.2015
comment
Я сделал, это работает. Вы просто забыли поговорить о переводе, который я должен был сделать, но это была самая легкая часть. Поскольку мне нужно окончательное изображение, в конце концов мне пришлось использовать Pout в качестве индекса из исходного изображения, чтобы восстановить новый. Если индекс выходит за пределы, я добавляю ноль. - person David Clifte; 01.09.2015
comment
@DavidClifte В вашем посте было не очень ясно. Вы только хотели знать, как вращать изображения, и я показал вам это довольно хорошо, но не говорил о том, как на самом деле создать изображение в конце. Как говорится, я рад, что вы это поняли! - person rayryeng; 01.09.2015