How to find the variance of several images in MATLAB - matlab

I am relatively new to MATLAB and Image processing, so understand with me. I am working in experiment on image processing, and my current stage, I need to
1) read some images (about 100 images of same dimension)
2) store them in a variable (either cell array, vector or structure)
3) Find the variance of each pixel in each image
4) Form a new matrix to store each computed variance
Here is my code, but I am not sure it solves this problem not withstanding that I get result
clc;
im_File = dir('*.bmp');
files = {im_File.name};
for k=1:numel(files)
im{k} = imread(files{k});
%# Get the number of dimensions for your arrays
dim = ndims(im{k});
all_images = cat(dim+1,im{:});
% Use linear combine to acquire all the images
Linear_comb_im = imlincomb(1,all_images,'uin');
%get the variance of all images
computed_variance = var(double(Linear_comb_im),1,dim+1);
end

So it seems that you have a redundant variable here : both im and all_im basically save the same information. if the dimensions werent the same i would use a cell array, otherwise matlab likes matrices better.
In addition, I am not sure why you are performing the linear combination.
I would do the following:
clc;
im_File = dir('*.bmp');
files = {im_File.name};
for k=1:numel(files)
im(:,:,k) = imread(files{k}); % to save time you should initialize im begore the loop i.e. im = zeros(m,n,numerl(files)), where m,n are the size of the images
end
%get the variance of all images
computed_variance = var(double(im),1,3);
so im here is a 3D matrix containing the images in the 3rd dimension. In order to access the idx image:
im(:,:,idx)

Related

How can I merge multiple images into one and save it on matlab?

I need to merge multiple bitmap of same sizes into one image.That image is basically rotated in different angles and needs to be merged into one whole image. I have tried multiple methods but I come with many issues as I am not able to save that image.
I have tried multiple codes but I actually cannot make sense out of it. What I want to achieve is transparent overlay (not sure) that superimposes two images and you can actually see both one image
figure1 = figure;
ax1 = axes('Parent',figure1);
ax2 = axes('Parent',figure1);
set(ax1,'Visible','off');
set(ax2,'Visible','off');
[a,map,alpha] = imread('E:\training data\0.bmp');
I = imshow(a,'Parent',ax2);
set(I,'AlphaData',alpha);
F = imshow('E:\training data\200.bmp','Parent',ax1);
I just want to superimpose multiple images.
This is my data set:
This is what I want to achieve, i want to add all of the rotated images and achieved into one
This is what I get sadly, I have tried everything
The following does kind of what you want. First load the image, then divide it into 6 equal blocks, and add these. To add the pixel values, I first converted the image to doubles, since uint8 only can go up to pixel values of 255. This would mean that you will just see a large bright spot in the image because you are clipping.
Then add all the blocks. You will see in the output, that the car is not always perfect in the center of the block, so depending on what you are trying to achieve you may want to align the blocks using something like xcorr2.
% load image
A = imread('S82CW.jpg');
fig = figure(1); clf
image(A);
% convert A to double and divide in blocks.
A = double(A);
[img_h, img_w, ~] = size(A);
block_h = img_h/2;
block_w = img_w/3;
% split image in blocks
Asplit = mat2cell(A, repelem(block_h,2), repelem(block_w,3), 3);
% check if splitting makes sense
figure(2); clf
for k = 1:numel(Asplit)
subplot(3,2,k)
image(uint8(Asplit{k}))
end
% superimpose all blocks,
A_super = zeros(size(Asplit{1,1}),'like',Asplit{1,1} ); % init array, make sure same datatype
for k = 1:numel(Asplit)
A_super = A_super + Asplit{k};
end
% divide by max value in A and multiply by 255 to make pixel
% values fit in uint8 (0-255)
A_super_unit8 = uint8(A_super/max(A_super,[],'all')*255);
figure(3); clf;
image(A_super_unit8)

How can I modify a set of vectors to have the same size?

i'm trying to extract HOG_features for mathematical symbols classification (i will use SVM classifier). I get a 1xn vector then i have to put all the vectors in a single matrix. The problem is that the size of the feature vector is different for each image so I can't concatenate them.
Is there a way to make all vectors having the same size ?
Thank you in advance.
Here is the code:
rep1 = 'D:\mémoire MASTER\data';
ext = '*.tif' ;
chemin = fullfile(rep1, ext);
list = dir(chemin);
for i=1:length(list)
I = imread(fullfile(rep1, list(i).name), ext(3:end));
if size(I,3)==3 % RGB image
I = rgb2gray(I);
end
I1 = imbinarize(I);
% Extract HOG features data
HOG_feat = extractHOGFeatures(I1,'CellSize', [2 2]);
HOG_feat1 = HOG_feat';
end
You can pad each one with zeros to be as long as the longest one:
e.g. to put two vectors, v1 and v2, into a matrix M:
M = zeros(2,max(length(v1),length(v2)));
M(1,1:length(v1)) = v1;
M(2,1:length(v2)) = v2;
You have the problem that all your vectors are a different size. Instead of trying to coerce them to be the sesame size by zero-padding or interpolating (both I think are bad ideas), change your computation so that the length of the output vector does not depend on the size of the image.
This is your current code:
HOG_feat = extractHOGFeatures(I1,'CellSize', [2 2]);
% ^^^
% the image is split in cells of 2x2 pixels
2x2 cells are way too small for this method anyway. You could instead divide your image into a set number of cells, say 100 cells:
cellSize = ceil(size(I1)/10);
HOG_feat = extractHOGFeatures(I1,'CellSize', cellSize);
(I’m using ceil in the division because I figure it’s necessary to have an integer size. But I’m not sure whether ceil or floor or round is needed here, and I don’t have access to this function to test it. A bit of trial and error should show which method gives consistent output size.)

Wrong output for 2d convolution function

As the title says, the output I’m getting out of this function is incorrect. By incorrect I mean that the data are overflowing. How do I normalise the matrix correctly? Currently almost all of the pictures I get are white.
I called the function from another MATLAB file like this:
mask = [3,10,3;0,0,0;-3,-10,-3];
A = imread(“football.jpg”);
B = ConvFun(A,mask);
function [ image ] = ConvFun( img,matrix )
[rows,cols] = size(img); %// Change
%// New - Create a padded matrix that is the same class as the input
new_img = zeros(rows+2,cols+2);
new_img = cast(new_img, class(img));
%// New - Place original image in padded result
new_img(2:end-1,2:end-1) = img;
%// Also create new output image the same size as the padded result
image = zeros(size(new_img));
image = cast(image, class(img));
for i=2:1:rows+1 %// Change
for j=2:1:cols+1 %// Change
value=0;
for g=-1:1:1
for l=-1:1:1
value=value+new_img(i+g,j+l)*matrix(g+2,l+2); %// Change
end
end
image(i,j)=value;
end
end
%// Change
%// Crop the image and remove the extra border pixels
image = image(2:end-1,2:end-1);
imshow(image)
end
In a convolution, if you want the pixel value to stay in the same range
, you need to make the mask add up to 1. Just divide the mask by sum(mask(:)) after defining it. This is however, not the case you are dealing with.
Sometimes that is not the needed. For example if you are doing edge detection (like the kernel you show), you don't really care about maintaining the pixel values. In those cases, the plotting of unnormalized images is more the problem. You can always set the imshow function to auto select display range: imshow(image,[]).
Also, I hope this is homework, as this is the absolutely worst way to code convolution. FFT based convolution is about 100 times faster generally, and MATLAB has an inbuilt for it.

How to add HOG features into matrix (matlab)

After extracting HOG features of folder of images, I want to add all this results in one matrix. How I can do this? this is my code in matlab:
training_female = 'E:\Training Set\Female Images';
% read all images with specified extention, its jpg in our case
filenames = dir(fullfile(training_female, '*.jpg'));
% count total number of photos present in that folder
total_images = numel(filenames);
for n = 1:total_images
% Specify images names with full path and extension
full_name= fullfile(training_female, filenames(n).name);
% Read images
training_images = imread(full_name);
[featureVector, hogVisualization] = extractHOGFeatures(training_images);
figure (n)
% Show all images
imshow(training_images); hold on;
plot(hogVisualization);
end
By looking at the documentation, calling extractHOGFeatures computes a 1 x N vector given an input image. Because it can be a bit cumbersome to calculate what the output size of this may be, which also depends on what parameters you set up for the HOG detector, it's best to first create an empty matrix and dynamically concatenate the features at each iteration. Usually for performance you pre-allocate a matrix if you want to populate the elements on an iterative basis. Not doing it this way gives a slight ding in performance, but it's the most adaptable given your situation. You may want to adjust the HOG parameters and if we do it the dynamic way, that removes the headache of determining what the total size of the matrix should be.
So do something like this. I've placed %//New tags where I've modified your code:
training_female = 'E:\Training Set\Female Images';
% read all images with specified extention, its jpg in our case
filenames = dir(fullfile(training_female, '*.jpg'));
% count total number of photos present in that folder
total_images = numel(filenames);
featureMatrix = []; %// New - Declare feature matrix
for n = 1:total_images
% Specify images names with full path and extension
full_name= fullfile(training_female, filenames(n).name);
% Read images
training_images = imread(full_name);
[featureVector, hogVisualization] = extractHOGFeatures(training_images);
%// New - Add feature vector to matrix
featureMatrix = [featureMatrix; featureVector];
figure(n);
% Show all images
imshow(training_images); hold on;
plot(hogVisualization);
end
featureMatrix will contain your HOG features where each row is for each image. Therefore, for a particular image i, you can determine the HOG features by:
feature = featureMatrix(i,:);
Caveat
I need to mention that the above code assumes that all images in your directory are the same size. If they're not, then the output vector size for each HOG call is going to be different. If that's the case, you'll want to have a cell array to adapt for the different sizes.
Therefore, do something like this:
training_female = 'E:\Training Set\Female Images';
% read all images with specified extention, its jpg in our case
filenames = dir(fullfile(training_female, '*.jpg'));
% count total number of photos present in that folder
total_images = numel(filenames);
featureMatrix = cell(1,total_images); %// New - Declare feature matrix
for n = 1:total_images
% Specify images names with full path and extension
full_name= fullfile(training_female, filenames(n).name);
% Read images
training_images = imread(full_name);
[featureVector, hogVisualization] = extractHOGFeatures(training_images);
%// New - Add feature vector to matrix
featureMatrix{n} = featureVector;
figure(n);
% Show all images
imshow(training_images); hold on;
plot(hogVisualization);
end
To access a particular image's features, or image i, do:
feature = featureMatrix{i};

Creating a movie in MATLAB with point data for a simple N-body simulation

I am trying to write a simple n-body gravity simulation with 4 particles in C++. I am outputting the positions of the 4 particles to .mat files labeled "time_X.mat" (where X=1,2,3.... indicates the time-stamp) in the form of a 4x2 matrix where
i'th row indicates (x,y) cooridinates of the ith particle at time X .
Now for a particular time-step I am able load the .mat file into MATLAB and get a scatterplot of the points in the matrix, showing me particle positions. But I would like to create a movie out of all the .mat files / scatter-plots of the time_X.mat files which shows me the evolution of the 4 particle syestem . How should I do that in MATLAB?
First you have to make frames (images) of each time step of your simulation.
Since you have Cartesian coordinates, you have to convert your x and y coordinates to pixel indices, and make an image matrix from them. See my answer to a relevant question for an example of how to do this. You could also modify the code to make your points larger than a pixel, have shapes, etc., perhaps with strel or [a,b,~] = sphere(N).
Once you have the frames, you can easily make an AVI file (uncompressed or MPEG) in MATLAB:
aviOutput = fullfile('path','to','file.avi');
aviobj = VideoWriter(aviOutput);
aviobj.Quality = 100;
aviobj.FrameRate = 24; %# arbitrary
open(aviobj);
for i=1:length(frames)
writeVideo(aviobj,frames{i}); %# or frames(:,:,i) etc.
end
close(aviobj);
Update
The above assumes the time steps are all available. For example:
files = dir('path/to/dir');
files(1:2) = []; %# . and ..
orderedfiles = cell(length(files),1);
for i=1:length(files)
ind = sscanf(files(i).name,[name '%*[_]%u%*s']);
orderedfiles{ind+1} = files(i).name;
end
timeSteps = zeros(numPoints,2,length(orderedfiles));
for i=1:length(orderedfiles)
temp = load(orderedfiles(i).name);
timeSteps(:,:,i) = temp.matrixName %# All the same name?
end
The code from the linked answer is written to operate on two vectors x and y with the coordinates, which you would get with timeSteps(:,1,i) and timeSteps(:,2,i), and do for each time step.