The idea of an image is quite different when you try to perceive it as a matrix, especially if you twist some things around. So what does an image look like if you perceive it as a matrix with the RGB value as a z-axis while keeping the x- and y-axes ? How can you produce a 3D representation of a 2D image? Something similar to the below?

The idea of producing a 3D image from a 2D image steamed from a need of analysing and validating the roughness in microscope 2D images. My reasoning was that it had to be easier to analyse an image in three dimensions, compared to two dimensions. In hindsight I should have realised that for my purpose I was utterly wrong…

After some programming in MATLAB/Octave I had achieved my script that converts 2D images to 3D, and I had my output. However, the data you get when inserting a grey-scale image and converting it to 3D is quite overwhelming. You actually don’t get any more information out of it due to the large variation in a small grey-coloured interval. And a simple filtering didn’t really clear up the image either. The result was clearly not helpful.

2D and 3D representations of microscope images

So, what do you do with some code that is more or less useless? Well, you have some fun with it. It also became apparent that whilst visualisation in grey-scale wasn’t optimal, visualisations in colour was quite interesting. Here you can see some images, with and without filtering

Without filtering

With filtering

The big downside of the script, as well as with MATLAB/Octave in general, is the exportation to a suitable format. Is it possible to export the result to a Wavefront object file? Yes, primarily due to the important checking that the axes are of similar dimensions/values. The representation is however in black and white. Since this hasn’t any real purpose, other than some fun scripting, I will leave it here (for now).

% This script transforms a 2D RGB image to a 3D image, where the Z axis is given by the RGB number.
% For the beginner:
% 1. Save the script as 'script_2Dimage_to_3D.m'
% 2. Run the script via run 'script_2Dimage_to_3D.m'
% 3. Insert path to image you want to analyse.
% Alex Björkholm 2016
pkg load image  % Note that this needs to be commented out in MATLAB

% Load image from input
prompt = 'Enter path to image to be processed: ';
str = input(prompt,'s');
rgb_image = imread(str);
fprintf('Analysing image "%s"\n',str);

% Filtering yes/no
prompt = 'Apply filtering (yes/no): ';
yes_no = input(prompt,'s');

% Filtering
if strcmp(yes_no, 'yes')
   printf('\nApplying filter\n');
   f = ones(5) * 1/25;
   rgb_filter = imfilter(rgb_image, f, "symmetric";);
   rgbim = rgb_filter;

   figure;
   subplot ( 1, 2, 1), imshow ( rgb_image ), title('unfiltered');
   subplot ( 1, 2, 2), imshow ( rgb_filter ), title('filtered');

else
   fprintf('\nNo filter applied\n');
   rgbim = rgb_image;

end

% Converting image format and getting colormap
[C,map] = rgb2ind(rgbim);

% Setting X,Y dimensions, where X and Y has the same dimensions.
[X,Y] = meshgrid(-floor(size(rgbim, 2)/2):floor(size(rgbim, 2)/2)-1, -floor(size(rgbim, 1)/2):floor(size(rgbim, 1)/2)-1);

% Dimensions X and Y must be the same as C. This can be accomplished by adjusting the meshgrid. Automatically done below.
i = 0;
j = 0;
while ( size(X)(1) ~= size(C)(1) ) % While dimensions of x different for X and C, Note X == Y.
   i++;
   [X,Y] = meshgrid(-floor(size(rgbim, 2)/2):floor(size(rgbim, 2)/2) + 10 - j, -floor(size(rgbim, 1)/2):floor(size(rgbim, 1)/2) + 10 - i);
end

while ( size(X)(2) ~= size(C)(2) ) % While dimensions of x different for X and C, Note X == Y.
   j++;
   [X,Y] = meshgrid(-floor(size(rgbim, 2)/2):floor(size(rgbim, 2)/2) + 10 - j, -floor(size(rgbim, 1)/2):floor(size(rgbim, 1)/2) + 10 - i);
end

% If error persists, print array dimensions of X, Y, and C
XC = isequal(size(X),size(C));
YC = isequal(size(Y),size(C));
if XC ~= 1 || YC ~= 1
   fprintf('size(X):   %i   %i\n', size(X)(1), size(X)(2));
   fprintf('size(Y):   %i   %i\n', size(Y)(1), size(Y)(2));
   fprintf('size(C):   %i   %i\n', size(C)(1), size(C)(2));
end

% Setting a reasonable restriction on the Z (C) axis, which in turn enables the exportation of a reasonable 3D object
k = max(C(:)) / max(X(:));
[Z] = double(C/k);

% Setting 3D figure output
figure;
surf(X, Y, Z, double(C)), shading flat;
colormap(map); % This command returns the original image colour

Advertisements