0

I have a heat map

enter image description here

and want to convert this 2D matrix to a 3D volume/shape/surface data points for further processing. Not simply display it in 3D using surf.

What would be a good way to do this?

With a lot of help from this community I could come closer:

I shrunk the size to 45x45 px for simplicity.

I = (imread("TESTGREYPLASTIC.bmp"))./2+125;
Iinv = 255-(imread("TESTGREYPLASTIC.bmp"))./2-80;%

for i = 1:45
for j = 1:45
A(i, j, I(i,j) ) = 1;
A(i, j, Iinv(i,j) ) = 1;
end
end
volshow(A)

Its not ideal but the matrix is what I wanted now. Maybe the loop can be improved to run faster when dealing with 1200x1200 points.

enter image description here

How do I create a real closed surface now?

Adriaan
  • 17,741
  • 7
  • 42
  • 75
nolimits
  • 43
  • 1
  • 3
  • 16
  • I strongly suggest to ask different questions for different issues. That's the way SO works, and you will get better results doing it. For your performance issue, read my answer again. All you need is different indices along 3-rd dimension. You keep them in a new variable and let the `sub2ind` do the rest for you. – saastn Oct 07 '20 at 12:14
  • The disconnection between neighboring voxels comes directly from your data. This occurs when two neighboring pixels in the original image differ by more than one level in intensity. You can reduce it using smoothing filters, but this is not something that can be completely removed in a discrete data. – saastn Oct 07 '20 at 12:15

2 Answers2

3

The contour plot that is shown can't be generated with "2D" data. It requires three inputs as follows:

[XGrid,YGrid] = meshgrid(-4:.1:4,-4:.1:4);
C = peaks(XGrid,YGrid);

contourf(XGrid,YGrid,C,'LevelStep',0.1,'LineStyle','none')
colormap('gray')
axis equal

Where XGrid, YGrid and C are all NxN matrices defining the X values, Y values and Z values for every point, respectively.

Contour Plot

If you want this to be "3D", simply use surf:

surf(XGrid,YGrid,C)

Surface Plot

BoilermakerRV
  • 299
  • 1
  • 8
  • Thanks, much appreciated your response. I know I can display it in 3D using "surf" but I require real volumetric data points out of the 2D map for further processing. Basically, convert the greyscale to a third dimension? – nolimits Oct 07 '20 at 00:27
  • Are you saying you don't have the original data? If you can't get it or re-create it, you're going to be stuck doing some kind of image processing on the contour plot that you have. – BoilermakerRV Oct 07 '20 at 00:31
  • I do have the data. But its a 2D map, a X,Y matrix. I need to make it to a X, Y, Z matrix. Perhaps by converting the grey scales to the third Z dimension. I require a real 3D surface data points for further processing. – nolimits Oct 07 '20 at 00:33
  • There has to be another variable with the Z (i.e. greyscale) values. Can you see the line in code where the original contour plot was generated? – BoilermakerRV Oct 07 '20 at 00:38
  • It's an image as 2D mesh where each mesh point has a numerical 8 bit value. Thanks :) – nolimits Oct 07 '20 at 00:40
  • It sounds like your describing just the Z matrix. If we assume that X and Y are equally spaced and Z is an NxN matrix, then `[XGrid, YGrid] = meshgrid(linspace(0,1200,N),linspace(0,1200,N))` – BoilermakerRV Oct 07 '20 at 00:47
  • Yes, it is a 1200x1200 mesh where each point has an 8 Bit data. How do I convert this to a 1200x1200x256 mesh, where the 256 grey scales are just a surface now? – nolimits Oct 07 '20 at 01:05
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/222624/discussion-between-boilermakerrv-and-nolimits). – BoilermakerRV Oct 07 '20 at 01:07
3

Following your conversation with @BoilermakerRV, I guess you are looking for one of the following two results:

  1. A list of 3d points, where x and y are index of pixels in the image, and z is value of corresponding pixels. The result will be an m*n by 3 matrix.

  2. An m by n by 256 volume of zeros and ones, that for (i,j)-th pixel in the image, all voxels of the (i, j)-the pile of the volume are 0, except the one at I(i, j).

Take a look at the following example that generates both results:

    close all; clc; clear variables;
    I = rgb2gray(imread('data2.png'));
    imshow(I), title('Data as image') 

    % generating mesh grid
    [m, n] = size(I);
    [X, Y] = meshgrid(1:n, 1:m);

    % converting image to list of 3-d points
    P = [Y(:), X(:), I(:)];
    figure 
    scatter3(P(:, 1), P(:, 2), P(:, 3), 3, P(:, 3), '.')
    colormap jet
    title('Same data as a list of points in R^3')

    % converting image to 256 layers of voxels
    ind = sub2ind([m n 256], Y(:), X(:), I(:));
    V = zeros(m, n, 256);
    V(ind) = 1.0;
    figure
    h = slice(V, [250], [250], [71]) ;
    [h.EdgeColor] = deal('none');
    colormap winter
    camlight
    title('And finally, as a matrix of 0/1 voxels')

enter image description here

enter image description here

enter image description here

saastn
  • 5,717
  • 8
  • 47
  • 78
  • 1
    Good stuff @saastn! Did @nolimits provide the original image data somewhere, or did you extract it via some sort of image processing? I was struggling to understand what was being asked. I've never had to do anything quite like that. When the subject of volume was brought up, I was thinking about the volume under the surface. – BoilermakerRV Oct 07 '20 at 10:30
  • Wow, that's cool! @BoilermakerRV my data is that image :) – nolimits Oct 07 '20 at 10:55
  • Just checked it. I have trouble to add another (but different) one to the P matrix, to display two different images on one matrix. P appears still to be a 2D matrix and adding another P1+P2 adds up the numerical value for each point. – nolimits Oct 07 '20 at 11:21
  • I added some partial result from your appreciated suggestions in the original question. Please have a look :) – nolimits Oct 07 '20 at 11:42
  • 1
    @BoilermakerRV I just downloaded the image posted in the question and cropped out tick labels ;) And about the volume, "tomography" was the key. Like multiple MRI images of different levels of one's brain. – saastn Oct 07 '20 at 11:59
  • Thanks both!!! After fresh coffee next morning I understand your answer :) – nolimits Oct 07 '20 at 21:13
  • I'm glad it helped. – saastn Oct 07 '20 at 21:51