Local Histogram Separation Energy Implementation - matlab

I am working in level set method, specially Lankton method paper. I try to implement Histogram Separation (HS) Energy problem (Part III.C). It based on Bhattacharyya to control the evolution of contour. To understand it, the first we consider global method in which given an input image and a contour. The contour divides the image into inside and outside region. The Bhattacharyya distance is calculated by
B=sqrt (P_in.*P_out)
where P_in and P_pout are pdf of inside and outside regions.
To applied Bhattacharyya for global level set you can see source code at here. Now we return the Lankton paper. It is local level set. In which, he divides the image into small region by Ball function. Then, the contour will separate these regions into inside and outside region. Each small regions have P_in and P_out. And we can calculate Bhattacharyya distance. I done that step. But I cannot implement final step as formual. Can you help me???
and Av and Au is area of inside and outside of these regions. This is my main code. You can download at source code
for its = 1:max_its % Note: no automatic convergence test
%-- get the curve's narrow band
idx = find(phi <= 1.2 & phi >= -1.2)';
[y x] = ind2sub(size(phi),idx);
%-- get windows for localized statistics
xneg = x-rad; xpos = x+rad; %get subscripts for local regions
yneg = y-rad; ypos = y+rad;
xneg(xneg<1)=1; yneg(yneg<1)=1; %check bounds
xpos(xpos>dimx)=dimx; ypos(ypos>dimy)=dimy;
%-- re-initialize u,v,Ain,Aout
Ain=zeros(size(idx)); Aout=zeros(size(idx));
B=zeros(size(idx));integral=zeros(size(idx));
%-- compute local stats
for i = 1:numel(idx) % for every point in the narrow band
img = I(yneg(i):ypos(i),xneg(i):xpos(i)); %sub image
P = phi(yneg(i):ypos(i),xneg(i):xpos(i)); %sub phi
upts = find(P<=0); %local interior
Ain(i) = length(upts)+eps;
vpts = find(P>0); %local exterior
Aout(i) = length(vpts)+eps;
%% Bha distance
p = imhist(I(upts))/ Ain(i) + eps; % leave histograms unsmoothed
q = imhist(I(vpts)) / Aout(i) + eps;
B(i) = sum(sqrt(p.* q));
term2= sqrt(p./q)/Aout(i) - sqrt(q./p)/Ain(i); %Problem in here===I don't know how to code the integral term
integral(i) =sum(term2(:));
end
F =-B./2.*(1./Ain - 1./Aout) - integral./2;

I tried this - no idea if its correct - its has no histogram smoothing (I dont think it is necessary)
if type==3 % Set up for bhatt
F=zeros(size(idx,1),2);
for i = 1:numel(idx)
img2 = img(yneg(i):ypos(i),xneg(i):xpos(i));
P = phi(yneg(i):ypos(i),xneg(i):xpos(i));
upts = find(P<=0); %local interior
Ain = length(upts)+eps;
[u,~] = hist(img2(upts),1:256);
vpts = find(P>0); %local exterior
Aout = length(vpts)+eps;
[v,~] = hist(img2(vpts),1:256);
Ap = Ain;
Aq = Aout;
In=Ap;
Out=Aq;
try
p = ((u)) ./ Ap + eps;
q = ((v)) ./ Aq + eps;
catch
g
end
B = sum(sqrt(p .* q));
F(i)=B.*((1/numel(In))-(1/numel(Out)))+(0.5.*(1/numel(In)*(q(img(idx(i))+1)... /p(img(idx(i))+1))))-(0.5.*(1/numel(Out)*(p(img(idx(i))+1)/q(img(idx(i))+1))));
end

Related

Separate Double Moon Classification with A Line in Matlab

I have some Matlab code lines for drawing Double Moon Classification:
function data=dm(r,w,ts,d)
clear all; close all;
if nargin<4, w=6;end
if nargin<3, r=10;end
if nargin<2, d=-4;end
if nargin < 1, ts=1000; end
ts1=10*ts;
done=0; tmp1=[];
while ~done,
tmp=[2*(r+w/2)*(rand(ts1,1)-0.5) (r+w/2)*rand(ts1,1)];
tmp(:,3)=sqrt(tmp(:,1).*tmp(:,1)+tmp(:,2).*tmp(:,2));
idx=find([tmp(:,3)>r-w/2] & [tmp(:,3)<r+w/2]);
tmp1=[tmp1;tmp(idx,1:2)];
if length(idx)>= ts,
done=1;
end
end
data=[tmp1(1:ts,:) zeros(ts,1);
[tmp1(1:ts,1)+r -tmp1(1:ts,2)-d ones(ts,1)]];
plot(data(1:ts,1),data(1:ts,2),'.r',data(ts+1:end,1),data(ts+1:end,2),'.b');
title(['Perceptron with the double-moon set at distance d = ' num2str(d)]),
axis([-r-w/2 2*r+w/2 -r-w/2-d r+w/2])
save dm r w ts d data;
Results:
My question is how to put a line into the Double Moon Classification so that can separate both classification in Matlab code?
I have made a simulation of your problem and wrote a pragmatic solution based on the steps
generates a grid of points fine enough(step size as small as
possible)
find which of these points are in the space between both points
groups
find which points have an equal distance to both groups
plot points
The main part (without my data generation code and the plot I did) of the code is
PBlues = data(1:ts,:);
PReds = data(ts+1:end,:);
Xs = linspace( min(data(:,1)), max(data(:,1)), 100);
Ys = linspace( min(data(:,2)), max(data(:,2)), 100);
[Xs,Ys] = meshgrid( Xs, Ys);
%% compute point relative distance to each point set (ble and red)
bCouldbeInbetween = false(size(Xs));
minDistsb = zeros(size(Xs));
minDistsr = zeros(size(Xs));
for p=1:numel(Xs)
distb = sqrt( (Xs(p)- PBlues(:,1)).^2+(Ys(p)- PBlues(:,2)).^2);
distr = sqrt( (Xs(p)- PReds(:,1)).^2+(Ys(p)- PReds(:,2)).^2);
minDistsb(p) = min(distb);
minDistsr(p) = min(distr);
i = find(distb == minDistsb(p));
j = find(distr == minDistsr(p));
bCouldbeInbetween(p) = (sign(PBlues(i,1)-Xs(p)) ~= sign(PReds(j,1)-Xs(p))) || ...
(sign(PBlues(i,2)-Ys(p)) ~= sign(PReds(j,2)-Ys(p)));
if bCouldbeInbetween(p)
end
end
% point distance difference to each point set
DistDiffs = abs(minDistsb - minDistsr);
% point with equal distance using proportional decision strategy
bCandidates = DistDiffs./ max(minDistsb,minDistsr) < 0.05;
medianLine = [Xs(bCandidates),Ys(bCandidates)];
[~,I] = sort(medianLine(:,1));
medianLine(:,1) = medianLine(I,1);
medianLine(:,2) = medianLine(I,2);
I hope this helps
I have just made a submission which can be downloaded here: https://de.mathworks.com/matlabcentral/fileexchange/66618-linebetweentwopointsgroups-exchange--

How integral image influence the result of local binary pattern or center symmetric local binary pattern

I know this looks somehow not related to code errors and development but
I want to know if someone can understand these codes of
integral image and local binary pattern, and tell me how they affect the resulting histograms.
Before the use of integral image the output histogram is normal, but after applying the integral image method I found that most of the histogram changed to zeros. To clarify things, the expected benefit from the use of an integral image is to speed up the process of lbp method. In fact, I haven't seen this before because I'm trying it for the first time. Does anybody who knows about this may help me please?
These are the codes of every method:
Integral image
function [outimg] = integral( image )
[y,x] = size(image);
outimg = zeros(y+1,x+1);
disp(y);
for a = 1:y+1
for b = 1:x+1
rx = b-1;
ry = a-1;
while ry>=1
while rx>=1
outimg(a,b) = outimg(a,b)+image(ry,rx);
rx = rx-1;
end
rx = b-1;
ry = ry-1;
end
% outimg(a,b) = outimg(a,b)-image(a,b);
end
end
% outimg(1,1) = image(1,1);
disp('end loop');
end
CS-LBP
function h = CSLBP(I)
%% this function takes patch or image as input and return Histogram of
%% CSLBP operator.
h = zeros(1,16);
[y,x] = size(I);
T = 0.1; % threshold given by authors in their paper
for i = 2:y-1
for j = 2:x-1
% keeping I(j,i) as center we compute CSLBP
% N0 - N4
a = ((I(i,j+1) - I(i, j-1) > T ) * 2^0 );
b = ((I(i+1,j+1) - I(i-1, j-1) > T ) * 2^1 );
c = ((I(i+1,j) - I(i-1, j) > T ) * 2^2 );
d = ((I(i+1,j-1) - I(i - 1, j + 1) > T ) * 2^3 );
e = a+b+c+d;
h(e+1) = h(e+1) + 1;
end
end
end
Matlab has an inbuilt function for creating integral images, integralimage(). If you don't want to use the computer vision system toolbox you can achieve the same result by calling:
IntIm = cumsum(cumsum(double(I)),2);
Possibly adding padding if needed. You should check out that the image is not saturated, they do that sometimes. Calculating the cumulative sum goes to integers way above the range of uint8 and uint16 quickly, I even had it happen with a double once!

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)

HOG descriptor for multiple people detection

I am doing a real-time people detection using HOG-LBP descriptor and using a sliding window approach for the detector also LibSVM for the classifier. However, after classifier I never get multiple detected people, sometimes is only 1 or might be none. I guess I have a problem on my classification step. Here is my code on classification:
label = ones(length(featureVector),1);
P = cell2mat(featureVector);
% each row of P' correspond to a window
% classifying each window
[~, predictions] = svmclassify(P', label,model);
% set the threshold for getting multiple detection
% the threshold value is 0.7
get_detect = predictions.*[predictions>0.6];
% the the value after sorted
[r,c,v]= find(get_detect);
%% Creating the bounding box for detection
for ix=1:length(r)
rects{ix}= boxPoint{r(ix)};
end
if (isempty(rects))
rects2=[];
else
rects2 = cv.groupRectangles(rects,3,'EPS',0.35);
end
for i = 1:numel(rects2)
rectangle('Position',[rects2{i}(1),rects2{i}(2),64,128], 'LineWidth',2,'EdgeColor','y');
end
For the whole my code, I have posted here : [HOG with SVM] (sliding window technique for multiple people detection)
I really need a help for it. Thx.
If you have problems wiith the sliding window, you can use this code:
topLeftRow = 1;
topLeftCol = 1;
[bottomRightCol bottomRightRow d] = size(im);
fcount = 1;
% this for loop scan the entire image and extract features for each sliding window
for y = topLeftCol:bottomRightCol-wSize(2)
for x = topLeftRow:bottomRightRow-wSize(1)
p1 = [x,y];
p2 = [x+(wSize(1)-1), y+(wSize(2)-1)];
po = [p1; p2];
img = imcut(po,im);
featureVector{fcount} = HOG(double(img));
boxPoint{fcount} = [x,y];
fcount = fcount+1;
x = x+1;
end
end
lebel = ones(length(featureVector),1);
P = cell2mat(featureVector);
% each row of P' correspond to a window
[~, predictions] = svmclassify(P',lebel,model); % classifying each window
[a, indx]= max(predictions);

Simple Phase Shift for Removing Instrument Response

So I have a simple program where I want to shift a simple sine function pi/2. Now I knwo this would be extremely easy by just inserting a bias (i.e. A*sin(2*pi*frequency + bias). But this program is a simple way to test a theory. I need to shift complicated magnetic data, but the shift is frequency dependent. So to figure out how to do that I just want to shift this sin wave by a set shift, but I want to do it in the frequency domain. While the code below doesn't show any errors, it does not shift the data properly and effects magnitude. Code is below. Thank you!
clear all
time = 1:0.01:2*pi; %Create time vector
mag = sin(2*pi*time);
Y = fft(mag); %transform
Pnewr = pi/2;
%t = angle(mag);
t = imag(Y);
%t_fin = t-Pnewr; %Subtract the pahse delay from the original phase vector
R=real(Y);
I=t;
k = I./R
Phi = tan(k);
PhiFinal = Phi-Pnewr;
PhiFinal = PhiFinal'
IFinal = R * atan(PhiFinal);
spec=complex(R,IFinal);
Finalspec = ifft(spec); %Invert the transform
Final = Finalspec;
plot(time,mag);
hold on
plot(time,Final,'r')
grid on
For one thing you are not recombining imaginary and real components properly, since
PhiFinal = PhiFinal'
IFinal = R * atan(PhiFinal);
is effectively a dot product, not an element by element product. In general it doesn't look like you are making correct use of the complex relationships. The following generates a clean phase shift:
time = 1:0.01:2*pi;
mag = sin(2*pi*time);
Y = fft(mag); %transform
Pnewr = pi/2;
R = real(Y);
I = imag(Y);
It = abs(Y);
% It = sqrt(I.^2 + R.^2);
Phi= angle(Y); % <-- using matlab function, equivalent to `Phi = atan2(I, R);`
k = I./R;
Phi0 = atan(k);
figure, subplot(121), plot(Phi0,Phi,'.'), xlabel('Phi from tan'), ylabel('Phi from ''angle'''), grid on, axis('tight')
PhiFinal = Phi-Pnewr; % <-- phase shift
IFinal = It .* sin(PhiFinal);
RFinal = It .* cos(PhiFinal);
spec= RFinal + 1i*IFinal;
Final = ifft(spec); %Invert the transform
subplot(122)
plot(time,mag);
hold on
plot(time,real(Final),'r')
plot(time,imag(Final),'r:')
grid on
axis('tight')
legend('Initial','Final'),xlabel('t'), ylabel('I')
mag*mag' % <-- check that total power is conserved
Final*Final'
These figures show the phase as computed with tan vs matlab's angle (which uses atan2), and the results of the phase shift (right panel):