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.
I have a non-uniform rectangular grid along D dimensions, a matrix of logical values V on the grid, and a matrix of query data points X. The number of grid points differs across dimensions.
I run the interpolation multiple times for the same grid G and query X, but for different values V.
The goal is to precompute the indexes and weights for the interpolation and to reuse them, because they are always the same.
Here is an example in 2 dimensions, in which I have to compute indexes and values every time within the loop, but I want to compute them only once before the loop. I keep the data types from my application (mostly single and logical gpuArrays).
% Define grid
G{1} = single([0; 1; 3; 5; 10]);
G{2} = single([15; 17; 18; 20]);
% Steps and edges are reduntant but help make interpolation a bit faster
S{1} = G{1}(2:end)-G{1}(1:end-1);
S{2} = G{2}(2:end)-G{2}(1:end-1);
gpuInf = 1e10;
% It's my workaround for a bug in GPU version of discretize in Matlab R2017a.
% It throws an error if edges contain Inf, realmin, or realmax. Seems fixed in R2017b prerelease.
E{1} = [-gpuInf; G{1}(2:end-1); gpuInf];
E{2} = [-gpuInf; G{2}(2:end-1); gpuInf];
% Generate query points
n = 50; X = gpuArray(single([rand(n,1)*14-2, 14+rand(n,1)*7]));
[G1, G2] = ndgrid(G{1},G{2});
for i = 1 : 4
% Generate values on grid
foo = #(x1,x2) (sin(x1+rand) + cos(x2*rand))>0;
V = gpuArray(foo(G1,G2));
% Interpolate
V_interp = interpV(X, V, G, E, S);
% Plot results
subplot(2,2,i);
contourf(G1, G2, V); hold on;
scatter(X(:,1), X(:,2),50,[ones(n,1), 1-V_interp, 1-V_interp],'filled', 'MarkerEdgeColor','black'); hold off;
end
function y = interpV(X, V, G, E, S)
y = min(1, max(0, interpV_helper(X, 1, 1, 0, [], V, G, E, S) ));
end
function y = interpV_helper(X, dim, weight, curr_y, index, V, G, E, S)
if dim == ndims(V)+1
M = [1,cumprod(size(V),2)];
idx = 1 + (index-1)*M(1:end-1)';
y = curr_y + weight .* single(V(idx));
else
x = X(:,dim); grid = G{dim}; edges = E{dim}; steps = S{dim};
iL = single(discretize(x, edges));
weightL = weight .* (grid(iL+1) - x) ./ steps(iL);
weightH = weight .* (x - grid(iL)) ./ steps(iL);
y = interpV_helper(X, dim+1, weightL, curr_y, [index, iL ], V, G, E, S) +...
interpV_helper(X, dim+1, weightH, curr_y, [index, iL+1], V, G, E, S);
end
end
I found a way to do this and posting it here because (as of now) two more people are interested. It takes only a slight modification to my original code (see below).
% Define grid
G{1} = single([0; 1; 3; 5; 10]);
G{2} = single([15; 17; 18; 20]);
% Steps and edges are reduntant but help make interpolation a bit faster
S{1} = G{1}(2:end)-G{1}(1:end-1);
S{2} = G{2}(2:end)-G{2}(1:end-1);
gpuInf = 1e10;
% It's my workaround for a bug in GPU version of discretize in Matlab R2017a.
% It throws an error if edges contain Inf, realmin, or realmax. Seems fixed in R2017b prerelease.
E{1} = [-gpuInf; G{1}(2:end-1); gpuInf];
E{2} = [-gpuInf; G{2}(2:end-1); gpuInf];
% Generate query points
n = 50; X = gpuArray(single([rand(n,1)*14-2, 14+rand(n,1)*7]));
[G1, G2] = ndgrid(G{1},G{2});
[W, I] = interpIW(X, G, E, S); % Precompute weights W and indexes I
for i = 1 : 4
% Generate values on grid
foo = #(x1,x2) (sin(x1+rand) + cos(x2*rand))>0;
V = gpuArray(foo(G1,G2));
% Interpolate
V_interp = sum(W .* single(V(I)), 2);
% Plot results
subplot(2,2,i);
contourf(G1, G2, V); hold on;
scatter(X(:,1), X(:,2), 50,[ones(n,1), 1-V_interp, 1-V_interp],'filled', 'MarkerEdgeColor','black'); hold off;
end
function [W, I] = interpIW(X, G, E, S)
global Weights Indexes
Weights=[]; Indexes=[];
interpIW_helper(X, 1, 1, [], G, E, S, []);
W = Weights; I = Indexes;
end
function [] = interpIW_helper(X, dim, weight, index, G, E, S, sizeV)
global Weights Indexes
if dim == size(X,2)+1
M = [1,cumprod(sizeV,2)];
Weights = [Weights, weight];
Indexes = [Indexes, 1 + (index-1)*M(1:end-1)'];
else
x = X(:,dim); grid = G{dim}; edges = E{dim}; steps = S{dim};
iL = single(discretize(x, edges));
weightL = weight .* (grid(iL+1) - x) ./ steps(iL);
weightH = weight .* (x - grid(iL)) ./ steps(iL);
interpIW_helper(X, dim+1, weightL, [index, iL ], G, E, S, [sizeV, size(grid,1)]);
interpIW_helper(X, dim+1, weightH, [index, iL+1], G, E, S, [sizeV, size(grid,1)]);
end
end
To do the task the whole process of interpolation ,except computing the interpolated values, should be done. Here is a solution translated from the Octave c++ source. Format of the input is the same as the frst signature of the interpn function except that there is no need to the v array. Also Xs should be vectors and should not be of the ndgrid format. Both the outputs W (weights) and I (positions) have the size (a ,b) that a is the number of neighbors of a points on the grid and b is the number of requested points to be interpolated.
function [W , I] = lininterpnw(varargin)
% [W I] = lininterpnw(X1,X2,...,Xn,Xq1,Xq2,...,Xqn)
n = numel(varargin)/2;
x = varargin(1:n);
y = varargin(n+1:end);
sz = cellfun(#numel,x);
scale = [1 cumprod(sz(1:end-1))];
Ni = numel(y{1});
index = zeros(n,Ni);
x_before = zeros(n,Ni);
x_after = zeros(n,Ni);
for ii = 1:n
jj = interp1(x{ii},1:sz(ii),y{ii},'previous');
index(ii,:) = jj-1;
x_before(ii,:) = x{ii}(jj);
x_after(ii,:) = x{ii}(jj+1);
end
coef(2:2:2*n,1:Ni) = (vertcat(y{:}) - x_before) ./ (x_after - x_before);
coef(1:2:end,:) = 1 - coef(2:2:2*n,:);
bit = permute(dec2bin(0:2^n-1)=='1', [2,3,1]);
%I = reshape(1+scale*bsxfun(#plus,index,bit), Ni, []).'; %Octave
I = reshape(1+sum(bsxfun(#times,scale(:),bsxfun(#plus,index,bit))), Ni, []).';
W = squeeze(prod(reshape(coef(bsxfun(#plus,(1:2:2*n).',bit),:).',Ni,n,[]),2)).';
end
Testing:
x={[1 3 8 9],[2 12 13 17 25]};
v = rand(4,5);
y={[1.5 1.6 1.3 3.5,8.1,8.3],[8.4,13.5,14.4,23,23.9,24.2]};
[W I]=lininterpnw(x{:},y{:});
sum(W.*v(I))
interpn(x{:},v,y{:})
Thanks to #SardarUsama for testing and his useful comments.
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]).';
I've been trying to implement a function called histogram(image) that perform the color histogram of an RGB image.
Can someone show me a sample that is easy to analyze in order to understand how does it exactly work.
I would really appreciate your help.
Here is a different algorithm for your question:
im = imread('lena.png'); % imshow(im);
histogram(im)
function histogram(im)
[rowSize, colSize, rgb] = size(im);
nshades = 256;
hist = zeros(rgb, nshades);
figure,
RGB = ['r', 'g', 'b'];
names = [{'Red Channel'}, {'Green Channel'}, {'Blue Channel'}];
x = 0 : 255;
for colour = 1 : rgb
for k = 1 : rowSize
for m = 1 : colSize
for n = 0 : (nshades - 1) % 0 - 255
if im(k, m, colour) == n
hist(colour, n + 1) = hist(colour, n + 1) + 1;
end
end
end
end
subplot(3, 1, colour)
bar(x, hist(colour, :), RGB(colour)); title(names(colour));
end
end
Here is the code which draws histogram of each color channels of an image.
I=imread('lena.png');
r=I(:,:,1);
g=I(:,:,2);
b=I(:,:,3);
totalNumofPixel=size(I,1)*size(I,2);
FrequencyofRedValues=zeros(256,1);
FrequencyofGreenValues=zeros(256,1);
FrequencyofBlueValues=zeros(256,1);
for x=0:255
FrequencyofRedValues(x+1)=size(r(r==x),1); // number of pixels whoose intensity is x
FrequencyofGreenValues(x+1)=size(g(g==x),1);
FrequencyofBlueValues(x+1)=size(b(b==x),1);
end
stem(0:255,FrequencyofRedValues,'.r');
title('Red Channel Histogram');
figure
stem(0:255,FrequencyofGreenValues,'.g');
title('Green Channel Histogram');
figure
stem(0:255,FrequencyofBlueValues,'.b');
title('Blue Channel Histogram');
I am working on rotating image manually in Matlab. Each time I run my code with a different image the previous images which are rotated are shown in the Figure. I couldn't figure it out. Any help would be appreciable.
The code is here:
[screenshot]
im1 = imread('gradient.jpg');
[h, w, p] = size(im1);
theta = pi/12;
hh = round( h*cos(theta) + w*abs(sin(theta))); %Round to nearest integer
ww = round( w*cos(theta) + h*abs(sin(theta))); %Round to nearest integer
R = [cos(theta) -sin(theta); sin(theta) cos(theta)];
T = [w/2; h/2];
RT = [inv(R) T; 0 0 1];
for z = 1:p
for x = 1:ww
for y = 1:hh
% Using matrix multiplication
i = zeros(3,1);
i = RT*[x-ww/2; y-hh/2; 1];
%% Nearest Neighbour
i = round(i);
if i(1)>0 && i(2)>0 && i(1)<=w && i(2)<=h
im2(y,x,z) = im1(i(2),i(1),z);
end
end
end
end
x=1:ww;
y=1:hh;
[X, Y] = meshgrid(x,y); % Generate X and Y arrays for 3-D plots
orig_pos = [X(:)' ; Y(:)' ; ones(1,numel(X))]; % Number of elements in array or subscripted array expression
orig_pos_2 = [X(:)'-(ww/2) ; Y(:)'-(hh/2) ; ones(1,numel(X))];
new_pos = round(RT*orig_pos_2); % Round to nearest neighbour
% Check if new positions fall from map:
valid_pos = new_pos(1,:)>=1 & new_pos(1,:)<=w & new_pos(2,:)>=1 & new_pos(2,:)<=h;
orig_pos = orig_pos(:,valid_pos);
new_pos = new_pos(:,valid_pos);
siz = size(im1);
siz2 = size(im2);
% Expand the 2D indices to include the third dimension.
ind_orig_pos = sub2ind(siz2,orig_pos(2*ones(p,1),:),orig_pos(ones(p,1),:), (1:p)'*ones(1,length(orig_pos)));
ind_new_pos = sub2ind(siz, new_pos(2*ones(p,1),:), new_pos(ones(p,1),:), (1:p)'*ones(1,length(new_pos)));
im2(ind_orig_pos) = im1(ind_new_pos);
imshow(im2);
There is a problem with the initialization of im2, or rather, the lack of it. im2 is created in the section shown below:
if i(1)>0 && i(2)>0 && i(1)<=w && i(2)<=h
im2(y,x,z) = im1(i(2),i(1),z);
end
If im2 exists before this code is run and its width or height is larger than the image you are generating the new image will only overwrite the top left corner of your existing im2. Try initializing im2 by adding adding
im2 = zeros(hh, ww, p);
before
for z = 1:p
for x = 1:ww
for y = 1:hh
...
As a bonus it might make your code a little faster since Matlab won't have to resize im2 as it grows in the loop.