簡體   English   中英

Matlab:用透明紋理覆蓋3D表面

[英]Matlab: Overlay a 3D surface with a transparent texture

我想在3D視圖中用一些強度數據覆蓋一些高度數據。 在2D中很容易(參見下面代碼生成的第一個圖像),但在3D中,表示看起來有些奇怪,請參見下面示例中的第二個和第三個圖像。 我希望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;

left:看起來很好,但只有2D。中心:強度圖像中有很多間隙。右:右:下面的表面看起來很怪異。

更新 :系統信息:

操作系統: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

好吧,似乎linux下的渲染或者至少我的opengl版本存在一些問題。 有一種解決方法可以解決我的問題:我沒有使用具有透明度的紋理,而是將高度和強度數據組合到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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM