[英]Matlab: Overlay a 3D surface with a transparent texture
I would like to overlay some height data with some intensity data in a 3D-view. 我想在3D视图中用一些强度数据覆盖一些高度数据。 It is easy in 2D (see the first image generated by the code below), but in 3D the representations look somewhat weird, see second and third image in the example below. 在2D中很容易(参见下面代码生成的第一个图像),但在3D中,表示看起来有些奇怪,请参见下面示例中的第二个和第三个图像。 I would like the dots in the rgb image look more "solid". 我希望rgb图像中的点看起来更“坚固”。
figure;
subplot(1,3,1);
% Get some data
[x,y,z] = peaks(128);
pos = (rand(2,5).*4)-2;
i = zeros(128,128);
for n = 1:5
i = i+exp(-((((x-pos(1,n))/.2).^2+(((y-pos(2,n)))/.2).^2)));
end
% Convert to uin16 since real data is uint16
i = i./max(i(:));
i = i * 2^16;
i = uint16(i);
i_rgb = ind2rgb(i, hot(2^16));
% Display data
% This is how it should look like in 3D
imagesc(z);
colormap(gray);
axis image;
hold on;
img = imshow(i_rgb);
img.AlphaData = i;
% now in 3D, here the texture looks strange
subplot(1,3,2);
s = surface(x,y,z);
s.EdgeColor = 'none';
axis ij tight equal off; colormap(gray);
hold on;
s2 = surface(x,y,z);
s2.EdgeColor = 'none';
s2.FaceColor = 'texturemap';
s2.CData = i_rgb;
s2.FaceAlpha = 'texturemap';
s2.AlphaData = i;
hold off;
% Again in 3D, but without FaceAlpha = 'texturemap';
% The intensity-dots look good, but the remaining area looks strange.
subplot(1,3,3);
s3 = surface(x,y,z);
s3.EdgeColor = 'none';
axis ij tight equal off; colormap(gray);
s4 = surface(x,y,z);
s4.EdgeColor = 'none';
s4.FaceColor = 'texturemap';
s4.CData = i_rgb;
s2.AlphaData = i;
Update : System information: 更新 :系统信息:
OS: SuSE Linux 42.1 操作系统:SuSE Linux 42.1
>> version
ans =
'9.2.0.538062 (R2017a)'
>> opengl info
Version: '4.5.0 NVIDIA 375.66'
Vendor: 'NVIDIA Corporation'
Renderer: 'Quadro K1000M/PCIe/SSE2'
MaxTextureSize: 16384
Visual: 'Visual 0x27, (RGBA 32 bits (8 8 8 8), Z depth 16 bits, Hardware acceleration, Double buffer, Antialias 8 samples)'
Software: 'false'
HardwareSupportLevel: 'full'
SupportsGraphicsSmoothing: 1
SupportsDepthPeelTransparency: 1
SupportsAlignVertexCenters: 1
Extensions: {330×1 cell}
MaxFrameBufferSize: 16384
Okay, it seems that there is some problem with the rendering under linux or at least my opengl version. 好吧,似乎linux下的渲染或者至少我的opengl版本存在一些问题。 There is a workaround that solves the problem for me: Instead of using a texture with transparency, I combine the height and intensity data to an rgb-image and use this as the texture: 有一种解决方法可以解决我的问题:我没有使用具有透明度的纹理,而是将高度和强度数据组合到rgb图像中并将其用作纹理:
figure;
% Get some data
[x,y,z] = peaks(128);
pos = (rand(2,5).*4)-2;
i = zeros(128,128);
for n = 1:5
i = i+exp(-((((x-pos(1,n))/.2).^2+(((y-pos(2,n)))/.2).^2)));
end
% Convert to uin16 since real data is uint16
i = i./max(i(:));
i = i * 2^16;
i = uint16(i);
% Do the same with the z-data
z_idx = z - min(z(:));
z_idx = z_idx / max(z_idx(:));
z_idx = uint16(2^16 * z_idx );
i_rgb = ind2rgb(i, hot(2^16));
z_rgb = ind2rgb(z_idx, gray(2^16));
% merge the images using i as alpha values.
alphas = double(i)/2^16;
alphas_inv = ones(size(alphas)) - alphas;
% Display data
merged_rgb = zeros(size(i,1), size(i,2), 3);
for channel = 1:3
merged_rgb(:,:,channel) = z_rgb(:,:,channel).*alphas_inv + i_rgb(:,:,channel) .* alphas;
end
s = surface(x,y,z);
s.EdgeColor = 'none';
s.FaceColor='texturemap';
s.CData = merged_rgb;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.