How do I display a surf of an image in MATLAB? - matlab

I have an image that shows depth of the image using colors where warmer colors represent the closer parts of the image and cooler colors represent objects further away. I want to represent this image as a surf plot showing the depth. I have to do this in java but I think its easier to understand the process in Matlab first before moving on. I tried using the size of the image and plotting that but it kept giving me errors. Any help would be much appreciated.
I tried the surf function:
`img = imread('sample.png');
grayImage = rgb2gray(img);
surf(double(img))`
and got this error:
>> surf
Attempt to execute SCRIPT surf as a function:
C:\Users\kuchin\Documents\MATLAB\surf.m
Error in surf (line 3)
surf(double(img))

EDIT
As seen in your comment in this own post, your problem is that you are overriding the surf function by another surf.m file you have. Dont name your matlab files with the same name that Matlab built functions. Go to C:\Users\kuchin\Documents\MATLAB\surf.m and name it mysurf.m. It will resolve your problem.
ORIGINAL POST
If you have a depth image (MxN) of doubles just
surf(img);
if they are uint8
surf(double(img));
Will do the trick.
Test code:
img=imread( 'coins.png' );
surf(double(img))
Outputs:

Related

Scramble the pixels of black and white images in Matlab

I have a series of black and white images (not greyscale, black and white; 2D matrices in Matlab), and I need to randomly scramble the pixels. I found this package in Mathworks File Exchange (https://it.mathworks.com/matlabcentral/fileexchange/66472-image-shuffle); one of the functions, imScrambleRand, does exactly what I need, but it works for RGB images (3D matrices). Is there a way to transform b&w images into 3D matrices so that I can use that function? Or can anyone suggest any other script that does what I need? Keep in mind that I'm not familiar with Matlab, but I'll do my best.
Thank you.
EDIT 1: When I import the BW image I get a 2D matrix of logic values (0 = black, 1 = white). I think the different data format (logic vs integer) is what yields errors when using the function for RGB images.
EDIT 2: I adapted the demo code from the aforementioned package and I used the suggestion by #Jonathan for transforming a 2D matrix into a 3D matrix, and added a loop to transform the logic values into RGB integer values, then use the imScrambleRand function. It works, but what I obtain is the following image: SCRAMBLED IMAGE. This is the BW picture I start with: BW IMAGE. So I checked the scrambled image, and the function from the FEX file actually scrambles within the RGB values, meaning that I found, for instance, a pixel with RGB 0,255,0. So I solved a problem but actually there's a problem within the function: it doesn't scramble pixels, it scrambles values generating colors that were not in the original picture.
EDIT 3: I used the code provided by #nhowe and I obtain exactly what I need, thanks!
EDIT 4: Ok, turns out it's not ok to scramble the pixels since it makes the image too scattered and different from the starting image (you don't say?), but I need to scramble BLOCKS OF PIXELS so that you can't really recognize the image but the black pixels are not too scattered. Is there a way to do that using the code provided by #nhowe?
EDIT 5: It should be ok with this function: https://it.mathworks.com/matlabcentral/fileexchange/56160-hio-been-hb-imagescramble
A simple way to scramble matrix M:
r = rand(size(M));
[~,ri] = sort(r(:));
M(ri) = M;
The simplest solution to go from grayscale to RGB might be this:
rgbImage = cat(3, grayImage, grayImage, grayImage);
Then apply your function from FEX and extract one color channel, assuming that the FEX function will yield three identical color channels.

Rectify images of different sizes

I wanted to rectify a stereo image pair coming from two different modalities (visual and thermal). I calibrated both cameras using
[cameraParams,imagesUsed,estimationErrors] = estimateCameraParameters(imagePoints,worldPoints);
giving me a stereoParameter object, since imagePoints contains matching checkerboard points for both modalities.
To rectify, I used the following call:
[J1,J2] = rectifyStereoImages(I1,I2, cameraParamsStereo);
where I1 is a visual image and I2 a thermal one. Unfortunately, that gives me the error:
Error using rectifyStereoImages>parseInputs (line 106) Inputs must be
of the same size and data types.
Error in rectifyStereoImages (line 96) [I1, I2, interp, outputView,
fillValues] = parseInputs(...
The resolutions of both images are quite different (2048x1088 for visual, 384x288 for thermal). From my undertanding however, rectification in principle should still work, since it is done similarly in this paper. Honestly however, I am not sure how...
Question:
Is there a way in MATLAB to rectify images of different sizes? If not, is there an algorithm to do so that can be easily implemented?
Unfortunately, the rectifyStereoImages function requires the two images to have the same size. This is a limitation of the implementation, not the algorithm.
One thing you can do is undistort the images using the undistortImage function, find matching points (e.g. using matchFeatures), and then use the triangulate function to get a sparse 3-D reconstruction.
You can also try making the two images the same size, by padding the smaller image with zeros. You would need to pad the calibration images before calibration, so that everything is consistent.

Exporting 3D image from Matlab to u3D or any other 3D format

I have a question regarding the exportation of a 3D image made in Matlab to any other 3D format (u3D, collada, Fbx).
I have a stack of images (ct images) and I used the isosurface method in Matlab in order to obtain the 3D volume rendering.
The code is as follows:
p_bone=patch(isosurface(volume_gabbia,0));%create isosurface patch
isonormals(volume_gabbia,p_bone)%compute and set normals
set(p_bone,'FaceColor','m','EdgeColor','none')%set surface props
daspect([1 1 1])
view(3), axis vis3d tight, box on, grid on
camproj perspective
camlight, lighting phong, alpha(.2)
volume_gabbia is a stack of images which contains only the ribcage.
The result is an image (.fig) volume that I can rotate, move, ecc...
Now I need to export this 3D volume in a 3D file (u3D r similar).
I've tried to use the Fig2u3d file (http://it.mathworks.com/matlabcentral/fileexchange/37640-export-figure-to-3d-interactive-pdf) but I get the following error:
fig2u3d No surfaces found.
Preprocessing patch No.1 Undefined function 'ddisp' for input arguments of type 'char'.
Error in u3d_pre_patch>single_patch_preprocessor (line 115)
ddisp('Patch: Fixing face color')
Error in u3d_pre_patch (line 70)
[v, f, fvx, r] = single_patch_preprocessor(h);
Error in fig2u3d (line 195) [patch_vertices, patch_faces,
patch_facevertexcdata, patch_renderers] = u3d_pre_patch(ax);
Does anyone know how can I export a 3D image from Matlab?
Try exporting as .stl (look at file exchange), it is much better supported. Then convert to u3d with meshlab.
I unintendedly introduced the call to the function ddisp during maintenance.
The function ddisp is a local convenience wrapper for disp that was used to filter debug output globally (in absence of any proper logging infrastructure in matlab).
Fixed as of commit e15999. Thanks for reporting it.

Save Spectrogram as an Image in MATLAB

I'm analyzing some sound clips using the spectrogram() function in MATLAB. I would like to save the spectrogram as an image (jpg, png, etc). But regardless of what image format I save the figure in, the resulting image always looks different ("spotty") from what I see in the figure.
Here's an example of the spectrograms: Matlab Figure vs. Saved Image
All I want is to save exactly what I see in the figure as an image. I've already tried saving the figure in all the image formats possible but all of them are producing the same "spotting" effect. I've also tried both manual saving (click on file -> save as) and programmatically using the print() and the saveas() functions. Same result every time.
Any help would be appreciated!
What is the data range of your spectrogram?
One of reasons might be that your spectrogram range is out of the [0,1] region for double images or [0,255] for uint* images (your white spots on saved image are suspiciously close to the local minima on MatLab figure).
Another guess might be that you are using imwrite function, in particular its imwrite(X,map,filename,fmt) syntax. MatLab documentation explains:
imwrite(X,map,filename,fmt) writes the indexed image in X and its associated colormap map to filename in the format specified by fmt. If X is of class uint8 or uint16, imwrite writes the actual values in the array to the file. If X is of class double, imwrite offsets the values in the array before writing, using uint8(X–1). map must be a valid MATLAB colormap. Note that most image file formats do not support colormaps with more than 256 entries.
so the uint8(X–1) might be the source of the white spots.
Though have no idea why they appear after print()'ing.
I found a work-around for this problem by using the pcolor() function, which is essentially a rotated surf() function plotted in a grid format (doc). After tinkering with the spectrogram() function more, I'm convinced that these "spotting" artifacts have nothing to do with the data format, property, or scale. The problem seems to lie in the way MATLAB plots and visualizes 3D plots. I tried plotting with the mesh() function as well and it produced a different kind of "spotting" effect. pcolor() works because it's a 2D visualization of a 3D plot.
This is how spectrogram() plots the image using surf() (adapted from the doc):
[S,T,F,P] = spectrogram(X,256,250,256,2000);
surf(T,F,abs(S),'EdgeColor','none');
axis tight; view(0,90);
... and this is how to use pcolor() to plot a save-friendly image:
[S,T,F,P] = spectrogram(X,256,250,256,2000);
h = pcolor(T,F,abs(S));
set(h,'EdgeColor','none');
The white spots are an OpenGL issue, which is the renderer used in spectrogram()'s internal call to surf().
Since you are interested in plotting a 2D visualization, change the renderer for the current figure to zbuffer:
set(gcf, 'renderer', 'zbuffer');
where gcf means "get current figure". The white spots are now gone.
Note that you can also select the zbuffer renderer when you create the figure, before calling spectrogram():
myNewFig = figure('renderer','zbuffer');

imshow() produces different output to imwrite()

I was wondering how it is possible to save an image created by imshow() in matlab. The code below uses the imshow() function with the min and max arguments specified - How can I apply this directly to the image itself instead of just specifying Matlab to show it?
imshow(img4fft, [1 300000]);
imwrite(img4fft, 'img.png');
Writing to the file produces a different output to what is shown via imshow().
Can anyone suggest how to get the output from imshow() saved as an image?
Many thanks MatLab is an alien language to me!
I obtain the same result by doing:
img4fft2=min(double(img4fft),300000)/300000;
imwrite(img4fft2,'img.png');
You could apply saturation to the image manually:
I2 = imadjust(I, [0,30000],[0,2^{resolution}-1]);
imwrite('out.png', I2);