Отображение текстур в MATLAB
У меня есть точки в трехмерном пространстве и соответствующие им точки 2D-изображения. Как я могу сделать сетку из трехмерных точек, а затем текстурировать треугольные грани, образованные сеткой?
2 ответа
Обратите внимание, что функция trisurf
то, что вы изначально пытались использовать, возвращает дескриптор объекта патча. Если вы посмотрите на 'FaceColor'
свойство для объектов патча, вы можете увидеть, что нет 'texturemap'
вариант. Эта опция действительна только для 'FaceColor'
свойство поверхностных объектов. Поэтому вам нужно будет найти способ построить вашу треугольную поверхность как объект поверхности, а не как патч- объект. Вот два способа приблизиться к этому:
Если ваши данные находятся в единой сетке...
Если координаты ваших данных поверхности представляют собой единую сетку, такую что z
является прямоугольным набором точек, которые охватывают xmin
в xmax
по оси х и 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. Это привело к следующей поверхности с текстурой:
Если ваши данные расположены неравномерно...
Если ваши данные не располагаются регулярно, вы можете создать набор регулярно расположенных интервалов X
а также Y
координаты (как я делал выше, используя meshgrid
), а затем использовать одну из функций griddata
или же TriScatteredInterp
интерполировать регулярную сетку Z
значения из вашего нерегулярного набора 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
В этом случае вы должны сначала выбрать значения 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
Это привело к следующей поверхности с текстурой:
Обратите внимание, что рядом с углами поверхности имеются зубчатые края. Это места, где было слишком мало очков для TriScatteredInterp
адекватно подогнать интерполированную поверхность. Z
поэтому значения в этих точках nan
, в результате чего точка поверхности не отображается.
Если ваша текстура уже имеет правильную геометрию, вы можете просто использовать обычное наложение старой текстуры.
Ссылка на документацию MathWorks по наложению текстур: http://www.mathworks.com/access/helpdesk/help/techdoc/visualize/f0-18164.html
РЕДАКТИРОВАТЬ: немного обновил код:
Попробуйте этот подход (я только получил его на работу).
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), которые находятся на поверхности. Обратите внимание, что изображение растягивается, чтобы соответствовать поверхности.