I'm trying to import data from a .tif file generated in ArcGIS into MATLAB. I know what the final image is supposed to look like because there is a .pdf version of the gridded data posted with the data I've downloaded (so I can check if I've done this correctly).
I have been able to load in the .tif file, but based on how I read the data in & how I plot it, the results look very different. I know that the image I want is closer to the one in imread() and plotted with imshow(). The two images genereated here and the .pdf version I'm trying to recreate are attached. I am wondering
(1) How to colourize this data and
(2) if the differences between these two images are simply the colour scale. Of note, the original .pdf is colourized, but neither my variables 'X' nor 'gridd' have a 3rd dimension that would contain colour info.
filename= 'Na_dep_2017.tif'; % My file
infoii = imfinfo(filename,'tif'); % Get info about my file
[gridd,R] = geotiffread(filename); % Load in geocoded tiff file.
gridd(gridd==str2num(infoii.GDAL_NODATA))=NaN; % Set NANs where we have no data.
[X,cmap] = imread(filename); % Load it in as an image.
X(X==str2num(infoii.GDAL_NODATA))=NaN; % Set NANs where we have no data.
figure(1)
subplot(1,2,1)
imshow(X,cmap); title('Loaded with imread(), plotted with imshow()')
subplot(1,2,2)
mapshow(double(gridd),R);
title('Loaded with geotiffread(), plotted with mapshow()')
Two dif images I make & actual image
I don't think how you load the data in actually changes the image that you get, but it does appear to influence the white-black max/min that the image is displayed with. The two images are therefore not fundamentally different. I got around using either of these methods & without worrying about colorizing the image using rgb channels, because I actually got the data surface that the image is made of by loading the data in. I used pcolor() to display the 'gridd' variable with a standard MATLAB colormap as follows.
filename= 'Na_dep_2017.tif'; % My file
infoii = imfinfo(filename,'tif'); % Get info about my file
[gridd,R] = geotiffread(filename); % Load in geocoded tiff file.
gridd(gridd==str2num(infoii.GDAL_NODATA))=NaN; % Set NANs where we have no data.
figure(1)
h=pcolor(flipud(double(gridd)));
set(h, 'EdgeColor', 'none'); % Makes tightly gridded figure not all black.
colormap(jet)
Related
I'm trying to plot some temperature data over a grayscale image, with the temperature data shown using a colorscale. I've been able to do so by overlaying a partially-transparent array with the temperature data over the image data. The problem comes when I try to save it as a tiff (or jpeg). While the colorbar (for the temperature data) shows up exactly as intended in the Matlab figure, when I save it as a tiff, the colorbar comes up empty (solid white). Any ideas?
figure
imagesc(xlims, ylims, image_data)
set(gca,'YDir','normal');
colormap(gray)
title(title)
xlabel('xlabel')
ylabel('ylabel')
hold on
axis equal
axis tight
%Skip lines of code where I build my temperature array (T) here
%Force a single pixel to 2200
T(1,1)=2200;
%Remove any data below 1000
T(T<1000)=0;
% Establish Transparency Mask for Temperature Data
transp = T~=0; % Binary matrix highlighting where temp data exists
% Overlay Temp Data on Background Image
imagesc(xlims, ylims, T,'AlphaData',transp)
% Create Colormaps and Combine Them
% Note: Assumes no overlap between background image values and temp data
% (highest value in background image is 73)
cmap1 = colormap(gray(73));
cmap2 = colormap(gray(999-73));
cmap3 = colormap(jet(2200-999));
cmap = [cmap1; cmap2; cmap3];
% Apply Combined Colormap to Figure
colormap(cmap)
% Add and Modify colorbar
h = colorbar;
set(h,'YLim',[1000 2200]) % Reduces Range of Colorbar to show only Temp Data
ylabel(h,'Temperature, Kelvin')
print(gcf, '-dtiff', 'filename');
When saved the colorbar looks like this:
In the Matlab figure it looks fine:
UPDATE: I had a bit of old code that I had done something kind of similar on and went line by line looking at differences. For some reason, having the figure visible matters? If I change
figure
to
figure ('visible','off');
the whole thing works. Still curious as to why????
I have designed one MATLAB GUI in which there are two axes for displaying images. I am using 'imcontrast' function to adjust brightness/contrast of the images on first axes. Now, I want to store this enhanced output(brightness/contrast adjusted output) in some variable. As 'imcontrast' function does not returns the output image, so how can i get output image? or Is there any way to read image data from particular axes? I have tried with 'getimage' function but it returns the first image data contained in the Handle Graphics object (i.e previously displayed input image) and not latest brightness/contrast adjusted Image. Please help me out in saving the brightness/contrast adjusted Image given by 'imcontrast' function.
Use this -
imcontrast(gca) %// Perform imcontrast
waitfor(gcf); %// Wait for figure data to be updated with imcontrast
image_data = getimage(gcf);%// Store image data as image_data variable
How to use within a GUI
Just to showcase on how to use it, you can create a pushbutton with MATLAB-Guide and in it's callback function use this -
%// Show the image on an existing image axes of the GUI.
imshow('pout.tif') %// This image is available in MATLAB image library.
imc_figure = imcontrast(gca) %// Perform imcontrast
waitfor(imc_figure); %// Wait for the data to be updated in the current figure
image_data = getimage(gcf);%// image data stored into image_data variable
%// Open image_data on a separate figure window for verification.
%// Make sure this is the updated image.
figure,imshow(image_data)
How to use as a standalone code
Im = imread('cameraman.tif');%// This image is available in MATLAB image library.
h1 = imshow(Im)
h2 = imcontrast(gca); %// Perform imcontrast
waitfor(h2); %// Wait for figure data to be updated with imcontrast
image_data = getimage(gcf);%// Store modified image data
%// Show modified image data for verification
figure,imshow(image_data)
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');
I am using MATLABs 'saveas' to save off one of my figures as a .png or .jpg or whatever.
So I just do:
y = randn(1,00);
plot(y); grid on;
saveas(gcf,'y','png');
Now the problem is that the png or final picture comes out as a perfect square - even if I manually stretch the figure before I use the 'saveas' command.
How do I get it so save something more rectangular?
Thanks!
Here's a short sample taken from a mathworks discussion
figure('units','pix','pos',[100 100 200 400]) % create a 200x400 image
>> imagesc(rand(10,10)) % put some random data in it
>> print(gcf,'-dbitmap','test.bmp') % save to bmp
Using print like this saves an image in the desired resolution.
How do I avoid a jagged image in MATLAB?
I have a 600 x 600 pixels image opened in MATLAB and do some processing on the image. However, when I save it, it looks so blurred and jagged. What should I do?
(This question is related to my previous question, MATLAB - How to plot x,y on an image and save?)
fid = fopen(datafile.txt);
A = textscan(fid,'%f%f%f'); %read data from the file
code = A{1};
xfix = A{2};
yfix = A{3};
for k=1:length(code)
imagefile=code(k);
rgb = imread([num2str(imagefile) '.jpg']);
imshow(rgb);
hold on;
x = xfix2(k);
y = yfix2(k);
plot(x,y,'-+ b'); % plot x,y on the
saveas(([num2str(imagefile) '.jpg'])) % Save the image with the same name as it open.
end
hold off
If it is just a resolution issue, perhaps using the print command (as listed below) with an explicit resolution option may fix it.
print(gcf,'-djpeg','-r600',[num2str(imagefile)])
My guess would be JPEG compression artifacts. JPEG isn't a great format for data with a lot of high frequency components. Have you tried turning the compression down? Like so:
imwrite(f.cdata,([num2str(imagefile) '.jpg']),'Quality',100);
The default for the quality parameter is only 75. That's plenty for a lot of cases, but you might need more.