Color Detection Algorithm - Page 2
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 2 of 3 FirstFirst 123 LastLast
Results 16 to 30 of 39

Thread: Color Detection Algorithm

  1. #16
    Join Date
    Dec 2001
    Location
    Greece, Athens
    Posts
    1,015

    Re: Color Detection Algorithm

    Well, that's true, I had not read the thread for a long period of time.
    Anyway, probably it's too late, but here some code I wrote for color detection (though, the pseodo code I had given was, in my opinion quite clear and easy to be transposed to matlab code).

    Anyway, the following code is a matlab function that takes the following arguments:
    1) RGB: a MxNx3 matrix of the RGB values
    2) mode: this argument should take the values 1,2 or 3, depending on the color you want to detect (red, green or blue).
    3) thres: a threshold that is used to detect the desired color in the following way: if the desired color is LARGER than thres * (each of the other two colors), then the current pixel is labelled as 1 (color found).

    Code:
    function I = findColor(RGB, mode, thres)
    % function BIN = findColor(RGB, rgbVal, Thres)
    % Function for detecting a specific rgb value, within acceptable tollerance
    
    % RGB: the rgb image
    % mode: the color to detect:
    %       1: red
    %       2: green
    %       3: blue
    % thres: the distance tollerance
    
    [M,N,t] = size(RGB);
    
    switch (mode)
        case 1
            I1 = zeros(M,N); I2 = zeros(M,N);
            I1( find(RGB(:,:,1) > thres * RGB(:,:,2)) ) = 1;
            I2( find(RGB(:,:,1) > thres * RGB(:,:,3)) ) = 1;
            strTitle = 'Color RED  detected (white areas)';
            I = I1 .* I2;
        case 2
            I1 = zeros(M,N); I2 = zeros(M,N);
            I1( find(RGB(:,:,2) > thres * RGB(:,:,1)) ) = 1;
            I2( find(RGB(:,:,2) > thres * RGB(:,:,3)) ) = 1;
            strTitle = 'Color GREEN  detected (white areas)';
            I = I1 .* I2;        
        case 3
            I1 = zeros(M,N); I2 = zeros(M,N);
            I1( find(RGB(:,:,3) > thres * RGB(:,:,1)) ) = 1;
            I2( find(RGB(:,:,3) > thres * RGB(:,:,2)) ) = 1;
            strTitle = 'Color BLUE  detected (white areas)';
            I = I1 .* I2;        
        otherwise
            fprintf('WRONG ARGUMENTS'\n);
            return;
    end
    
    
    
    subplot(2,1,1),imshow(RGB); title('Original Image');
    subplot(2,1,2),imshow(I,[]); title(strTitle);
    Theodore
    Personal Web Page (some audio segmentation tools): www.di.uoa.gr/~tyiannak

  2. #17
    Join Date
    Dec 2001
    Location
    Greece, Athens
    Posts
    1,015

    Re: Color Detection Algorithm

    Also, here is an example:
    I load the "trees" matlab image, and convert it to an RGB image:

    Code:
    load trees;
    RGB = ind2rgb(X,map);
    Then I detect all 3 colors, in order:
    Code:
    I1 = findColor(RGB, 1, 1.0);
    I2 = findColor(RGB, 2, 1.0);
    I3 = findColor(RGB, 3, 1.0);
    The plotted results are shown in the attached images.


    PS1: Other threshold values can be used for more accurate color detection.
    PS2: The thresholding method presented here is trivial. More sophisticated methods could also be used, that, for example would take into consideration the texture.
    Attached Images Attached Images    
    Theodore
    Personal Web Page (some audio segmentation tools): www.di.uoa.gr/~tyiannak

  3. #18
    Join Date
    Jun 2007
    Posts
    7

    Re: Color Detection Algorithm

    and how do I do that in HSV?

  4. #19
    Join Date
    Dec 2001
    Location
    Greece, Athens
    Posts
    1,015

    Re: Color Detection Algorithm

    Quote Originally Posted by mwg
    and how do I do that in HSV?
    Well, in a similar way. I suppose you will have to check the hue scale mainly. For example, if you want to detect "RED" color you will have to search about pixels with values of H close to 0. If you are interested in "pure" red color then force the S (saturation) to be close to 100%. Otherwise, do not use the S component. Finally, you can put restrictions (with a tollerance) in the Value component. Anyway, if you are not interested in the brightness, do not use the V component, and if you are not interested in the "clearness" of the color do not use the S component.

    To be more analytic, assume you want to detect red color. You have to decide if you want a specific brightness of the color (that is V) and a specific pureness of your color. To speak in "rgb terms", for example you want to detect RGB={150,0,0} (that has 100% saturation, since it is 100% pure red color). The questions above become:
    1. do you also want to detect e.g. RGB={250,0,0} (that is, do you want to have tollerance in the V coefficient of the HSV space?) and
    2. do you also want to detect, e.g. RGB = {60,10,10} which corresponds to lower S values?
    Theodore
    Personal Web Page (some audio segmentation tools): www.di.uoa.gr/~tyiannak

  5. #20
    Join Date
    Dec 2001
    Location
    Greece, Athens
    Posts
    1,015

    Re: Color Detection Algorithm

    Quote Originally Posted by mwg
    and how do I do that in HSV?
    I've also made an example function for you:

    Code:
    function colorDetectHSV(RGB, hsvVal, tol)
    
    HSV = rgb2hsv(RGB);
    
    % find the difference between required and real H value:
    diffH = abs(HSV(:,:,1) - hsvVal(1));
    
    [M,N,t] = size(RGB);
    I1 = zeros(M,N); I2 = zeros(M,N); I3 = zeros(M,N);
    
    T1 = tol(1);
    
    I1( find(diffH < T1) ) = 1;
    
    if (length(tol)>1)
        % find the difference between required and real S value:
        diffS = abs(HSV(:,:,2) - hsvVal(2));    
        T2 = tol(2);
        I2( find(diffS < T2) ) = 1;    
        if (length(tol)>2)
            % find the difference between required and real V value:
            difV = HSV(:,:,3) - hsvVal(3);    
            T3 = tol(3);
            I3( find(diffS < T3) ) = 1;
            I = I1.*I2.*I3;
        else
            I = I1.*I2;
        end
    else
        I = I1;    
    end
    
    subplot(2,1,1),imshow(RGB); title('Original Image');
    subplot(2,1,2),imshow(I,[]); title('Detected Areas');
    The above function:
    1. Takes as argument an rgb image (MxNx3), the hsv value you want to detect (this can be a vector 1x1 OR 2x1 OR 3x1) and a tolerance array (save size as hsv value)
    2. Transposes the image to HSV.
    3. Depending on the length L of tollerance (tol):
    3.1: L=1: Searches ONLY the H coeficient and finds pixels that are close enough to hsv.
    3.2: L=2: Searches H and S coeficients and finds pixels that are close enough to hsv (the 2 values given in the argument).
    3.3. L=3: Searches ALL HSV componets.

    Here is an example of how to call the above function (again with the trees image):
    Code:
    load trees;
    RGB = ind2rgb(X,map);
    colorDetectHSV(RGB, [0.66 1.0 0.5], [0.1 0.5 0.5])
    The above code calls the function for finding the hsv value [0.66 1.0 0.5] with tollerance [0.1 0.5 0.5]. We have to note that H = 0.66 stands for the blue color (tolerance: 0.1), S = 1.0 stands for 100% pure color (tolerance 0.50).

    I attach the original and the detected image in the attached image.

    PS: the HSV values in matlab are between 0 and 1.

    Attached Images Attached Images  
    Theodore
    Personal Web Page (some audio segmentation tools): www.di.uoa.gr/~tyiannak

  6. #21
    Join Date
    Jun 2007
    Posts
    7

    Re: Color Detection Algorithm

    I really appreciate it!

    thank you!!

  7. #22
    Join Date
    Nov 2007
    Posts
    27

    Re: Color Detection Algorithm

    Hi guys,

    do you have any idea which one is better, RGB or HSV if i use it to detect lips or mouth?

    The attachments below "image.zip" are images which i have tried with RGB. The moustache seems to be the noise.

    Please help, i will appreciate every piece of comment.
    Attached Files Attached Files

  8. #23
    Join Date
    Dec 2001
    Location
    Greece, Athens
    Posts
    1,015

    Re: Color Detection Algorithm

    Quote Originally Posted by tommy_chai
    Hi guys,

    do you have any idea which one is better, RGB or HSV if i use it to detect lips or mouth?

    The attachments below "image.zip" are images which i have tried with RGB. The moustache seems to be the noise.

    Please help, i will appreciate every piece of comment.

    Hi. First of all I believe HSV is better for colour detection (I've tried this in the past for "skin" detection and it worked better). Though, in order to test the above function I've written, you need some "training" data, i.e. some prior knowledge. In other words, you may need the average value of your object of interest (in that case lips).
    The following function does the following:

    • Loads an image (which you provide as an RGB argument)
    • Waits for user clicks (right clicks) and for each click it selects an area (around the selected point) and it keeps the HSV (average) value of that area.
    • Finally, it calculates the average HSV value and it plots the progress of the average H, S, and V coefficients along mouse clicks.


    Code:
    function hsvMean = selectPixelsAndGetHSV(RGB, Area)
    
    %
    % function hsvMean = selectPixelsAndGetHSV(RGB, Area)
    %
    % Use this function in order to select multiple points from an image (use
    % right click to stop process). The selected points are used to calculate
    % the average HSV values.
    
    % ARGUMENTS:
    % RGB: the RGB image
    % AREA: the area size used to calulate the HSV values of each point
    %
    %
    % Theodoros Giannakopoulos - November 2007
    %
    
    
    
    imshow(RGB); hold on;
    HSV = rgb2hsv(RGB);
    numOfSelectedPixels = 0;
    right_not_pressed = 1;
    BUTTON = 1;
    while (BUTTON~=3)
        numOfSelectedPixels = numOfSelectedPixels + 1;
        [X,Y,BUTTON] = GINPUT(1);    
        hsvTemp2 = HSV(Y-(Area-1)/2:Y+(Area-1)/2, X-(Area-1)/2:X+(Area-1)/2, :);    
        
        hsvTemp = zeros(3,1);
        [K,L,M] = size(hsvTemp2);
        for (i=1:K)
            for (j=1:L)
                hsvTemp(1) = hsvTemp(1) + hsvTemp2(i,j,1);
                hsvTemp(2) = hsvTemp(2) + hsvTemp2(i,j,2);
                hsvTemp(3) = hsvTemp(3) + hsvTemp2(i,j,3);
            end
        end
        
        hsvTemp = hsvTemp / (K*L);
        
        hsv(numOfSelectedPixels,:) = hsvTemp;
        hsvMean = mean(hsv,1);
        
        line([X-(Area-1)/2 X+(Area-1)/2] , [Y-(Area-1)/2 Y-(Area-1)/2]);
        line([X+(Area-1)/2 X+(Area-1)/2] , [Y-(Area-1)/2 Y+(Area-1)/2]);
        line([X+(Area-1)/2 X-(Area-1)/2] , [Y+(Area-1)/2 Y+(Area-1)/2]);
        line([X-(Area-1)/2 X-(Area-1)/2] , [Y+(Area-1)/2 Y-(Area-1)/2]);
        
        fprintf('Cur HSV Values:  %.3f %.3f %.3f\n', hsvTemp(1), hsvTemp(2), hsvTemp(3));
        fprintf('Mean HSV Values: %.3f %.3f %.3f\n', hsvMean(1), hsvMean(2), hsvMean(3));
    end
    
    [N, t] = size(hsv);
    
    for (i=1:N) hsvM1(i) = mean(hsv(1:i,1)); end    
    for (i=1:N) hsvM2(i) = mean(hsv(1:i,2)); end    
    for (i=1:N) hsvM3(i) = mean(hsv(1:i,3)); end    
    
    hsvMean = mean(hsv);
    
    figure;
    subplot(3,1,1); plot(hsvM1); title(sprintf('H-->%.4f',hsvM1(end)));
    subplot(3,1,2); plot(hsvM2); title(sprintf('S-->%.4f',hsvM2(end)));
    subplot(3,1,3); plot(hsvM3); title(sprintf('V-->%.4f',hsvM3(end)));
    I run the above m-file for one of your images (code: hsvMean = selectPixelsAndGetHSV(RGB1, 5). In the following pictures you can see:
    a) the initial image and the selected 5x5 areas in blue.
    b) how the average H, S and V values were changed along time.


    As you can see, the final HSV values are:
    HSV = [0.0782 0.5461 0.3454].



    Regards,
    Theodore
    Attached Images Attached Images   
    Theodore
    Personal Web Page (some audio segmentation tools): www.di.uoa.gr/~tyiannak

  9. #24
    Join Date
    Jun 2002
    Location
    Moscow, Russia.
    Posts
    2,176

    Re: Color Detection Algorithm

    Or even better don't stick to particular representation and allow a class of transformations that covers RGB, HSV and more and learn parameters appropriate for you task from training data. You'd need to understand some theory though.
    "Programs must be written for people to read, and only incidentally for machines to execute."

  10. #25
    Join Date
    Nov 2007
    Posts
    27

    Re: Color Detection Algorithm

    Thanks for the code.
    Yiannakop: I have tried your codes. Let's say we get HSV = [0.0782 0.5461 0.3454] by running selectPixelsAndGetHSV(RGB, Area). Then only we use the mean to apply to your previous codes on HSV, colorDetectHSV(a, [0.0782 0.5461 0.3454], [0.3 0.5 0.5]). Is this what you mean?
    I can get the mouth region in black pixels. Why? By right it should be detected in white pixels as shown by your example "tree".

    This attachment "aa.pgm" is the result i get by using your RGB codes. It is the same image as you tried with HSV. I found that the result generated by RGB is better. Why? I have used the method as above.

    Can you try to make the HSV automatically as the RGB code, in which we only need to fill in the threshold? This is because if i have a bigger database, does it mean that i need to mark every image to get the average for HSV? Can you help to make the HSV codes more automated in this case?

    Anyway, thanks for sharing out the codes. At least i know HSV can do it but more complicated compared to RGB. Thank you very much.
    Attached Files Attached Files
    • File Type: zip aa.zip (754 Bytes, 152 views)
    Last edited by tommy_chai; November 23rd, 2007 at 04:14 AM.

  11. #26
    Join Date
    Dec 2001
    Location
    Greece, Athens
    Posts
    1,015

    Re: Color Detection Algorithm

    Ok I found were the problem was. As you can see, in the last function i sent you I finally keep the mean() (AVERAGE) value of the HSV values. I realized that this is incorrect: suppose that you select a pixel which has much different HSV values. Then, the average value will significally change (and that is much obvious in HSV values, where for example the H value differs alot from color to color). Therefore, I have decided to replace the mean() calls with median(), which is more robust against noise pixels. Now, the code becomes:

    Code:
    function hsvMean = selectPixelsAndGetHSV(RGB, Area)
    
    %
    % function hsvMean = selectPixelsAndGetHSV(RGB, Area)
    %
    % Use this function in order to select multiple points from an image (use
    % right click to stop process). The selected points are used to calculate
    % the average HSV values.
    
    % ARGUMENTS:
    % RGB: the RGB image
    % AREA: the area size used to calulate the HSV values of each point
    %
    %
    % Theodoros Giannakopoulos - November 2007
    %
    
    
    
    imshow(RGB); hold on;
    HSV = rgb2hsv(RGB);
    HSV2 = HSV;
    numOfSelectedPixels = 0;
    right_not_pressed = 1;
    BUTTON = 1;
    while (BUTTON~=3)
        numOfSelectedPixels = numOfSelectedPixels + 1;
        [X,Y,BUTTON] = GINPUT(1);    
        
        hsvTemp2 = HSV(Y-(Area-1)/2:Y+(Area-1)/2, X-(Area-1)/2:X+(Area-1)/2, :);    
            
        HSV2(Y-(Area-1)/2:Y+(Area-1)/2, X-(Area-1)/2:X+(Area-1)/2, :) = 0;
        
        hsvTemp = zeros(3,1);
        [K,L,M] = size(hsvTemp2);
        for (i=1:K)
            for (j=1:L)
                hsvTemp(1) = hsvTemp(1) + hsvTemp2(i,j,1);
                hsvTemp(2) = hsvTemp(2) + hsvTemp2(i,j,2);
                hsvTemp(3) = hsvTemp(3) + hsvTemp2(i,j,3);
            end
        end
        
        hsvTemp = hsvTemp / (K*L);
        
        hsv(numOfSelectedPixels,:) = hsvTemp;
        hsvMean = median(hsv,1);
        
        line([X-(Area-1)/2 X+(Area-1)/2] , [Y-(Area-1)/2 Y-(Area-1)/2]);
        line([X+(Area-1)/2 X+(Area-1)/2] , [Y-(Area-1)/2 Y+(Area-1)/2]);
        line([X+(Area-1)/2 X-(Area-1)/2] , [Y+(Area-1)/2 Y+(Area-1)/2]);
        line([X-(Area-1)/2 X-(Area-1)/2] , [Y+(Area-1)/2 Y-(Area-1)/2]);
        
        
        %rgbTemp = hsv2rgb(hsvTemp);
        %fprintf('Cur RGV Values:  %.3f %.3f %.3f\n', rgbTemp(1), rgbTemp(2), rgbTemp(3));
        fprintf('Cur HSV Values:  %.3f %.3f %.3f\n', hsvTemp(1), hsvTemp(2), hsvTemp(3));
        fprintf('Mean HSV Values: %.3f %.3f %.3f\n', hsvMean(1), hsvMean(2), hsvMean(3));
    end
    
    [N, t] = size(hsv);
    
    for (i=1:N) hsvM1(i) = median(hsv(1:i,1)); end    
    for (i=1:N) hsvM2(i) = median(hsv(1:i,2)); end    
    for (i=1:N) hsvM3(i) = median(hsv(1:i,3)); end    
    
    hsvMean = median(hsv);
    
    figure;
    subplot(3,1,1); plot(hsvM1); title(sprintf('H-->%.4f',hsvM1(end)));
    subplot(3,1,2); plot(hsvM2); title(sprintf('S-->%.4f',hsvM2(end)));
    subplot(3,1,3); plot(hsvM3); title(sprintf('V-->%.4f',hsvM3(end)));
    
    figure;
    RGB2 = hsv2rgb(HSV2);
    imshow(RGB2);
    And if I run the above function for one of your images again, I get the following hsv vales:

    HSV = [0.0189 0.5501 0.3329];

    I also attach the respective figure of the HSV values.

    Regards,
    Theodore
    Attached Images Attached Images  
    Theodore
    Personal Web Page (some audio segmentation tools): www.di.uoa.gr/~tyiannak

  12. #27
    Join Date
    Dec 2001
    Location
    Greece, Athens
    Posts
    1,015

    Re: Color Detection Algorithm

    Also, here is an example of calling the HSV color detection function with the values above:

    Code:
    RGB1 = imread('m-005-3.pgm');
    HSV1 = rgb2hsv(RGB1);
    colorDetectHSV(RGB1, [0.019 0.55 0.33], [0.01 0.02 0.02]);
    The results are shown in the attached figure.

    Hope this helped you a bit.

    Regards,
    Theodore
    Attached Images Attached Images  
    Theodore
    Personal Web Page (some audio segmentation tools): www.di.uoa.gr/~tyiannak

  13. #28
    Join Date
    Dec 2001
    Location
    Greece, Athens
    Posts
    1,015

    Re: Color Detection Algorithm

    Quote Originally Posted by tommy_chai
    Can you try to make the HSV automatically as the RGB code, in which we only need to fill in the threshold? This is because if i have a bigger database, does it mean that i need to mark every image to get the average for HSV? Can you help to make the HSV codes more automated in this case?
    Well I suppose it wouldn't be hard to use the hsv detect function i've written in a matlab script that reads multiple images from a folder and keep the median hsv value from all images. I know this is hard work, but this is generally a serious step in all pattern recognition problems: gathering and labelling training data... so you will have to get through this......
    Theodore
    Personal Web Page (some audio segmentation tools): www.di.uoa.gr/~tyiannak

  14. #29
    Join Date
    Nov 2007
    Posts
    27

    Re: Color Detection Algorithm

    Yiannakop: Thanks for your guidance, really appreciated it. From my opinion,
    colorDetectHSV(RGB1, [0.019 0.55 0.33], [0.01 0.02 0.02]);
    we still have to fill in manually for HSV value which we can obtain by executing hsvMean = selectPixelsAndGetHSV(RGB, Area) right?
    In order to make it automated, i need to make a link to connect the HSV value which is generated to automatically update in colorDetectHSV() right?

    Good job my friend. Thanks again.

    Best regards,
    Tommy
    (PS:Honestly, i haven't try your new program to use median() due to my workload but i iwill try it as soon as possible)

  15. #30
    Join Date
    Dec 2001
    Location
    Greece, Athens
    Posts
    1,015

    Re: Color Detection Algorithm

    Quote Originally Posted by tommy_chai
    Yiannakop: Thanks for your guidance, really appreciated it.
    Any time

    Quote Originally Posted by tommy_chai
    From my opinion,
    colorDetectHSV(RGB1, [0.019 0.55 0.33], [0.01 0.02 0.02]);
    we still have to fill in manually for HSV value which we can obtain by executing hsvMean = selectPixelsAndGetHSV(RGB, Area) right?
    Yes you need to have a "manual" stage involving in your training process and that happens in general. So, yes you will have to execute selectPixelsAndGetHSV(), and to be 100% correct you will have to execute this on MANY images (which, in a way will form the training data set).

    Quote Originally Posted by tommy_chai
    In order to make it automated, i need to make a link to connect the HSV value which is generated to automatically update in colorDetectHSV() right?
    I am not sure I get this actually...
    Theodore
    Personal Web Page (some audio segmentation tools): www.di.uoa.gr/~tyiannak

Page 2 of 3 FirstFirst 123 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center