Finding objects in images

I am trying to find only spherical objects like ball ... I wrote a code to track the "orange" colored ball but it is not showing anything so please tell me the mistake.......and also how to track object of different shape with with different colors..
vid=videoinput('winvideo',2,'I420_320x240');
set(vid,'FramesPerTrigger',Inf);
set(vid,'ReturnedColorspace','rgb');
vid.FrameGrabInterval=2;
framesneeded=300;
start(vid)
while(vid.FramesAcquired<=framesneeded)
RGB=getsnapshot(vid);
R=RGB(:,:,1);
R=fliplr(R);
G=RGB(:,:,2);
G=fliplr(G);
B=RGB(:,:,3);
B=fliplr(B);
RGB=cat(3,R,G,B);
R=((R+G))-(B);
bw=R>60;
bw=medfilt2(bw,[3 3]);
bw=bwareaopen(bw,20);
bw=bwconncomp(bw,8);
stats=regionprops(bw,'CENTROID','Eccentricity');
imshow(RGB)
hold on
if length(stats)>1
ecc= stats(1).Eccentricity;
if(ecc<0.2)
cent=stats(1).Centroid;
plot(cent(1),cent(2),'+','MarkerfaceColor','g','markerSize',30);
end
end
hold off
flushdata(vid);
end

 Réponse acceptée

Image Analyst
Image Analyst le 8 Août 2012
Modifié(e) : Image Analyst le 9 Août 2012

0 votes

The problem is most likely here:
R=((R+G))-(B);
Since R and G are probably uint8, when you add them, they probably go past 255 and so the result is clipped. Cast to single or uint16 before adding. To get the difference between the average of the red and green channel, and the blue channel, do this:
averageDifferenceImage = (single(R) + single(G))/2 - single(B);
At that point, you can cast it back into uint8 if you want:
averageDifferenceImage = uint8(averageDifferenceImage);
Also, Eccentricity is not good for finding circles. I think squares would even have the same eccentricity as circles. It's better to use the circularity, which unfortunately is not built in to regionprops() yet. But you can do this
stats=regionprops(bw,'Area','Perimeter');
circularities = ([stats.Perimeter] .^ 2) ./ (4 * pi * [stats.Area]);
Circularity will be 1 for perfect circles and gets higher the more non-circular the blob gets.

11 commentaires

Sri
Sri le 9 Août 2012
i have tried the following code but it shows mldivide Matrix dimension must agreee!!! Please help me!!!!
vid=videoinput('winvideo',2,'I420_320x240'); set(vid,'FramesPerTrigger',Inf); set(vid,'ReturnedColorspace','rgb'); vid.FrameGrabInterval=2; framesneeded=300; start(vid) while(vid.FramesAcquired<=framesneeded) RGB=getsnapshot(vid); R=RGB(:,:,1); R=fliplr®; G=RGB(:,:,2); G=fliplr(G); B=RGB(:,:,3); B=fliplr(B); RGB=cat(3,R,G,B); R=((single®+single(G))/2)-(single(B)); R=uint8®; bw=R>40; bw=medfilt2(bw,[3 3]); bw=bwareaopen(bw,20); bw=bwconncomp(bw,8); stats=regionprops(bw,'CENTROID','Area','Perimeter'); imshow(RGB) hold on if length(stats)>1 if (([stats.Perimeter.^2] / (4 * pi * [stats.Area]))>0.8) cent=stats(1).Centroid; plot(cent(1),cent(2),'g+','MarkerfaceColor','g','markerSize',20); end hold off flushdata(vid); end end
Sri
Sri le 9 Août 2012
Modifié(e) : Sri le 9 Août 2012
i have tried this code also but after some time time it is showing ??? Undefined function or method 'power' for input arguments of type 'struct'.
vid=videoinput('winvideo',2,'I420_320x240'); set(vid,'FramesPerTrigger',Inf); set(vid,'ReturnedColorspace','rgb'); vid.FrameGrabInterval=2; framesneeded=300; start(vid); while(vid.FramesAcquired<=framesneeded) RGB=getsnapshot(vid); R=RGB(:,:,1); R=fliplr®; G=RGB(:,:,2); G=fliplr(G); B=RGB(:,:,3); B=fliplr(B); RGB=cat(3,R,G,B); R=((single®+single(G))/2)-(single(B)); R=uint8®; bw=R>40; bw=medfilt2(bw,[3 3]); bw=bwareaopen(bw,20); bw=bwconncomp(bw,8); stats=regionprops(bw,'CENTROID','Area','Perimeter'); imshow(RGB); hold on circular=([stats.Perimeter.^2].\ (4 * pi * [stats.Area])); if length(stats)>1 if (circular>0.8) cent=stats(1).Centroid; plot(cent(1),cent(2),'g+','MarkerfaceColor','g','markerSize',20); end hold off flushdata(vid); end end
Image Analyst
Image Analyst le 9 Août 2012
Modifié(e) : Image Analyst le 9 Août 2012
Sorry - my mistake. You need to get all the perimeters into an array first before you raise it to a power since you can't raise the structure to a power. In other words, you can't do this:
[stats.Perimeter.^2] % No good.
You have to do it like this:
circularities = ([stats.Perimeter] .^ 2) ./ (4 * pi * [stats.Area]);
I've edited and corrected the above code in my first answer.
Sri
Sri le 15 Août 2012
I have worked out the code thanks But now i want to find the velocity of the given object can you please help me
Image Analyst
Image Analyst le 15 Août 2012
You will have the centroid in each frame, so take the distance it traveled (use the Pythagorean theorem) and divide it by the time between frames. That should get you the velocity in the field of view plane. I know that's so obvious it's maybe not much help, but I'm not sure how else to help you.
Sri
Sri le 16 Août 2012
Actually I am working on tracking the object through kalman filter and I am new to matlab. I have been learning matlab. I have done the above but i am getting errors which even after my repeated checking are haunting me!!!!!!
I have written this following code that i persume will do the kalman for tracking it....... Please check the code as it is giving me error "Inner matrix dimensions must agree"................
vid=videoinput('winvideo',2,'I420_320x240');
set(vid,'FramesPerTrigger',Inf);
set(vid,'ReturnedColorspace','rgb');
vid.FrameGrabInterval=2;
framesneeded=300;
t=0.1;
A = [1 t; 0 1] ;
B = [t^2/2; t];
C = [1 0];
x_1=[];
x_2=[];
xnoise = 0.1;
znoise = 10;
Ez = znoise^2;
Ex = xnoise^2 * [t^4/4 t^3/2; t^3/2 t^2];
P = Ex;
cent1=0;
cent2=0;
velx1=0;
vely1=0;
start(vid)
while(vid.FramesAcquired<=framesneeded)
RGB=getsnapshot(vid);
R=RGB(:,:,1);
R=fliplr(R);
G=RGB(:,:,2);
G=fliplr(G);
B=RGB(:,:,3);
B=fliplr(B);
RGB=cat(3,R,G,B);
R=((single(R)+single(G-30))/2)-(single(B));
R=uint8(R);
bw=R>40;
bw=medfilt2(bw,[3 3]);
bw=bwareaopen(bw,20);
bw=bwconncomp(bw,8);
stats=regionprops(bw,'CENTROID','Area','Perimeter');
imshow(RGB)
hold on
if length(stats)>1
if ((([stats.Perimeter].^2) / (4 * pi * [stats.Area]))>0.8)
cent=stats(1).Centroid;
plot(cent(1),cent(2),'g+','MarkerfaceColor','g','markerSize',20);
te=text(cent(1)+15,cent(2), strcat('X:', num2str(round(cent(1))), 'Y:', num2str(round(cent(2)))));
end
velx=(cent1-cent(1))^2;
vely=(cent2-cent(2))^2;
cent1=cent(1);
cent2=cent(2);
x=cent;
vel=(((velx)+(vely))^0.5)/20;
ax=abs((vel-velx1)/20);
ay=abs((vel-vely1)/20);
a=((ax*2)+(ay*2))^0.5;
x=(A*cent)+(B*a)+Ex;
z=(C*(x))+Ez;
x_1 = [x_1; x(1)];
x_2 = [x_2; z];
P=Ex;
P=(A*P*A')+Ex;
K=(P*C'*(inv((C*P*C')+Ez)));
x=x+(K*((x_2)-(C*x)));
P=(eye(2)-K*C)*P;
plot(x(1),x(2),'r+','MarkerfaceColor','x','markerSize',20);
hold off
flushdata(vid);
end
end
I know the algorithm for the kalman filter!!!!!! but I feel my implementation is wrong ....Kindly Help me.......THANKS THANKS in ADVANCE
Walter Roberson
Walter Roberson le 16 Août 2012
"inner matrix dimensions must agree" often indicates that you have a "*" operation (mathematical matrix multiplcation) when you want the ".*" (element-by-element multiplication) operation.
Image Analyst
Image Analyst le 16 Août 2012
Or else you have a R1 x C1 matrix multiplied by an R2 x C2 matrix where C1 is not equal to R2. Remember from your linear algebra class (m x n) * (p * q) - the only way for that to work is for n to equal p so you have (m x n) * (n * q) = (m x q) matrix. This works because the inner dimensions are both "n". Set a break point on the line with the error and check all your dimensions.
Sri
Sri le 17 Août 2012
I have checked the possibility of matrix multiplication that u have mentioned and the above by "walter roberson" also but i still get same error even after I change the code to this
vid=videoinput('winvideo',2,'I420_320x240');
set(vid,'FramesPerTrigger',Inf);
set(vid,'ReturnedColorspace','rgb');
vid.FrameGrabInterval=2;
framesneeded=300;
t=0.1;
A = [1 t; 0 1] ;
B = [t^2/2; t];
C = [1 0];
x_1=[];
x_2=[];
xnoise = 0.1;
znoise = 10;
Ez = znoise^2;
Ex = xnoise^2 * [t^4/4 t^3/2; t^3/2 t^2];
P = Ex;
cent1=0;
cent2=0;
velx1=0;
vely1=0;
start(vid)
while(vid.FramesAcquired<=framesneeded)
RGB=getsnapshot(vid);
R=RGB(:,:,1);
R=fliplr(R);
G=RGB(:,:,2);
G=fliplr(G);
B=RGB(:,:,3);
B=fliplr(B);
RGB=cat(3,R,G,B);
R=((single(R)+single(G-30))/2)-(single(B));
R=uint8(R);
bw=R>40;
bw=medfilt2(bw,[3 3]);
bw=bwareaopen(bw,20);
bw=bwconncomp(bw,8);
stats=regionprops(bw,'CENTROID','Area','Perimeter');
imshow(RGB)
hold on
if length(stats)>1
if ((([stats.Perimeter].^2) / (4 * pi * [stats.Area]))>0.8)
cent=stats(1).Centroid;
plot(cent(1),cent(2),'g+','MarkerfaceColor','g','markerSize',20);
te=text(cent(1)+15,cent(2), strcat('X:', num2str(round(cent(1))), 'Y:', num2str(round(cent(2)))));
end
velx=(cent1-cent(1))^2;
vely=(cent2-cent(2))^2;
cent1=cent(1);
cent2=cent(2);
vel=(((velx)+(vely))^0.5)/20;
ax=abs((vel-velx1)/20);
ay=abs((vel-vely1)/20);
a=((ax*2)+(ay*2))^0.5;
x=(A*cent)+(B*a)+Ex;
z=(C*(x))+Ez;
x_1 = [x_1; x(1)];
x_2 = [x_2; z];
P=Ex;
P=(A*P*A')+Ex;
K=(P*C'*(inv((C*P*C')+Ez)));
x=x+(K*((x_2)-(C*x)));
P=(eye(2)-K*C)*P;
plot(x(1),x(2),'r+','MarkerfaceColor','x','markerSize',20);
hold off
flushdata(vid);
end
end
Sri
Sri le 17 Août 2012
especially I checked the last equations of the code and to no even after i repeatedly try by putting everything on the paper and working out step by step I fear that "What I have wriiten my not be Kalman Filter" Please help me out...............Please
Image Analyst
Image Analyst le 17 Août 2012
I don't know if your code is the Kalman filter or not either. I don't have the time or resources to debug it for you, but you do. Just use the debugger and consult your reference for your algorithm and you should be able to figure it out.

Connectez-vous pour commenter.

Plus de réponses (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by