Отображение текстур в MATLAB - PullRequest
10 голосов
/ 21 марта 2010

У меня есть точки в трехмерном пространстве и соответствующие им точки 2D-изображения. Как сделать сетку из трехмерных точек, а затем текстурировать грани треугольника, образованные сеткой?

Ответы [ 2 ]

5 голосов
/ 21 марта 2010

Обратите внимание, что функция trisurf, которую вы изначально пытались использовать, возвращает дескриптор объекта patch .Если вы посмотрите на свойство 'FaceColor' для объектов исправлений , вы увидите, что опция 'texturemap' отсутствует.Эта опция действительна только для свойства 'FaceColor' поверхность объекты .Поэтому вам нужно будет найти способ построить вашу треугольную поверхность как объект поверхность вместо объекта patch .Вот два способа приблизиться к этому:

Если ваши данные находятся в однородной сетке ...

Если координаты ваших данных поверхности представляют однородную сетку, такую, что z является прямоугольнойнабор точек, которые охватывают от xmin до xmax по оси X и ymin до ymax по оси Y, вы можете построить его, используя surf вместо trisurf:

Z = ...  % N-by-M matrix of data
x = linspace(xmin, xmax, size(Z, 2));  % x-coordinates for columns of Z
y = linspace(ymin, ymax, size(Z, 1));  % y-coordinates for rows of Z
[X, Y] = meshgrid(x, y);               % Create meshes for x and y
C = imread('image1.jpg');              % Load RGB image
h = surf(X, Y, Z, flipdim(C, 1), ...   % Plot surface (flips rows of C, if needed)
         'FaceColor', 'texturemap', ...
         'EdgeColor', 'none');
axis equal

Чтобы проиллюстрировать результаты вышеприведенного кода, я инициализировал данные как Z = peaks;, использовал встроенный образец изображения 'peppers.png' и установилзначения x и y в диапазоне от 1 до 16. Это привело к следующей поверхности с текстурой:

enter image description here

Если ваши данныенеравномерно разнесены ...

Если ваши данные не разнесены регулярно, вы можете создать набор равномерно разнесенных X и Y координат (как я делал выше, используя meshgrid), а затем используйте одну из функций griddata или TriScatteredInterp для интерполяции регулярной сетки значений Z от yoВаш неправильный набор значений z.Я обсуждаю, как использовать эти две функции в моем ответе на другой вопрос SO .Вот улучшенная версия кода, который вы разместили, используя TriScatteredInterp (Примечание: с R2013a scatteredInterpolant является рекомендуемой альтернативой):

x = ...  % Scattered x data
y = ...  % Scattered y data
z = ...  % Scattered z data
xmin = min(x);
xmax = max(x);
ymin = min(y);
ymax = max(y);
F = TriScatteredInterp(x(:), y(:), z(:));  % Create interpolant
N = 50;  % Number of y values in uniform grid
M = 50;  % Number of x values in uniform grid
xu = linspace(xmin, xmax, M);         % Uniform x-coordinates
yu = linspace(ymin, ymax, N);         % Uniform y-coordinates
[X, Y] = meshgrid(xu, yu);            % Create meshes for xu and yu
Z = F(X, Y);                          % Evaluate interpolant (N-by-M matrix)
C = imread('image1.jpg');             % Load RGB image
h = surf(X, Y, Z, flipdim(C, 1), ...  % Plot surface
         'FaceColor', 'texturemap', ...
         'EdgeColor', 'none');
axis equal

В этом случае вам необходимо first выберите значения N и M для размера вашей матрицы Z.Чтобы проиллюстрировать результаты вышеприведенного кода, я инициализировал данные для x, y и z следующим образом и использовал встроенный пример изображения 'peppers.png':

x = rand(1, 100)-0.5;  % 100 random values in the range -0.5 to 0.5
y = rand(1, 100)-0.5;  % 100 random values in the range -0.5 to 0.5
z = exp(-(x.^2+y.^2)./0.125);  % Values from a 2-D Gaussian distribution

Это привело к следующей текстурной поверхности:

enter image description here

Обратите внимание, что рядом с углами поверхности имеются зубчатые края.В этих местах было слишком мало точек для TriScatteredInterp, чтобы адекватно соответствовать интерполированной поверхности.Поэтому значения Z в этих точках равны nan, в результате чего точка поверхности не отображается.

1 голос
/ 21 марта 2010

Если ваша текстура уже имеет правильную геометрию, вы можете просто использовать обычное наложение старой текстуры.

Ссылка на документацию MathWorks по текстурному наложению: http://www.mathworks.com/access/helpdesk/help/techdoc/visualize/f0-18164.html#f0-9250

Пересмотр: немного обновил код:

Попробуйте этот подход (я только получил его на работу).

 a=imread('image.jpg');
 b=double(a)/255;

 [x,y,z]=peaks(30);  %# This is a surface maker that you do have
                     %# The matrix [x,y,z] is the representation of the surface.

 surf(x,y,z,b,'FaceColor','texturemap')  %# Try this with any image and you 
                                         %# should see a pretty explanatory 
                                         %# result. (Just copy and paste) ;)

Итак, [x, y, z] - это «поверхность» или, скорее, матрица, содержащая количество точек в форме (x, y, z), которые находятся на поверхности. Обратите внимание, что изображение растягивается, чтобы соответствовать поверхности.

...