Histogram of an image - matlab

I need to take histogram of each splited image and i want to calculate mean and variance of the splited image. here i am getting an error while i calculating the mean value..... please guide me
[h w c] = size(x);
numSplits = 3; %
sw = floor(w/numSplits); %
widths = repmat(sw, 1, numSplits-1);
widths(numSplits) = w - sum(widths);
splits = mat2cell(x, h, widths, c);
% show the splits
for ii=1:numSplits
subplot(1,numSplits,ii);
imshow(splits{ii});
g(ii)=(splits{ii});
figure, imhist(g(ii));
end
%mean
im1=g(ii);
su=mean2(im1);
mean=ceil(su);
disp('mean Value');
disp(mean)
%variance
sv=double(im1);
v = var(sv);
disp(v)
i need to get the histograms of each seperate images and i need to calculate the mean for that splitted images

I assume that x is the image you want to split and analyze and that it is the image you have linked:
First, I load the image (you have already done this, I guess, so you do not need to copy this):
x = imread('https://i.stack.imgur.com/4PAaI.png');
The following code solves your coding errors:
[h, w, c] = size(x);
numSplits = 3; %
sw = floor(w/numSplits); %
widths = repmat(sw, 1, numSplits-1);
widths(numSplits) = w - sum(widths);
splits = mat2cell(x, h, widths, c);
results = repmat(struct('mean',[], 'variance',[]),numSplits, 1);
% show and analyze the splits
for ii=1:numSplits
subplot(2,numSplits,ii);
imshow(splits{ii});
subplot(2,numSplits, ii+numSplits);
imhist(splits{ii});
results(ii).mean = mean2(splits{ii});
results(ii).variance = (std2(splits{ii})).^2;
end
The mean and variance are stored in results:
>> results(1)
ans =
struct with fields:
mean: 118.0233
variance: 1.3693e+03
>> results(2)
ans =
struct with fields:
mean: 126.1719
variance: 1.9608e+03
>> results(3)
ans =
struct with fields:
mean: 121.9004
variance: 958.3740
However, please double check that you really want to compute the stats for the combined color channels of the images and not only for, for eample, the red one.

Related

How to process image before applying bwlabel?

I = imread('Sub1.png');
figure, imshow(I);
I = imcomplement(I);
I = double(I)/255;
I = adapthisteq(I,'clipLimit',0.0003,'Distribution','exponential');
k = 12;
beta = 2;
maxIter = 100;
for i=1:length(beta)
[seg,prob,mu,sigma,it(i)] = ICM(I, k, beta(i), maxIter,5);
pr(i) = prob(end);
hold on;
end
figure, imshow(seg,[]);
and ICM function is defined as
function [segmented_image,prob,mu,sigma,iter] = ICM(image, k, beta, max_iterations, neigh)
[width, height, bands] = size(image);
image = imstack2vectors(image);
segmented_image = init(image,k,1);
clear c;
iter = 0;
seg_old = segmented_image;
while(iter < max_iterations)
[mu, sigma] = stats(image, segmented_image, k);
E1 = energy1(image,mu,sigma,k);
E2 = energy2(segmented_image, beta, width, height, k);
E = E1 + E2;
[p2,~] = min(E2,[],2);
[p1,~] = min(E1,[],2);
[p,segmented_image] = min(E,[],2);
prob(iter+1) = sum(p);
%find mismatch with previous step
[c,~] = find(seg_old~=segmented_image);
mismatch = (numel(c)/numel(segmented_image))*100;
if mismatch<0.1
iter
break;
end
iter = iter + 1;
seg_old = segmented_image;
end
segmented_image = reshape(segmented_image,[width height]);
end
Output of my algorithm is a logical matrix (seg) of size 305-by-305. When I use
imshow(seg,[]);
I am able to display the image. It shows different component with varying gray value. But bwlabel returns 1. I want to display the connected components. I think bwlabel thresholds the image to 1. unique(seg) returns values 1 to 10 since number of classes used in k-means is 10. I used
[label n] = bwlabel(seg);
RGB = label2rgb(label);
figure, imshow(RGB);
I need all the ellipse-like structures which are in between the two squares close to the middle of the image. I don't know the number of classes present in it.
Input image:
Ground truth:
My output:
If you want to explode the label image to different connected components you need to use a loop to extract labels for each class and sum label images to get the out label image.
u = unique(seg(:));
out = zeros(size(seg));
num_objs = 0;
for k = 1: numel(u)
mask = seg==u(k);
[L,N] = bwlabel(mask);
L(mask) = L(mask) + num_objs;
out = out + L;
num_objs = num_objs + N ;
end
mp = jet(num_objs);
figure,imshow(out,mp)
Something like this is produced:
I have tried to do everything out of scratch. I wish it is of some help.
I have a treatment chain that get at first contours with parameters tuned on a trial-and-error basis, I confess. The last "image" is given at the bottom ; with it, you can easily select the connected components and do for example a reconstruction by markers using "imreconstruct" operator.
clear all;close all;
I = imread('C:\Users\jean-marie.becker\Desktop\imagesJPG10\spinalchord.jpg');
figure,imshow(I);
J = I(:,:,1);% select the blue channel because jpg image
J=double(J<50);% I haven't inverted the image
figure, imshow(J);
se = strel('disk',5);
J=J-imopen(J,se);
figure, imshow(J);
J=imopen(J,ones(1,15));% privilegizes long horizontal strokes
figure, imshow(J);
K=imdilate(J,ones(20,1),'same');
% connects verticaly not-to-far horizontal "segments"
figure, imshow(K);

From image to vector and vice versa, rotated image

I read a DICOM image and for a variety of reasons, I had to turn the image matrix in a row vector.
After performing various operations on the bits of the vector, I need to reprocess the vector in a DICOM image of the same size as the original.
I've done all these steps but when I go to display the resulting image, this is rotated.
This is what I get:
That's part of the code:
function [I0, Iw] = watIns(filename, w)
I0 = dicomread(filename);
figure(1);
imshow(I0, []);
title('(1) I0 originale');
info = dicominfo(filename);
width = info.Width;
height = info.Height;
size = info.FileSize;
k = info.BitDepth;
% I extract the first k pixels and memorize their LBS in a variable S.
x = 1 : k;
y = 1;
firstKPixel = I0(x, y);
% convert in binary
firstKPixel2 = 0*firstKPixel;
for i = 1 : length(firstKPixel)
if firstKPixel(i) == 0
firstKPixel2(i) = 0;
else
firstKPixel2(i) = dec2bin(firstKPixel(i), 'left-msb');
end
end
% I take the LSB of each element in firstKPixel2 and concatenate in the string S
S = '';
for i = 1 : k
c = firstKPixel2(i, :);
s = num2str(c(end));
S = strcat(S, s);
end
% I compute the vector corresponding to I0 but without the first 0 pixels and the corresponding histogram
[vecComp, histComp] = histKtoEnd(I0, 0, k);
% I compute the vector corresponding to I0 but without the first k pixels and the corresponding histogram
[vecWithoutKPixel, histWithoutKPixel] = histKtoEnd(I0, k, k);
L = ...; % is a vector of values
% I save l_0 in the LSB of the first k pixels.
% prendo l_0, ovvero il primo elemento di L
l_0 = L(1);
l_02 = fliplr(bitget(l_0, 1:k));
% I take the LSB of each element in firstKPixel2 and I sret it to the i-th element of l0_2
for i = 1 : k
c = firstKPixel2(i, :);
c(end) = l_02(i);
firstKPixel2(i, :) = c;
end
% convert to decimal each element of firstKPixel2
for i = 1 : length(firstKPixel2)
str = int2str(firstKPixel2(i));
firstKPixel2_lsb10(i) = bin2dec(str);
end
% I set first k pixels in the image to those just modified
vecComp(1 : k) = firstKPixel2_lsb10(1 : k);
% Transform the vector image
mat = reshape(vecComp, [width, height]);
dicomwrite(mat, './I1.dcm', 'CompressionMode', 'None');
I1 = dicomread('./I1.dcm');
figure(7);
imshow(I1, []); % ROTATE IMAGE!!!
% ...
end
histKtoEnd function is:
function [vecWithoutKPixel, hist] = histKtoEnd(image, k, colorDepth)
imageVec = reshape(image.', [], 1);
l = length(imageVec);
vecWithoutKPixel = imageVec((k+1) : l-1);
vecWithoutKPixel(end+1) = imageVec(l);
hist = zeros(1, 2^colorDepth);
for i = 0 : (2^colorDepth - 1)
grayI = (vecWithoutKPixel == i);
hist(1, i+1) = sum(grayI(:));
end
end
I read here that Matlab shows images like a matrix with the first coordinates (rows) going top-down and the second (columns) left-right.
I couldn't solve, can anyone help me?
Thank you!
Somehow in the unrolling, processing and rolling of your data it seems to get transposed. You can try to find why that happens, but if you do not care, you can always just transpose the result in the end by
mat = reshape(vecComp, [width, height]).';

calculate histogram of 2 variables

I have a vector containining the speed of 200 walks:
a = 50;
b = 100;
speed = (b-a).*rand(200,1) + a;
and another vector contaning the number of steps for each walk:
a = 8;
b = 100;
steps = (b-a).*rand(200,1) + a;
I would like to create a histogram plot with on the x axis the speeds and on the y axes the sum of the steps of each speed.
What I do is the following but I guess there is a more elegant way to do this:
unique_speed = unique(speed);
y_unique_speed = zeros(size(unique_speed));
for i = 1 : numel(unique_speed)
speed_idx = unique_speed(i);
idx = speed==speed_idx ;
y_unique_speed (i) = sum(steps (idx));
end
First you need to discretize your speed variable. Unlike in the other answer, the following allows you to choose arbitrary step size, e.g. I've chosen 1.5. Note that the last bin edge should be strictly more than the maximum data point, hence I used max(speed)+binstep. You can then use histc to determine which bin each pairs falls into, and accumarray to determine total number of steps in each bin. Finally, use bar to plot.
binstep = 1.5;
binranges = (min(speed):binstep:max(speed)+binstep)';
[~, ind] = histc(speed, binranges);
bincounts = accumarray(ind, steps, size(binranges));
hFig = figure(); axh = axes('Parent', hFig); hold(axh, 'all'); grid(axh, 'on');
bar(axh, binranges, bincounts); axis(axh, 'tight');
First, bin the speed data to discrete values:
sspeed = ceil(speed);
and then accumulate the various step sizes to each bin:
numsteps = accumarray(sspeed, steps);
plot(numsteps)

Running matlab code through a folder

I have the following code for which instead of loading one image at a time, I'd like to run through every image in a folder (the defective folder in this code). I'd like the output to be an array containing the values of 'G' for each of the input images. I'm not too sure how to go about this - so any points appreciated. Many thanks!
%PCA code,
img = imread('C:\users\m7-miller\desktop\250images\defective\inkblob01.png');
img_gray = rgb2gray(img);
img_gray_double = im2double(img_gray);
figure,
set(gcf,'numbertitle','off','name','Grayscale Image'),
imshow(img_gray_double)
%find mean of the image
img_mean = mean(img_gray_double);
[m n] = size(img_gray);
%Make column vector of mean image value
new_mean = repmat(img_mean,m,1);
%Mean corrected image
Corrected_img = img_gray_double - new_mean;
%Covariance matrix of corrected image
cov_img = cov(Corrected_img);
%Eigenvalues of covariance matrix - columns of V are e-vectors,
%diagonals of D e-values
[V, D] = eig(cov_img);
V_T = transpose(V);
Corrected_image_T = transpose(Corrected_img);
FinalData = V_T * Corrected_image_T;
% Image approximation by choosing only a selection of principal components
PCs = 3;
PCs = n - PCs;
Reduced_V = V;
for i = 1:PCs,
Reduced_V(:,1) =[];
end
Y=Reduced_V'* Corrected_image_T;
Compressed_img = Reduced_V*Y;
Compressed_img = Compressed_img' + new_mean;
figure,
set(gcf,'numbertitle','off','name','Compressed Image'),
imshow(Compressed_img)
% End of image compression
% Difference of original image and compressed
S = (img_gray_double - Compressed_img);
figure,
set(gcf,'numbertitle','off','name','Difference'),
imshow(S)
% Sum of the differences
F = sum(S);
G = sum(F)
Are you looking for the dir command?
files = dir('*.png');
for n=1:size(files,1)
filename = files(n).name;
img = imread(filename);
....
G = sum(F);
end

how to obtain the eigenfaces using eigenvalues and eigen vectors?

i want to find eigenfaces from eigen values here is the code for reference.
clc;
clear all;
close all;
% I) READ IMAGES
for i = 1:9
img{i} = imread(['C:\Users\shree\Desktop\archana\target\' num2str(i) '.jpg']);
end
%II) CONVERTING TO GRAY SCALE
gray_img=cellfun(#rgb2gray,img,'uniformoutput',false);
%imshow(gray_img{2});
%III) RESIZING GRAY IMAGES
res_img = cellfun(#(x)(imresize(x, [50, 50])), gray_img, 'UniformOutput', false);
%imshow(res_img{2});
%DISPLAYING ALL IMAGE
D=[res_img{1} res_img{2} res_img{3}
res_img{4} res_img{5} res_img{6}
res_img{7} res_img{8} res_img{9}];
figure, imshow(D);
%MEAN IMAGE
mean_img=(res_img{1}+res_img{2}+res_img{3}+res_img{4}+res_img{5}+res_img{6}+res_img{7}+res_img{8}+res_img{9})/9;
figure,imshow(mean_img);
%III)SINGLE VECTOR CONVERSION
vect_img= cellfun(#(x)((x(:))), res_img, 'UniformOutput', false);
%MEAN OF SINGLE VECTOR
mean_vect=(vect_img{1}+vect_img{2}+vect_img{3}+vect_img{4}+vect_img{5}+vect_img{6}+vect_img{7}+vect_img{8}+vect_img{9})/9;
%DEVIATION MATRIX
dev_mat=cellfun(#(x) ((x)-mean_vect),vect_img,'uniformoutput',false);
%imshow(dev_mat{1})
U=[dev_mat{1} dev_mat{2} dev_mat{3} dev_mat{4} dev_mat{5} dev_mat{6} dev_mat{7} dev_mat{8} dev_mat{9} ]
figure ,imshow(U);
%COVARIENCE MATRIX
C=[double(U')*double(U)]/9;
%VARIENCE
v=var(C);
%EIGEN VALUES
lambda = eig(C);
[V,D] = eig(C) ;% eigenvalues (D) & eigenvectors (V),=> A*V = V*D
size(lambda);
% EXTRACT DIONAL OF MATRIX VECTOR
%V = diag(V);
%SORT VARIENCE ACC.DECREASING ORDER
sort(lambda,'descend');
i reached upto the arranging the eiganvalues into non-increasing order plz help me how to procced in order to get the eigenfaces.regards
Instead of loading each file one by one try this
ImageDatabasePath ='C:\Users\shree\Desktop\final data';
ImageFiles = dir(ImageDatabasePath);
Train_Number = 0;
for i = 1:size(ImageFiles,1)
if not(strcmp(ImageFiles(i).name,'.')|strcmp(ImageFiles(i).name,'..')...
|strcmp(ImageFiles(i).name,'Thumbs.db'))
Image_Number = Image_Number + 1;
end
end
Now to make the images into 1D image vectors
T = [ ];
for i = 1 : Image_Number
str = int2str(i);
str = strcat('\',str,'.jpg');
str = strcat(ImageDatabasePath,str);
imt = imread(str);
[irow icol] = size(imt);
temp = reshape(imt,irow*icol,1);
T = [T temp];
end
Calculates mean value
m = mean(T,2);
Train_Number = size(T,2);
Calculates the deviation of each image from the mean image
A = [ ];
for i = 1 : Image_Number
temp = double(T(:,i)) - m;
A = [A temp];
end
Create covariance matrix
L = A'*A;
Calculate eigen values and eigen vector V-eigen vector D-diagonal matrix with eigen values
[V D] = eig(L);
L_eig_vec = [];
for i = 1 : size(V,2)
if( D(i,i)>1 )
L_eig_vec = [L_eig_vec V(:,i)];
end
end
Eigenvectors of covariance matrix C (or so-called "Eigenfaces") can be recovered from L's eiegnvectors.
Eigenfaces = A * L_eig_vec;
Use double(NEW) * double(NEW');
Besides, do not use mean and cov as variable name. They are built-in functions. I guess you want C = cov(double(NEW) * double(NEW')); in the covariance calculation.