我有一个我认为对您来说更好的解决方案,涉及两个步骤。首先,它提取图像的矩形部分,其中一半是用作纹理贴图的三角形部分,一半将被忽略。然后,将此纹理贴图应用于 3D 表面对象,调整其点以将其渲染为三角形而不是四边形。
对于我将在这里展示的示例,我将为您的各种参数使用以下值,假设您有一个三角形,其点被标记为“原点”(三角形顶点)、点“A”和点“B”图像空间(如下第一张图所示):
x = [0.1 0.9 0.8]; % [xorigin xA xB] coordinates in 3-D space
y = [0.9 0.1 0.8]; % [yorigin yA yB] coordinates in 3-D space
z = [0.1 0.1 0.9]; % [zorigin zA zB] coordinates in 3-D space
origin = [150 350]; % Vertex of triangle in image space
U = [300 -50]; % Vector from origin to point A in image space
V = [50 -250]; % Vector from origin to point B in image space
img = imread('peppers.png'); % Sample image for texture map
通过投影变换提取纹理图:
此步骤使用图像处理工具箱 https://www.mathworks.com/help/images/index.html功能maketform https://www.mathworks.com/help/images/ref/maketform.html and imtransform https://www.mathworks.com/help/images/ref/imtransform.html对包含要用作纹理贴图的三角形的图像部分执行投影变换。请注意,由于图像必须是矩形,因此由点定义的附加三角形部分(O,B,C)
必须包括在内。
您想要的图像的三角形部分将位于图像的右下半部分,而附加的三角形“填充物”部分将位于左上角。请注意,这个额外的三角形可以延伸到图像之外,这将导致默认情况下部分图像被黑色填充。下面是执行上面所示的投影变换的代码:
A = origin+U; % Point A
B = origin+V; % Point B
C = B-U; % Point C
[nRows, nCols, nPages] = size(img); % Image dimensions
inputCorners = [origin; ... % Corner coordinates of input space
A; ...
B; ...
C];
outputCorners = [1 nRows; ... % Corner coordinates of output space
nCols nRows; ...
nCols 1; ...
1 1];
tform = maketform('projective', ... % Make the transformation structure
inputCorners, ...
outputCorners);
triTexture = imtransform(img,tform, 'bicubic', ... % Transform the image
'xdata', [1 nCols], ...
'ydata', [1 nRows], ...
'size', [nRows nCols]);
请注意,此代码将创建最终图像triTexture
与输入图像的大小相同img
.
绘制三角形纹理映射表面:
绘制曲面现在非常简单,假设您已对中的值进行了排序x,y,z
变量,使得原点的坐标在第一个索引中,A点的坐标在第二个索引中,B点的坐标在第三个索引中。您现在可以创建新的 2×2 曲面坐标集X,Y,Z
包含点 B 的两个副本,这会导致仅渲染表面的一半(即包含所需三角形图像作为纹理贴图的一半)。这是执行此操作的代码:
index = [3 3; 1 2]; % Index used to create 2-by-2 surface coordinates
X = x(index); % x coordinates of surface
Y = y(index); % y coordinates of surface
Z = z(index); % z coordinates of surface
hSurface = surf(X, Y, Z, triTexture, ... % Plot texture-mapped surface
'FaceColor', 'texturemap', ...
'EdgeColor', 'none');
axis equal % Use equal scaling on axes
axis([0 1 0 1 0 1]); % Set axes limits
xlabel('x-axis'); % x-axis label
ylabel('y-axis'); % y-axis label
zlabel('z-axis'); % z-axis label
这是它创建的结果纹理贴图三角形表面,添加了一个插图以显示纹理贴图包含原始图像的正确三角形部分: