how to draw ROC curve in computer vision algorithm? - curve

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

Related

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

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

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))

Fitting of a sphere using SVD/LMS

I would like to fit a MR binary data of 281*398*104 matrix which is not a perfect sphere, and find out the center and radius of sphere and error also. I know LMS or SVD is a good choice to fit for sphere.
I have tried sphereFit from matlab file exchange but got an error,
>> sphereFit(data)
Warning: Matrix is singular to working precision.
> In sphereFit at 33
ans =
NaN NaN NaN
Would you let me know where is the problem, or any others solution?
If you want to use sphere fitting algorithm you should first extract the boundary points of the object you assume to be a sphere. The result should be represented by a N-by-3 array containing coordinates of the points. Then you can apply sphereFit function.
In order to obtain boundary point of a binary object, there are several methods. One method is to apply morphological erosion (you need the "imerode" function from the image processing toolbox) with small structuring element, then compute set difference between the two images, and finally use the "find" function to transform binary image into a coordinate array.
the idea is as follow:
dataIn = imerode(data, ones([3 3 3]));
bnd = data & ~data2;
inds = find(bnd);
[y, x, z] = ind2sub(size(data), inds); % be careful about x y order
points = [x y z];
sphere = sphereFitting(points);
By the way, the link you gave refers to circle fitting, I suppose you wanted to point to a sphere fitting submission?
regards,

How to obtain the bounding ellipse of a target connect component

Suppose we have a connected component in the image as the following image illustrates:image http://dl.dropbox.com/u/92688392/ellipse.jpg.
My question is how can calculate the bounding ellipse of the connected components (the red ellipse in the image). I have checked MATLAB function regionprops, and understand how MATLAB can do that. I also notice that Opencv has similar function to do that CBlob::GetEllipse(). However, although I understand how they obtain the result by reading the code, the fundamental theory behind it is still unclear to me. I am therefore wondering whether there are some standard algorithms to do the job. Thanks!
EDIT:
Based on the comments, I reorganized my question: in image moment Wikipedia the calculation formula of the longest axis angle is
However, in the MATLAB function regionprops, the codes are as follows:
% Calculate orientation.
if (uyy > uxx)
num = uyy - uxx + sqrt((uyy - uxx)^2 + 4*uxy^2);
den = 2*uxy;
else
num = 2*uxy;
den = uxx - uyy + sqrt((uxx - uyy)^2 + 4*uxy^2);
end
This implementation is inconsistent with the formula in Wikipedia. I was wondering which one is correct.
If you're looking for a OpenCV implementation than I can give it to you. The algorithm is the following:
Convert image to 1bit (b&w)
Find all contours
Create contour that contains all points from founded contours
Calculate convex hull of this contour
Find rotated ellipse (rectangle) with minimal square that contains calculated in previous step contour
Here's code:
Mat src = imread("ellipse.jpg"), tmp;
vector<Vec4i> hierarchy;
vector<vector<Point> > contours;
vector<Point> bigContour, hull;
RotatedRect ell;
//step 1
cvtColor(src, tmp, CV_BGR2GRAY);
threshold(tmp, tmp, 100, 255, THRESH_BINARY);
//step 2
findContours(tmp, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
//step 3
for (size_t i=0; i<contours.size(); i++)
{
for (size_t j=0; j<contours[i].size(); j++)
{
bigContour.push_back(contours[i][j]);
}
}
//step 4
convexHull(bigContour, hull);
//step 5
ell = fitEllipse(hull);
//drawing result
ellipse(src, ell, Scalar(0,0,255), 2);
imshow("result", src);
waitKey();
This is the input:
And here's a result:
I was trying to find out what's the algorithm behind it as well so I could write my own implementation of it. I found it on a blog post of mathworks. In one of the comments, the author says:
regionprops calculates the 2nd-order moments of the object in question and then returns measurements of the ellipse with the same 2nd-order moments.
and later later:
The equations used are from Haralick and Shapiro, Computer and Robot Vision vol. 1, Appendix A, Addison-Wesley 1992. I did a sanity check by constructing an image containing an ellipse with major axis length = 100 and minor axis length = 50, and regionprops returned the correct measurements.
I don't have that book but seems I'll need to get a copy of it.
I'm not sure how matlab or opencv calculates the ellipsoid. But if you are interested in math behind it, there is a very nice optimization approach called Löwner-John ellipsoid. You can find more information about this method in the Stanford Convex Optimization course. I hope it helps...

How does it work comparing/matching images with kd-trees and nearest neighbor search?

I have been querying google for some material about kd-trees and image comparison but I couldn't make the 'link' between the technics for image comparison using kd-trees.
Firstly, I found some articles talking about speed improvement with randomized kd-trees, then I was introduced to SIFT. After understanding basically how SIFT works, I read about nearest neighbor search.
My real question is: If I have a mesh of points from SIFT, then I create the kd-tree for every image. How the nearest neighbor search can help me compare the images? At first, I thought that comparing images with a tree would work with some algorithm checking the tree structure and how near every point is from an image A from a point in the same node in and image B.
If the question is too dumb, please suggest material or some topic for search.
Thank you!
I'd suggest first understanding slow feature matching, without kdtrees.
input: 1000 reference features, e.g. of faces or flowers; call these F1 .. F1000
a query feature Q: which face or flower feature is most like, nearest, Q ?
As you know,
SIFT
reduces an image feature to 128 8-bit numbers, scaled so that
similarity( feature F, feature Q ) =
Euclidean distance( SIFT(F), SIFT(Q) ).
The simplest way to find which of F1 .. F1000 is most like Q
is just to look at F1, F2 ... one by one:
# find the feature of F1 .. F1000 nearest Q
nearestdistance = infinity
nearestindex = 0
for j in 1 .. 1000:
distance = Euclideandistance( SIFT(Fj), SIFT(Q) ) # 128 numbers vs. 128 numbers
if distance < nearestdistance:
nearestdistance = distance
nearestindex = j
(Of course one computes the SIFT numbers outside the loop.)
A Kdtree
is just a way of finding nearby vectors quickly;
it has little to do with what is being matched
(vectors of numbers representing ...), or how (Euclidean distance).
Now kdtrees are very fast for 2d, 3d ... up to perhaps 20d,
but may be no faster than a linear scan of all the data above 20d.
So how can a kdtree work for features in 128d ?
The main trick is to quit searching early.
The paper by Muja and Lowe,
Fast approximate nearest neighbors with automatic algorithm configuration,
2009, 10p, describes multiple randomized kdtrees for matching 128d SIFT features.
(Lowe is the inventor of SIFT.)
To compare two images I and Q, one finds a set of feature vectors --
several hundred up to a few thousand SIFT vectors -- for each,
and looks for near matches of these sets.
(One may think of images as molecules, features as atoms;
near-matching molecules is much harder than near-matching atoms,
but it helps to be able to match atoms quickly.)
Hope this helps.
If you are planning on using kd-trees for approximate NN search in higher dimensions, you might want to review the experiments here: http://zach.in.tu-clausthal.de/software/approximate_nn/
I suggest you to extract color code values of each image and create a KD tree using those features vectors.
You can use the following mat lab code to extract the color code features.
im = imread('image.jpg');
len = size(im,3);
if(len == 1)
im = ind2rgb(im, colourMap);
im = uint8(im.*255);
end
im(logical( 0 <= im & im <= 63)) = 0;
im(logical( 64 <= im & im <= 127)) = 1;
im(logical(128 <= im & im <= 191)) = 2;
im(logical(192 <= im & im <= 255)) = 3;
im = im(:,:,1) * 16 + im(:,:,2) * 4 + im(:,:,3);
imHist = histc(im(:),0:63);

Resources