Search code examples
matlabimage-processingrobocup

how can I find orange ball?


I am trying to find "robocup's ball". because it is orange ,so I separated this color and after that test if it is round or not...

Here is an image for which the method does not work, but for others it works:

enter image description here

rgb = imread('E:/robot12.jpg'); 
imshow(rgb);
hsv=rgb2hsv(rgb);
h=hsv(: , : ,1);
s=hsv(: , : ,2);
v=hsv( : , : ,3);
bw= (h>0.05 & h<0.12) & (s>0.6) & (v> 0.51);
imagesc(bw)
colormap(gray)
se = strel('disk',2);
bw = imclose(bw,se);
bw = imfill(bw,'holes');

imshow(bw)
ball1 = bwareaopen(bw, 50);
imagesc(ball1);
lab = bwlabel(ball1);
s = regionprops(lab, 'Area', 'Perimeter');
sArea = [s.Area];
sPerim= [s.Perimeter];
metric= sPerim.^2/(4*pi.* sArea);
idx = find(metric > 0.7);
gr_fin = ismember(lab, idx);
imshow(gr_fin)


stat = regionprops(gr_fin,'centroid');
imshow(rgb); hold on;
 for x = 1: numel(stat)
    plot(stat(x).Centroid(1),stat(x).Centroid(2), 'wp','MarkerSize',20,'MarkerFaceColor','b');
  end

I don't know how to fix it...

can any one help me with this?


Solution

  • Ok, first of all, there is a bug in metric.

    After you do all your processing, your image has two different blobs, labeled as 1 (grey) and 2 (white).

    blobs

    So, sArea and sPerim will be two 1x2 arrays. To have a metric value for both blobs you need to fix the line into: metric= (sPerim.^2)./(4*pi.* sArea);

    The point is that this metric gives you 1 for a perfect circular disk, so I believe that it would be better if you had an upper threshold too, and not only metric > 0.7. For example for the blobs above, the values returned are:

    metric = 3.1406 1.9596

    which means that none of them resembles to a perfect circle.

    The second problem is that the real ball is not found completely by the colour thresholds because it becomes too 'yellowish' at the points were the lights hit it. This will be common in many well lit photos, and it will be darker when it's behind a shadow.

    To fix this problem you need to loosen up the hue values so that you allow more yellow and red variations. You will have more false positives but you hope that they will not pass the rest of the tests of your detector.

    I tried bw= (h>0.04 & h<0.15) & (s>0.6) & (v> 0.51); and this was the result:

    blobs 2

    I only changed the hue values, but you can see what suits you with the rest of your photos.

    This image produces metric values of:

    metric = 2.2190 1.1703

    so with a threshold of 1.3>metric>0.7 you would identify only the correct blob.

    result

    The main point is that all this procedure relies upon many arbitrary thresholds, and this makes it vulnerable to errors. Trimming it for a photo specifically could be easy but the point is to be robust for all the inputs. I think that for this specific ball the only variation you will have will be either to be too yellow/white or to dark/brown.

    If you don't want to search for another strategy, you can just see what values work best in the testing.