How to output the Cascading images or stacking images - image

See above image, if there are 24 pictures, how to use MATLAB to achieve this output effect. This kind of graph often appears in papers. I define a function, but there is one line of code that cannot be implemented.
function h = op(file_path, pad,m,n)
img_path_list = dir(strcat(file_path,'*.jpg'));
num = length(img_path_list);%
% [m,n]=size(image);
fw=n+(num-1)*pad;
fh=m+(num-1)*pad;
h=figure('position',[0,0,fw+pad,fh+pad]);
for j = 1:num
image_name = img_path_list(j).name;
image = imread(strcat(file_path,image_name));
hold on
pd=(j-1)*pad;
rpl=fw-n-pd;
rpb=fh-m-pd;
%How to specify the location of the output on the image canvas
% set('Position',[rpl rpb n m]);
% axes('position',[rpl rpb n m]);
imshow (image);
end
% h=gcf;

You can use the Xdata, and Ydata in imshow() function to set the axis position of each image to display them on the same axis stacked one upon other shifted to a fixed units for each image.
The code illustrating the procedure is given below.
close all
% read the images in metrices
i1 = imread('onion.png');
i2 = imread('cameraman.tif');
i3 = imread('peppers.png');
i4 = imread('moon.tif');
i5 = imread('trees.tif');
i6 = imread('greens.jpg');
% create a cell array of the images
imgs = {i1, i2, i3, i4, i5, i6};
% variable to shift the position of each image
shift = 0;
% looping from 1 to length of the cell arrays
for i = 1:numel(imgs)
% display image, shifting the position to 2 units
% for each image on the same axis
imshow(imgs{i}, 'XData', [1+shift 10+shift], ...
'YData', [1+shift 10+shift],'InitialMagnification', 400)
% hold on the axis
hold on
% increment the shift value
shift = shift + 2;
end
% set the axis limits
xlim([1 10+shift])
ylim([1 10+shift])
% hide the axis lines
axis off
Sample Output

Related

Matlab - Scale Colorbar of Image

How can I scale the colorbar axis of a false color image?
I read this post,and copied the code but it seems not to work correctly:
MATLAB Colorbar - Same colors, scaled values
Please see the two images below. In the first (without the scaling) the coloraxis goes
[1 2 3 4 5 6]*10^4
In the second image, it goes
[0.005 0.01 0.015 0.02 0.025]
The correct scaling (with C = 100000) would be
[0.1 0.2 0.3 0.4 0.5 0.6]
Without scaling
Wrong scaling
I want that the coloraxis is scaled by 1/C and I can freely choose C, so that when the pixel value = 10^4 and C=10^6 the scale should show 10^-2.
The reason why I multiply my image first by C is to get more decimals places, because all values below 1 will be displayed as zero without the C scaling.
When I run the code I get yticks as a workspace variable with the following values:
[500 1000 1500 2000 2500]
My code:
RGB = imread('IMG_0043.tif');% Read Image
info = imfinfo('IMG_0043.CR2'); % get Metadata
C = 1000000; % Constant to adjust image
x = info.DigitalCamera; % get EXIF
t = getfield(x, 'ExposureTime');% save ExposureTime
f = getfield(x, 'FNumber'); % save FNumber
S = getfield(x, 'ISOSpeedRatings');% save ISOSpeedRatings
date = getfield(x,'DateTimeOriginal');
I = rgb2gray(RGB); % convert Image to greyscale
K = 480; % Kamerakonstante(muss experimentel eavaluiert werden)
% N_s = K*(t*S)/power(f,2))*L
L = power(f,2)/(K*t*S)*C; %
J = immultiply(I,L); % multiply each value with constant , so the Image is Calibrated to cd/m^2
hFig = figure('Name','False Color Luminance Map', 'ToolBar','none','MenuBar','none');
% Create/initialize default colormap of jet.
cmap = jet(16); % or 256, 64, 32 or whatever.
% Now make lowest values show up as black.
cmap(1,:) = 0;
% Now make highest values show up as white.
cmap(end,:) = 1;
imshow(J,'Colormap',cmap) % show Image in false color
colorbar % add colorbar
h = colorbar; % define colorbar as variable
y_Scl = (1/C);
yticks = get(gca,'YTick');
set(h,'YTickLabel',sprintfc('%g', [yticks.*y_Scl]))
ylabel(h, 'cd/m^2')% add unit label
title(date); % Show date in image
caxis auto % set axis to auto
datacursormode on % enable datacursor
img = getframe(gcf);
nowstr = datestr(now, 'yyyy-mm-dd_HH_MM_SS');
folder = 'C:\Users\Taiko\Desktop\FalseColor\';
ImageFiles = dir( fullfile(folder, '*.jpg') );
if isempty(ImageFiles)
next_idx = 1;
else
lastfile = ImageFiles(end).name;
[~, basename, ~] = fileparts(lastfile);
file_number_str = regexp('(?<=.*_)\d+$', basename, 'match' );
last_idx = str2double(file_number_str);
next_idx = last_idx + 1;
end
newfilename = fullfile( folder, sprintf('%s_%04d.jpg', nowstr, next_idx) );
imwrite(img.cdata, newfilename);
Problems:
1) You are getting YTick of the figure (gca) but not the color bar. That would give you the "pixel" coordinates of the graph, instead of the actual values. Use yticks = get(h,'YTick');.
2) caxis auto Should come before overwriting YTicks (and after enabling the color bar); otherwise the scale and ticks will mismatch.
3) Do you mean C = 100000?
Result:

MATLAB second axis for colorbar following a convention

i want to make a second axis for the same colorbar of an false color image. the second scale should follow this convention : [new values] = Log10([old values]/108000)/-0.4 . i have this code for the first axis:
C = 10
hFig = figure('Name','False Color Luminance Map', 'ToolBar','none','MenuBar','none');
% Create/initialize default colormap of jet.
cmap = parula(16); % or 256, 64, 32 or whatever.
% Now make lowest values show up as black.
cmap(1,:) = 0;
% Now make highest values show up as white.
cmap(end,:) = 1;
imshow(J,'Colormap',cmap) % show Image in false color
colorbar % add colorbar
h = colorbar; % define colorbar as variable
caxis auto
y_Scl = (1/C);
yticks = get(h,'YTick');
set(h,'YTickLabel',sprintfc('%g', [yticks.*y_Scl]))
in a previous post here i got this lines for an second axis:
BarPos = get(hBar1,'position');
ylabel(hBar1,'label','FontSize',12);
haxes = axes('position',BarPos,'color','none','ytick',0:5:15,'ylim',[0 15],'xtick',[]);
how can i make the second axis use the the yticks of the first axis as an input for the convention?
EDIT: here is what i came up with. the thing is the values are wrong :/
fname='IMG_0041'; % select target image
C = 1000; % Constant to adjust image
K = 480; % Cameraconstant
RGB = imread([fname, '.tif']);% Read Image as tif
info = imfinfo([fname,'.CR2']); % get Metadata from CR2
x = info.DigitalCamera; % get EXIF
t = getfield(x, 'ExposureTime');% save ExposureTime
f = getfield(x, 'FNumber'); % save FNumber
S = getfield(x, 'ISOSpeedRatings');% save ISOSpeedRatings
date = getfield(x,'DateTimeOriginal'); % save DateTimeOriginal
I = rgb2gray(RGB); % convert Image to greyscale
% N_s = K*(t*S)/power(f,2))*L
L = power(f,2)/(K*t*S)*C; % calculate L/N_s
J = immultiply(I,L);
hFig = figure('Name','False Color Luminance Map', 'ToolBar','none', 'MenuBar','none');
% Create/initialize default colormap of jet.
cmap = parula(16); % or 256, 64, 32 or whatever.
% Now make lowest values show up as black.
cmap(1,:) = 0;
% Now make highest values show up as white.
cmap(end,:) = 1;
imshow(J,'Colormap',cmap) % show Image in false color
colorbar % add colorbar
h = colorbar; % define colorbar as variable
caxis auto
y_Scl = (1/C);
yticks = get(h,'YTick');
set(h,'YTickLabel',sprintfc('%g', [yticks.*y_Scl]))
BarPos = get(h,'position');
haxes = axes('position',BarPos,'color','none','ylim',[0 150]);
set(haxes,'YTickLabel', sprintfc('%g', log10(yticks.*y_Scl/108000)/-0.4));
https://www.sendspace.com/file/39wwm9 -> files for testing the code

Matlab image - how to count number of white pixels

The matlab code below splits up an image into a number of smaller images. It then counts the number of black pixels in the image and displays it as a percentage of the total number of pixels in the picture. example of image
My question is - instead of counting the black pixels and displaying the percentage, how can I count the white pixels? (essentially the opposite!)
Thanks
% Divide an image up into blocks (non-overlapping tiles).
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
workspace; % Make sure the workspace panel is showing.
fontSize = 20;
% Read the image from disk.
rgbImage = imread('edge-diff.jpg');
% Display image full screen.
imshow(rgbImage);
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
drawnow;
% Get the dimensions of the image. numberOfColorBands should be = 3.
[rows columns numberOfColorBands] = size(rgbImage)
%==========================================================================
% The first way to divide an image up into blocks is by using mat2cell().
blockSizeR = 400; % Rows in block.
blockSizeC = 400; % Columns in block.
% Figure out the size of each block in rows.
% Most will be blockSizeR but there may be a remainder amount of less than that.
wholeBlockRows = floor(rows / blockSizeR);
blockVectorR = [blockSizeR * ones(1, wholeBlockRows), rem(rows, blockSizeR)];
% Figure out the size of each block in columns.
wholeBlockCols = floor(columns / blockSizeC);
blockVectorC = [blockSizeC * ones(1, wholeBlockCols), rem(columns, blockSizeC)];
% Create the cell array, ca.
% Each cell (except for the remainder cells at the end of the image)
% in the array contains a blockSizeR by blockSizeC by 3 color array.
% This line is where the image is actually divided up into blocks.
if numberOfColorBands > 1
% It's a color image.
ca = mat2cell(rgbImage, blockVectorR, blockVectorC, numberOfColorBands);
else
ca = mat2cell(rgbImage, blockVectorR, blockVectorC);
end
percentBlack = cellfun(#(x)sum(sum(all(x == 0, 3))) / (numel(x) / size(x,3)), ca);
% Now display all the blocks.
plotIndex = 1;
numPlotsR = size(ca, 1);
numPlotsC = size(ca, 2);
for r = 1 : numPlotsR
for c = 1 : numPlotsC
fprintf('plotindex = %d, c=%d, r=%d\n', plotIndex, c, r);
% Specify the location for display of the image.
subplot(numPlotsR, numPlotsC, plotIndex);
ax2 = subplot(numPlotsR, numPlotsC, plotIndex);
% Extract the numerical array out of the cell
% just for tutorial purposes.
rgbBlock = ca{r,c};
imshow(rgbBlock); % Could call imshow(ca{r,c}) if you wanted to.
[rowsB columnsB numberOfColorBandsB] = size(rgbBlock);
set(ax2, 'box', 'on', 'Visible', 'on', 'xtick', [], 'ytick', []);
% Make the caption the block number.
averageBlack = percentBlack(r,c);
disp(numPlotsR);
disp(averageBlack);
caption = sprintf('Frame #%d of %d\n Percentage information content %0.2f', ...
plotIndex, numPlotsR*numPlotsC, averageBlack*100);
title(caption);
drawnow;
% Increment the subplot to the next location.
plotIndex = plotIndex + 1;
end
end
This line:
percentBlack = cellfun(#(x)sum(sum(all(x == 0, 3))) / (numel(x) / size(x,3)), ca);
specifically the part that says all(x == 0, 3) means "all color channels have value 0". You want to change it to "all color channels have value 1 (or 255 depends on your image)"
So basically, change that 0 to 1 or 255, deependinf if your image is unit8 or double

Plot over an image background in MATLAB

I'd like to plot a graph over an image. I followed this tutorial to Plot over an image background in MATLAB and it works fine:
% replace with an image of your choice
img = imread('myimage.png');
% set the range of the axes
% The image will be stretched to this.
min_x = 0;
max_x = 8;
min_y = 0;
max_y = 6;
% make data to plot - just a line.
x = min_x:max_x;
y = (6/8)*x;
imagesc([min_x max_x], [min_y max_y], img);
hold on;
plot(x,y,'b-*','linewidth',1.5);
But when I apply the procedure to my study case, it doesn't work. I'd like to do something like:
I = imread('img_png.png'); % here I load the image
DEM = GRIDobj('srtm_bigtujunga30m_utm11.tif');
FD = FLOWobj(DEM,'preprocess','c');
S = STREAMobj(FD,flowacc(FD)>1000);
% with the last 3 lines I calculated the stream network on a geographic area using the TopoToolBox
imagesc(I);
hold on
plot(S)
The aim is to plot the stream network over the satellite image of the same area.
The only difference between the two examples that doesn't let the code working is in the plot line, in the first case "plot(x,y)" works, in the other one "plot(S)" doesn't.
Thanks guys.
This is the satellite image, imagesc(I)
It is possible that the plot method of the STREAMobj performs it's own custom plotting including creating new figures, axes, toggling hold states, etc. Because you can't easily control what their plot routine does, it's likely easier to flip the order of your plotting so that you plot your stuff after the toolbox plots the STREAMobj. This way you have completely control over how your image is added.
% Plot the STREAMobj
hlines = plot(S);
% Make sure we plot on the same axes
hax = ancestor(hlines, 'axes');
% Make sure that we can add more plot objects
hold(hax, 'on')
% Plot your image data on the same axes
imagesc(I, 'Parent', hax)
Maybe I am preaching to the choir or overlooking something here but the example you used actually mapped the image to the data range of the plot, hence the lines:
% set the range of the axes
% The image will be stretched to this.
min_x = 0;
max_x = 8;
min_y = 0;
max_y = 6;
imagesc([min_x max_x], [min_y max_y], img);
where you directly plot your image
imagesc(I);
If now your data coordinates and your image coordinates are vastly different you either see one or the other.
Thanks guys, I solved in this way:
I = imread('orto.png'); % satellite image loading
DEM = GRIDobj('demF1.tif');
FD = FLOWobj(DEM,'preprocess','c');
S = STREAMobj(FD,flowacc(FD)>1000); % Stream network extraction
x = S.x; % [node attribute] x-coordinate vector
y = S.y; % [node attribute] y-coordinate vector
min_x = min(x);
max_x = max(x);
min_y = min(y);
max_y = max(y);
imagesc([min_x max_x], [min_y max_y], I);
hold on
plot(S);
Here's the resulting image: stream network over the satellite image
Actually the stream network doesn't match the satellite image just because I'm temporarily using different images and DEM.

How to reconstruct an image using rgb values of all pixels in Matlab

I am trying to read an image using imread then, save the RGB values of all of the pixels in an array. And finally, be able to recreate this image using only the RGB values.
This is the for loop that saves all of the RGB values of each pixel.
A=imread('image.jpg');
N=2500; %the image dimensions are 50x50
i=1;
rgbValues = zeros(N, 3);
for x = 1:50
for y = 1:50
rgbValues(i,:) = A(x,y,:);
i=i+1;
end
end
Now, how am I able to recreate this image if I have all of the rgb values saved.
A direct way to do this is:
ny = 50;
nx = 50;
recreatedImage = zeros(ny,nx,3, 'uint8');
for ind = 1:3
recreatedImage(:,:, ind) = ( reshape(rgbValues(:, ind), nx, ny))';
end
As Natan indicated, reshape will work also but you have to do this:
recreatedImage=reshape(rgbValues,[ny,nx,3]);
Which is, unfortunately, transposed so you will need to work it to get it rotated back up.
You might consider swapping your x and y values in your for loop so you iterate over all y and then all x values---because this is how MATLAB stores the data and you can change the above code to:
for ind = 1:3
recreatedImage(:,:, ind) = ( reshape(rgbValues(:, ind), ny, nx));
end
(edit) and then the direct reshape works as well:
rgbValuesBacktoShape=reshape(rgbValues,[50,50,3]);

Resources