2017-10-02 1 views
1

일부 높이 데이터를 3D 뷰의 일부 강도 데이터로 오버레이하고 싶습니다. 2D에서 쉽습니다 (아래 코드에서 생성 된 첫 번째 이미지 참조). 그러나 3D에서는 표현이 다소 이상하게 보입니다. 아래 예제에서 두 번째 및 세 번째 이미지를 참조하십시오. 나는 rgb 이미지의 점들이보다 "단색"으로 보이길 원합니다.Matlab : 투명 텍스처로 3D 표면 오버레이

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: looks fine, but 2D only. center: a lot of gaps in the intensity image. right: right: the surface underneath looks weird.

업데이트 : 시스템 정보 :

OS : 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 
+0

(나쁜) 수치를 재현 할 수 없습니다. OS, matlab 버전, OpenGL 버전을 지정할 수 있습니까? OpenGL 문제인지 확인하려면'opengl software '를 사용하여 소프트웨어 렌더링으로 전환 해보십시오. – m7913d

+0

업데이트에 시스템 데이터를 추가했습니다. 소프트웨어 렌더링을 사용하면 중앙 이미지가 조금 더 멋지게 보이지만 회전시킬 때 여전히 간격이 있습니다. –

+0

원하는 결과입니까? https://imgur.com/a/cFdxh? – m7913d

답변

3

좋아 수세 리눅스, 리눅스에서 렌더링 몇 가지 문제가있는 것 같습니다 또는 적어도 내 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; 

이 예상 결과를 얻을 수 enter image description here