Detect and count the number of people in an image using matlab - algorithm

Counting the number of people in a room using MatLab but couldn't do it accurately using Viola-Jones Algorithm. can someone help me out, please?
%Detect objects using Viola-Jones Algorithm
%% CODE FOR PEOPLE COUNT BASED ON FACES
%get the input image
I=imread('DCN.jpg')*2;
imshow(I),title('Image:1');
J = rgb2gray(I);
%To detect Face
FDetect = vision.CascadeObjectDetector;
% Returns Bounding Box values based on number of objects
BB = step(FDetect,J);
figure,
%detectedImg = insertObjectAnnotation(J,'rectangle',BB,'stop sign');
%
imshow(J); hold on
for i = 1:size(BB,1)
rectangle('Position',BB(i,:),'LineWidth',2,'LineStyle','-','EdgeColor','y');
end
title('Face Detection');
hold off;
numberOfBlobs = length(BB);
message = sprintf('Done by Abhishek.\nThe number of persons = %d', numberOfBlobs);
uiwait(helpdlg(message));

You can use another well known algorithm for pedestrian detection using HOG an svm.
Look at the following tutorial for Matlab.
https://www.mathworks.com/help/vision/ref/vision.peopledetector-class.html

Related

How to detect defect/missing pills in blister pack? (Matlab)

How do I detect defect/missing tablets in the tablet strips. Assuming there is one missing tablet in the tablet strip. I've tried stdfilt(), but the image contains alot noise .I ve also tried average and median filtring such as canny and prewitt. I also added noise such as salt and paper to the image.
Is there any othe segmentation method? Any coding will be helpful
I2=rgb2gray(I);
J = imnoise(I2,'salt & pepper',0.02);
figure
imshow(J)
Kaverage = filter2(fspecial('average',3),J)/255;
figure
imshow(Kaverage)
Kmedian = medfilt2(J);
imshowpair(Kaverage,Kmedian,'montage')
BW1 = edge(Kmedian,'Canny');
BW2 = edge(Kmedian,'Prewitt');`
Here's an approach based on my comment
% reduce to grayscale
d=rgb2gray(your_img);
% find edge and blur a bit so we can find circles
d2=conv2(edge(d),ones(9),'same');
d2=max(d2(:))-d2;
% find circles
Rmin = 71; Rmax = 80;
[center, radius] = imfindcircles(d2,[Rmin Rmax],'Sensitivity',0.98);
% Display what we found
imagesc(d);axis square
hold on;
viscircles(center,radius);
plot(center(:,1),center(:,2),'yx','LineWidth',2);
hold off;
% histogram of each circle content:
[x, y]=meshgrid(1:size(d,2),1:size(d,1));
for n=1:numel(radius)
circle_pixels{n}=find ((x-center(n,1)).^2+(y-center(n,2)).^2<=radius(n).^2);
h(:,n) = histcounts(d(circle_pixels{n}),0:max(d(:)) );
subplot(2,5,n); plot(h(:,n));title(['circle # ' num2str(n)]);
end
Now we can see how the intensity is distributed in each circle and choose a metric to discriminate the missing pills. We can see that for the missing pills (#5,#9,#10) we have a less simple distribution of intensities (more than one peak) , and in particular a saturation of the maximal intensity that happen because of the glare reflection of the foil probably. So you can choose now a threshold based on that, or any other statistical metric you want (# of peaks in the distributions etc)...

Compute curvature of a bent pipe using image processing (Hough transform parabola detection)

I'm trying to design a way to detect this pipe's curvature. I tried applying hough transform and found detected line but they don't lie along the surface of pipe so smoothing it out to fit a beizer curve is not working .Please suggest some good way to start for the image like this.[
The image obtained by hough transform to detect lines is as follows
[
I'm using standard Matlab code for probabilistic hough transform line detection that generates line segment surrounding the structure. Essentially the shape of pipe resembles a parabola but for hough parabola detection I need to provide eccentricity of the point prior to the detection. Please suggest a good way for finding discrete points along the curvature that can be fitted to a parabola. I have given tag to opencv and ITK so if there is function that can be implemented on this particular picture please suggest the function I will try it out to see the results.
img = imread('test2.jpg');
rawimg = rgb2gray(img);
[accum, axis_rho, axis_theta, lineprm, lineseg] = Hough_Grd(bwtu, 8, 0.01);
figure(1); imagesc(axis_theta*(180/pi), axis_rho, accum); axis xy;
xlabel('Theta (degree)'); ylabel('Pho (pixels)');
title('Accumulation Array from Hough Transform');
figure(2); imagesc(bwtu); colormap('gray'); axis image;
DrawLines_2Ends(lineseg);
title('Raw Image with Line Segments Detected');
The edge map of the image is as follows and the result generated after applying Hough transform on edge map is also not good. I was thinking a solution that does general parametric shape detection like this curve can be expressed as a family of parabola and so we do a curve fitting to estimate the coefficients as it bends to analyze it's curvature. I need to design a real time procedure so please suggest anything in this direction.
I suggest the following approach:
First stage: generate a segmentation of the pipe.
perform thresholding on the image.
find connected components in the thresholded image.
search for a connected component which represents the pipe.
The connected component which represents the pipe should have an edge map which is divided into top and bottom edges (see attached image).
The top and bottom edges should have similar size, and they should have a relatively constant distance from one another. In other words, the variance of their per-pixel distances should be low.
Second stage - extract curve
At this stage, you should extract the points of the curve for performing Beizer fitting.
You can either perform this calculation on the top edge, or the bottom edge.
another option is to do it on the skeleton of the pipe segmentation.
Results
The pipe segmentation. Top and bottom edges are mark with blue and red correspondingly.
Code
I = mat2gray(imread('ILwH7.jpg'));
im = rgb2gray(I);
%constant values to be used later on
BW_THRESHOLD = 0.64;
MIN_CC_SIZE = 50;
VAR_THRESHOLD = 2;
SIMILAR_SIZE_THRESHOLD = 0.85;
%stage 1 - thresholding & noise cleaning
bwIm = im>BW_THRESHOLD;
bwIm = imfill(bwIm,'holes');
bwIm = imopen(bwIm,strel('disk',1));
CC = bwconncomp(bwIm);
%iterates over the CC list, and searches for the CC which represents the
%pipe
for ii=1:length(CC.PixelIdxList)
%ignore small CC
if(length(CC.PixelIdxList{ii})<50)
continue;
end
%extracts CC edges
ccMask = zeros(size(bwIm));
ccMask(CC.PixelIdxList{ii}) = 1;
ccMaskEdges = edge(ccMask);
%finds connected components in the edges mat(there should be two).
%these are the top and bottom parts of the pipe.
CC2 = bwconncomp(ccMaskEdges);
if length(CC2.PixelIdxList)~=2
continue;
end
%tests that the top and bottom edges has similar sizes
s1 = length(CC2.PixelIdxList{1});
s2 = length(CC2.PixelIdxList{2});
if(min(s1,s2)/max(s1,s2) < SIMILAR_SIZE_THRESHOLD)
continue;
end
%calculate the masks of these two connected compnents
topEdgeMask = false(size(ccMask));
topEdgeMask(CC2.PixelIdxList{1}) = true;
bottomEdgeMask = false(size(ccMask));
bottomEdgeMask(CC2.PixelIdxList{2}) = true;
%tests that the variance of the distances between the points is low
topEdgeDists = bwdist(topEdgeMask);
bottomEdgeDists = bwdist(bottomEdgeMask);
var1 = std(topEdgeDists(bottomEdgeMask));
var2 = std(bottomEdgeDists(topEdgeMask));
%if the variances are low - we have found the CC of the pipe. break!
if(var1<VAR_THRESHOLD && var2<VAR_THRESHOLD)
pipeMask = ccMask;
break;
end
end
%performs median filtering on the top and bottom boundaries.
MEDIAN_SIZE =5;
[topCorveY, topCurveX] = find(topEdgeMask);
topCurveX = medfilt1(topCurveX);
topCurveY = medfilt1(topCurveY);
[bottomCorveY, bottomCurveX] = find(bottomEdgeMask);
bottomCurveX = medfilt1(bottomCurveX);
bottomCorveY = medfilt1(bottomCorveY);
%display results
imshow(pipeMask); hold on;
plot(topCurveX,topCorveY,'.-');
plot(bottomCurveX,bottomCorveY,'.-');
Comments
In this specific example, acquiring the pipe segmentation by thresholding was relatively easy. In some scenes it may be more complex. in these cases, you may want to use region growing algorithm for generating the pipe segmentation.
Detecting the connected component which represents the pipe can be done by using some more hueristics. For example - the local curvature of it's boundaries should be low.
You can find the connected components (CCs) of your inverted edge-map image. Then you can somehow filter those components, say for example, based on their pixel count, using region-properties. Here are the connected components I obtained using the given Octave code.
Now you can fit a model to each of these CCs using something like nlinfit or any suitable method.
im = imread('uFBtU.png');
gr = rgb2gray(uint8(im));
er = imerode(gr, ones(3)) < .5;
[lbl, n] = bwlabel(er, 8);
imshow(label2rgb(lbl))

Image differences detection in matlab

I'm trying to find the broken ligaments for these two photos. Because the patten it got I can use the conv2 function find the general broken areas. However, it is really hard for me think how to make it tell the exact broken ligaments. Can you guys give me some idea for how to find which ligaments are broken please?
Because I'm new to this website, I can not post more photos with 2-D convolution results.
Original Picture
Broken Picture
Make a region growing algorithm inside each perfect square.
Once you get that, calculate the area of that section.
Once you find this, calculate the remaining areas. The larger values will be the broken ligaments :)
img = imread('unbroke.jpg');
level = graythresh(rgb2gray(img));
BW = im2bw(rgb2gray(img),level);
BW2= imdilate(imerode(BW, ones(5)), ones(5));
BW3 = bwmorph(BW2,'remove');
figure, imshow(BW2), hold on[![enter image description here][1]][1]
[H,T,R] = hough(BW2);
P = houghpeaks(H,15,'threshold',ceil(0.3*max(H(:))));
x = T(P(:,2)); y = R(P(:,1));
lines = houghlines(BW2,T,R,P,'FillGap',5,'MinLength',7);
max_len = 0;
for k = 1:length(lines)
xy = [lines(k).point1; lines(k).point2];
plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','green');
% Plot beginnings and ends of lines
plot(xy(1,1),xy(1,2),'x','LineWidth',2,'Color','yellow');
plot(xy(2,1),xy(2,2),'x','LineWidth',2,'Color','red');
% Determine the endpoints of the longest line segment
len = norm(lines(k).point1 - lines(k).point2);
if ( len > max_len)
max_len = len;
xy_long = xy;
end
end
lines from unbroken image
lines from broken image
Now, you know what the line segments are do some matching. Or else find pairs of segments that would be connected (same slope + same x/y intercept) within a threshold.
This may be an interesting way to do this too. I saved the second image only as 'image.jpg'.
I = imread('image.jpg');
J = imbinarize(rgb2gray(I)); % Threshold to get a BW image.
BW = bwpropfilt(~J, 'Area', [35001, 1013283]);
imshow(BW)
shows
For selecting the area thresholds easily, I used https://www.mathworks.com/help/images/calculate-region-properties-using-image-region-analyzer.html
If you don't have a recent MATLAB version where imbinarize or bwpropfilt doesn't exist, you can use equivalent thresholding functions, and regionprops to extract all objects within the area range.

How to count number of white pieces or patches accurately?

Hi tried using this code for removing noise and blur.
J = double(imread('C:\Users\sai_praneeth7777\Desktop\project\real123.jpg'));
L= imnoise(J,'salt & pepper',0.02);
k = im2bw(I);
se=strel('disk',1);
bw=imopen(k,se);
imshow(bw);
cc = bwconncomp(bw,4);
number1 = cc.NumObjects;
display(number1);
BW1 = imfill(bw,'holes');
cc = bwconncomp(BW1,4);
number2 = cc.NumObjects;
figure;
imshow(L);
display(number2);
imshow(I);
Here is the original image
Here is the processed image
The problem is there is still some noise remaining and also some divisions are not clear,like in the top right the partitions are gone.I want to count number of white pieces so i will be getting wrong answer.I am new to matlab and image processing.
I would start with a median filter, then you can make an opening a little bit bigger and then a small closing in order to regularize the contours. But as the borders are fuzzy, you cannot have a very precise/neat segmentation.
If you want to separate the different components, you can compute a distance map and use the local maxima in a watershed.

how to draw ROC curve in computer vision algorithm?

I used a detection algorithm to detect the object in 100 images, with each image containing exactly 2 truth, i.e., each image contains 2 objects. then I added noise and find the best one. I calculated the intersection area between detection result and the ground truth intArea, and also the union area unionArea = rectA + rectB - intArea. then I planned to use these ratios to draw ROC curve as follows:
init TP, FP as 100X1 array.
for threshold = 0..1, step = 0.01
curIdx = 1;
for each ratio(i), i = 1..100
if ratio(i) > threshold then
TP(curIdx) = TP(curIdx) + 1;
else
FP(curIdx) = FP(curIdx) + 1;
end
end
then I used TP/100 as Y axis value, and TP/(TP+FP) as X axis value to draw ROC curve.
but the result is not as expected: (I can't post image now because I'm a new user -_-)
https://lh4.googleusercontent.com/-cuNKyobdV7E/UMkiJmrhTFI/AAAAAAAAEQg/B5twqcZtlQA/s560/roc.jpg
So, would anyone plz help me and tell me where I was wrong? thank you all!
VLFeat implements a very easy way to draw ROC curve under the Matlab environment. Please check this link: http://www.vlfeat.org/overview/plots-rank.html
If you want to know the internals of ROC graph generation, you can read Tom Fawcett's report on ROC Graphs or his
ScienceDirect article.
If you just want to generate the plots without going to its technicalities, you can use Yard phyton library or ROCR R package

Resources