difference between histcounts and imhist matlab - matlab

histcounts and imhist are not returning the same values for counts and bin locations.
x = [0.5000, 0.6429, 0.7143, 0.6429, 0.7857, 0.2857, 0.8571, 0.6429,0, 0.7857, 0.9286, 1.0000, 0.1429, 0.8571, 0.2857, 0.8571, 0.5714, 0.0714];
[c1, l1] = histcounts(x, 6)
c1 =
3 2 1 4 3 5
l1 =
0 0.1700 0.3400 0.5100 0.6800 0.8500 1.0200
[c2, l2] = imhist(x, 6)
c2 =
2 3 0 5 6 2
l2 =
0 0.2000 0.4000 0.6000 0.8000 1.0000
What could be the reason for that?

MATLAB
close all;clear all;clc
nbins=[6 16 26 46]
x = [0.5000, 0.6429, 0.7143, 0.6429, 0.7857, 0.2857, 0.8571, ...
0.6429,0, 0.7857, 0.9286, 1.0000, 0.1429, 0.8571, 0.2857, 0.8571, 0.5714, 0.0714];
one can take it from one side
for k=1:1:numel(nbins)
figure(k);
ax=gca;hold on;grid on
[C1, L1] = histcounts(x,nbins(k));
stem(L1(1:end-1),C1);hold on
[C2, L2] = imhist(x,nbins(k));
stem(ax,L2,C2)
end
or from the other, stem graphs not shown, quite similar to the above ones.
for k=1:1:numel(nbins)
figure(k);
ax=gca;hold on;grid on
[C1, L1] = histcounts(x,nbins(k));
stem(L1(2:end),C1);hold on
[C2, L2] = imhist(x,nbins(k));
stem(ax,L2,C2)
end
The point : imhist is a command for images and it applies an offset to all histogram bin locations depending upon the type of image fed in.
imhist doesn't have a cut-off for tiny images, so the sequence x is assumed as image, which it is not.
Read imhist details here.
In particular this table shows such offset

Related

optimization of a linear system of inequalites

We are given four points, assumed to be ordered:
A = sort(randn(1,4))
I want to find the maximum possible number x in the interval 0<x<1 such that
A(1)<x<A(2) or A(3)<x<A(4)
Some examples:
A = [-1.4924 0.3004 1.6630 2.1204], x = 0.3004
A = [-0.4754 0.1353 0.6552 1.3873]; x = 1.0000
A = [-1.0213 -0.4521 -0.0905 0.1000]; x = 0.1000
A = [-1.8258 -0.5790 -0.4568 -0.1950]; x = 0.0000
A = [ 1.5000 2.0000 2.5000 3.0000]; x = 1.0000
Can you suggest a compact code to do this job, without having to list all the possible scenarios using if statements?
Having tried to do this with no if statements, I found that the readability of the code was greatly diminished. Note that there is only a single if statement in the code below while several other if statements could be substituted for the logical comparisons.
All of your tests pass and the code remains very concise (9 lines without the comments and loop over all of the tests).
A = [[-1.4924 0.3004 1.6630 2.1204];
[-0.4754 0.1353 0.6552 1.3873];
[-1.0213 -0.4521 -0.0905 0.1000];
[-1.8258 -0.5790 -0.4568 -0.1950];
[ 1.5000 2.0000 2.5000 3.0000]];
for i = 1:size(A,1)
% Reshape A so that each set of 2 entries are compared
Atmp = reshape(A(i,:),2,2);
% Find any valid entries
Valid = Atmp > 0 & Atmp < 1;
Ind_Valid = find(Valid == 1);
if (~isempty(Ind_Valid))
% If there are valid entries, return:
% max(A(ind),0) if the entry is the 1st of the pair
% max(A(ind),1) if the entry is the 2nd of the pair
max_Ind = max(Ind_Valid);
x = max(Atmp(max_Ind),mod(max_Ind,2))
else
% If there are no valid entries, return:
% 0 if max A < 0
% 1 if max A > 1
x = max(Atmp(:)) > 0
end
end
Output:
x =
0.3004
x =
1
x =
0.1000
x =
0
x =
1

matlab store multiple outputs of function from loop in matrix

i am trying to save the output of the following function (it gives two outputs for every iteration of input 1, the rest remains the same).
The function creates a stress testing for an interbank market, testing for the effects (output is capital_losses and defaulted_banks) of default of every bank in the sample, i.e. input1 must go from 1:(length(input2), 4 in the code provided here, 300+ in the final code, so i need a loop
here a sample of one iteration with bank 3 defaulting
input1 = 3; % default_bank
input2=[100000;200000;300000;400000]; % capital levels in the function
input3 = ...
[70000, 15000, 24000, 52453;
23420, 24252, 10000, 35354;
98763, 45666, 96555, 05000;
09800, 54444, 04336, 67520]; % interbank loans in the function
input4 = 1;
input5 = .35;
input6 = 1;
% function calls on above inputs
[capital_losses defaulted_banks] = interbank_model( ...
input1, input2, input3, input4, input5, input6)
this is the standard output for one iteration with default_bank=3, but I need this for 300+, so a loop would be helpful...
capital_losses3 =
1.0e+05 *
0.5857
0.2598
3.0000
0.0609
defaulted_banks3 =
0
0
1
0
I would like to get the output for every defaulted bank, i.e. default_bank=1:4 to be displayed by the for loop as follows:
capital_losses_all =
1.0e+05 *
1.0000 0.2320 0.5857 0.5857
0.2867 2.0000 0.2598 0.2598
1.0716 0.4917 3.0000 3.0000
0.2816 0.6682 0.0609 0.0609
defaulted_banks_all =
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
This was manually generated, but how do i store the values in matrices?
Thanks for your help. (I had a similar question before but the editing and commenting got very confusing so here's my improved cry for help... )
Chris
Very general answer (adapt for your need):
valuesThatChange = [1 3 5 4 2]; % different for each iteration in the loop
% values that don't change:
a=1;
b=2;
c=3;
N = numel(valuesThatChange);
% create storage for results:
results = zeros(4, N);
% loop N times
for ii=1:N
results(:,ii) = functionCall(valuesThatChange(ii), a, b, c); % returns a 4 element result
end
Now you have the result from your function for each loop in a 4xN matrix.

MATLAB: How to calculate (on) Submatrices without a loop

I want to split a matrix columnwise into 3 segments and do a calculation on it (mean()). Is there a way to get this without a for-loop, as I did in this provided sample?
M = [2 4 9; 50 50 200; 30 0 0];
M = [M 10*M]
N = length(M);
seg = 3 % split in lets say 3 parts
segLen = round(N/seg)
segBeg = (((1:seg)-1) * segLen)+1 % start indices
segEnd = segBeg + segLen -1 % end indices
for i = 1: length(segBeg)
mean(M(:,segBeg(i):segEnd(i)),2)
end
Thank you!
Think outside the box: use the 3rd dimension:
r=reshape(M,size(M,1),segLen,[])
squeeze(mean(r,2))
The first line produces a 3d array with the first matrix at r(:,:,1), the second at r(:,:,2), ... (use M(:,1:seg*segLen) instread of M if the number of columns is not divisible by segLen).
mean(r,2) produces a nrows-by-1-by-seg array, squeeze makes a nrows-by-seg matrix out of it again.
You can use arrayfun together with cell2mat
result = cell2mat(arrayfun(#(x,y) mean(M(:,x:y),2), segBeg, segEnd,...
'UniformOutput', false))
This results in
result =
1.0e+03 *
0.0030 0.0145 0.0650
0.0500 0.3500 1.2500
0.0150 0.1500 0
where each column represents the mean across one submatrix.
Another solution using blockproc (like suggested by #DennisJaheruddin in the comments) could look like this
myFun = #(x) mean(x.data,2);
result2 = blockproc(M, [N, segLen], myFun)
This also results in
result2 =
1.0e+03 *
0.0030 0.0145 0.0650
0.0500 0.3500 1.2500
0.0150 0.1500 0
Note that blockproc can take advantage of parallel processing if the flag 'UseParallel' is set to true, i.e., result2 = blockproc(M, [N, segLen], myFun, 'UseParallel', true)
You can do for your example case
mean1 = mean(M(:,1:segLen))
mean2 = mean(M(:,segLen+1:N-segLen-1))
mean3 = mean(M(:,N-segLen:end))

Saving different 'graycoprops' properties values on a matrix [MATLAB]

I've a picture. I create the co-occurrence matrix (graycomatrix) to extract different properties (contrast, correlation) etc on it (graycoprops)
x = []
for a lot of pictures, do the same:
imgB = imread('currentLoopImage.jpg')
contrast = graycoprops(graycomatrix(rgb2gray(imgB)), 'Contrast')
correlation = graycoprops(graycomatrix(rgb2gray(imgB)), 'Correlation')
energy = graycoprops(graycomatrix(rgb2gray(imgB)), 'Energy')
homogeneity = graycoprops(graycomatrix(rgb2gray(imgB)), 'Homogeneity')
x = [x;contrast;correlation;energy;homogeneity]
The thing is that I need to save all the values on that matrix X, but I get the following error:
CAT arguments are not consistent in structure field names.
As this is the output I get from each type:
homogeneity =
Homogeneity: 0.8587
There are different types, so I can't save them on the X matrix.
The output matrix X, should save only the numbers, and ignore that "Homogenity"
Can someone tell me who can I do this?
From the graycoprops() example:
>> GLCM = [0 1 2 3;1 1 2 3;1 0 2 0;0 0 0 3];
>> stats = graycoprops(GLCM)
stats =
Contrast: 2.8947
Correlation: 0.0783
Energy: 0.1191
Homogeneity: 0.5658
Then just do:
>> x = struct2array(stats)
ans =
2.8947 0.0783 0.1191 0.5658
Also note that you can include all your images in an m x n x p matrix and process them all at once, instead of using the for loop. For example:
>> GLCM(:,:,2) = GLCM;
>> cell2mat(struct2cell(stats))
ans =
2.8947 2.8947
0.0783 0.0783
0.1191 0.1191
0.5658 0.5658

Triangulation & Direct linear transform

Following Hartley/Zisserman's Multiview Geometery, Algorithm 12: The optimal triangulation method (p318), I got the corresponding image points xhat1 and xhat2 (step 10). In step 11, one needs to compute the 3D point Xhat. One such method is Direct Linear Transform (DLT), mentioned in 12.2 (p312) and 4.1 (p88).
The homogenous method (DLT), p312-313, states that it finds a solution as the unit singular vector corresponding to the smallest singular value of A, thus,
A = [xhat1(1) * P1(3,:)' - P1(1,:)' ;
xhat1(2) * P1(3,:)' - P1(2,:)' ;
xhat2(1) * P2(3,:)' - P2(1,:)' ;
xhat2(2) * P2(3,:)' - P2(2,:)' ];
[Ua Ea Va] = svd(A);
Xhat = Va(:,end);
plot3(Xhat(1),Xhat(2),Xhat(3), 'r.');
However, A is a 16x1 matrix, resulting in a Va that is 1x1.
What am I doing wrong (and a fix) in getting the 3D point?
For what its worth sample data:
xhat1 =
1.0e+009 *
4.9973
-0.2024
0.0027
xhat2 =
1.0e+011 *
2.0729
2.6624
0.0098
P1 =
699.6674 0 392.1170 0
0 701.6136 304.0275 0
0 0 1.0000 0
P2 =
1.0e+003 *
-0.7845 0.0508 -0.1592 1.8619
-0.1379 0.7338 0.1649 0.6825
-0.0006 0.0001 0.0008 0.0010
A = <- my computation
1.0e+011 *
-0.0000
0
0.0500
0
0
-0.0000
-0.0020
0
-1.3369
0.2563
1.5634
2.0729
-1.7170
0.3292
2.0079
2.6624
Update Working code for section xi in algorithm
% xi
A = [xhat1(1) * P1(3,:) - P1(1,:) ;
xhat1(2) * P1(3,:) - P1(2,:) ;
xhat2(1) * P2(3,:) - P2(1,:) ;
xhat2(2) * P2(3,:) - P2(2,:) ];
A(1,:) = A(1,:)/norm(A(1,:));
A(2,:) = A(2,:)/norm(A(2,:));
A(3,:) = A(3,:)/norm(A(3,:));
A(4,:) = A(4,:)/norm(A(4,:));
[Ua Ea Va] = svd(A);
X = Va(:,end);
X = X / X(4); % 3D Point
As is mentioned in the book (sec 12.2), pi T are the rows of P. Therefore, you don't need to transpose P1(k,:) (i.e. the right formulation is A = [xhat1(1) * P1(3,:) - P1(1,:) ; ...).
I hope that was just a typo.
Additionally, it is recommended to normalize each row of A with its L2 norm, i.e. for all i
A(i,:) = A(i,:)/norm(A(i,:));
And if you want to plot the triangulated 3D points, you have to normalize Xhat before plotting (its meaningless otherwise), i.e.
Xhat = Xhat/Xhat(4);
A(1,:) = A(1,:)/norm(A(1,:));
A(2,:) = A(2,:)/norm(A(2,:));
A(3,:) = A(3,:)/norm(A(3,:));
A(4,:) = A(4,:)/norm(A(4,:));
Could be simplified as A = normr(A).