HSV color range detection

11,198

Solution 1

you can find a color wheel easily at internet. See the image below which tells you the Hue range of various colors. The range in color wheel given below is 0 to 360 but in openCV, the range is 0 to 180. So, just divide the values by 2, and you will get the value for openCV.

image

Solution 2

You can also use OpenCV version of HSV colour wheel , which I created to chose HSV value easily using trackbar while HSV-color segmentation

enter image description here

Code:

Mat HSV;
int H =170;
int S=200;
int V =200;
int R=0;
int G=0;
int B=0;

int MAX_H=179;
int MAX_S=255;
int MAX_V=255;
int mouse_x=0;
int mouse_y=0;
char window_name[20] = "HSV Color Plot";

//Global variable for hsv color wheel plot
int max_hue_range=179;
int max_step=3; //nuber of pixel for each hue color
int wheel_width=max_hue_range*max_step;
int wheel_hight=50;
int wheel_x=50; //x-position of wheel
int wheel_y=5;//y-position of wheel

//Global variable plot for satuarion-value plot
int S_V_Width=MAX_S;
int S_V_Height=MAX_S;
int S_V_x=10;
int S_V_y=wheel_y+wheel_hight+20;

//Global variable for HSV ploat
int HSV_Width=150;
int HSV_Height=150;
int HSV_x=S_V_x+S_V_Width+30;
int HSV_y=S_V_y+50;


void onTrackbar_changed(int, void*);
static void onMouse( int event, int x, int y, int, void* );
void drawPointers(void);

int main()
{

HSV.create(390,640,CV_8UC3); //Mat to store clock image
HSV.setTo(Scalar(200,0,200));

namedWindow(window_name);
createTrackbar( "Hue",window_name, &H, HUEMAX, onTrackbar_changed );
createTrackbar( "Saturation",window_name, &S, SATMAX,onTrackbar_changed );
createTrackbar( "Value",window_name, &V, VALMAX,onTrackbar_changed);
onTrackbar_changed(0,0); //initialoze window

setMouseCallback( window_name, onMouse, 0 );
 while(true)
  {
    int c;
    c = waitKey( 20 );
    if( (char)c == 27 )
      { break; }
   }

    return 0;
}

void onTrackbar_changed(int, void*){

//Plot color wheel.
int hue_range=0;
int step=1;
for(int i=wheel_y;i<wheel_hight+wheel_y;i++){
    hue_range=0;
    for(int j=wheel_x;j<wheel_width+wheel_x;j++){
   if(hue_range>=max_hue_range) hue_range=0;
       if(step++==max_step){
           hue_range++;
           step=1;
       }
        Vec3b pix;
        pix.val[0]=hue_range;
        pix.val[1]=255;
        pix.val[2]=255;


     HSV.at<Vec3b>(i,j)=pix;

    }

}


//Plot for saturation and value
int sat_range=0;
int value_range=255;
for(int i=S_V_y;i<S_V_Height+S_V_y;i++){
    value_range--;
    sat_range=0;
for(int j=S_V_x;j<S_V_Width+S_V_x;j++){
        Vec3b pix;
        pix.val[0]=H;
        pix.val[1]=sat_range++;
        pix.val[2]=value_range;
     HSV.at<Vec3b>(i,j)=pix;

    }

}

//Ploat for HSV
Mat roi1(HSV,Rect(HSV_x,HSV_y,HSV_Width,HSV_Height));
roi1=Scalar(H,S,V);
drawPointers();

Mat RGB;
cvtColor(HSV, RGB,CV_HSV2BGR);

imshow(window_name,RGB);
imwrite("hsv.jpg",RGB);

}

static void onMouse( int event, int x, int y, int f, void* ){
if(f&CV_EVENT_FLAG_LBUTTON){
        mouse_x=x;
        mouse_y=y;
    if(((wheel_x<=x)&&(x<=wheel_x+wheel_width))&&((wheel_y<=y)&&(y<=wheel_y+wheel_hight))){
        H=(x-wheel_x)/ max_step;
        cvSetTrackbarPos("Hue", window_name, H);
        }
    else if(((S_V_x<=x)&&(x<=S_V_x+S_V_Width))&&((S_V_y<=y)&&(y<=S_V_y+S_V_Height))){

        S=x-S_V_x;
        y=y-S_V_y;
        V=255-y;

        cvSetTrackbarPos("Saturation", window_name, S);
        cvSetTrackbarPos("Value", window_name, V);


        }

}

}

void drawPointers(){
   // Point p(S_V_x+S,S_V_y+(255-V));
    Point p(S,255-V);



    int index=10;
    Point p1,p2;
    p1.x=p.x-index;
    p1.y=p.y;
    p2.x=p.x+index;
    p2.y=p.y;

    Mat roi1(HSV,Rect(S_V_x,S_V_y,S_V_Width,S_V_Height));
    line(roi1, p1, p2,Scalar(255,255,255),1,CV_AA,0);
    p1.x=p.x;
    p1.y=p.y-index;
    p2.x=p.x;
    p2.y=p.y+index;
    line(roi1, p1, p2,Scalar(255,255,255),1,CV_AA,0);

    int x_index=wheel_x+H*max_step;
    if(x_index>=wheel_x+wheel_width) x_index=wheel_x+wheel_width-2;
    if(x_index<=wheel_x) x_index=wheel_x+2;

    p1.x=x_index;
    p1.y=wheel_y+1;
    p2.x=x_index;
    p2.y=wheel_y+20;
    line(HSV, p1, p2,Scalar(255,255,255),2,CV_AA,0);

    Mat RGB(1,1,CV_8UC3);
    Mat temp;
    RGB=Scalar(H,S,V);
    cvtColor(RGB, temp,CV_HSV2BGR);
    Vec3b rgb=temp.at<Vec3b>(0,0);
    B=rgb.val[0];
    G=rgb.val[1];
    R=rgb.val[2];

    Mat roi2(HSV,Rect(450,130,175,175));
    roi2=Scalar(200,0,200);

    char name[30];
    sprintf(name,"R=%d",R);
    putText(HSV,name, Point(460,155) , FONT_HERSHEY_SIMPLEX, .7, Scalar(5,255,255), 2,8,false );

    sprintf(name,"G=%d",G);
    putText(HSV,name, Point(460,180) , FONT_HERSHEY_SIMPLEX, .7, Scalar(5,255,255), 2,8,false );

    sprintf(name,"B=%d",B);
    putText(HSV,name, Point(460,205) , FONT_HERSHEY_SIMPLEX, .7, Scalar(5,255,255), 2,8,false );


    sprintf(name,"H=%d",H);
    putText(HSV,name, Point(545,155) , FONT_HERSHEY_SIMPLEX, .7, Scalar(5,255,255), 2,8,false );

    sprintf(name,"S=%d",S);
    putText(HSV,name, Point(545,180) , FONT_HERSHEY_SIMPLEX, .7, Scalar(5,255,255), 2,8,false );

    sprintf(name,"V=%d",V);
    putText(HSV,name, Point(545,205) , FONT_HERSHEY_SIMPLEX, .7, Scalar(5,255,255), 2,8,false );


}
Share:
11,198
farhangdon
Author by

farhangdon

My name is Farhan Maqsood and I belong to Pakistan. Software Development is my biggest passion. I am always looking for something new to learn, for a new way to improve, for the next challenge. My interest in the field of Computer Science has led me in search of pursuing a career in Computer Science and Engineering. The various amazing applications of computers in real world has instigated a passion in me for getting to know the intricate details of Computer Science and also how to implement these applications. Whether it be the field of medicine or business, banking or gaming, robotics or sports, aero planes or weather analysis, the great many applications of Computer Science in these fields have fascinated me. I started my carrier in a multi-national software company DreamsVue as a Software engineer. I worked there for approximately 1 year, my major responsibility was to develop android applications. In 2015 I started working in a software company Node-Square . I worked there as a web developer and my major responsibility was to design and develop good quality responsive web applications, I really enjoy working in Node-Square and its March 2016, I am currently work there. Right now I am working primarily as a freelancer/part-time job. I am available for any queries.

Updated on June 25, 2022

Comments

  • farhangdon
    farhangdon almost 2 years

    I am new to image detection techniques. I am using java openCV to detect colors in an image. I am able to detect yellow and red colors. I got there value from hit and trial method, these are working fine. But I want to detect green , orange and blue color as well from the hand image below.

    enter image description here

    Here is a part of my code .

    public class ObjectPositionDetect {
    
    
        static int hueLowerR = 160;              // for red
        static int hueUpperR = 180;
    
    
    //    static int hueLowerR = 20;                  // for yellow
    //    static int hueUpperR = 31;
    
    
    
    
        public static void main(String[] args) {
            IplImage orgImg = cvLoadImage("3.JPG");
            IplImage thresholdImage = hsvThreshold(orgImg);
            cvSaveImage("test.jpg", thresholdImage);
            Dimension position = getCoordinates(thresholdImage);
            System.out.println("Dimension of original Image : " + thresholdImage.width() + " , " + thresholdImage.height());
            System.out.println("Position of red spot    : x : " + position.width + " , y : " + position.height);
        }
    
        static Dimension getCoordinates(IplImage thresholdImage) {
            int posX = 0;
            int posY = 0;
            CvMoments moments = new CvMoments();
            cvMoments(thresholdImage, moments, 1);
            // cv Spatial moment : Mji=sumx,y(I(x,y)•xj•yi)
            // where I(x,y) is the intensity of the pixel (x, y).
            double momX10 = cvGetSpatialMoment(moments, 1, 0); // (x,y)
            double momY01 = cvGetSpatialMoment(moments, 0, 1);// (x,y)
            double area = cvGetCentralMoment(moments, 0, 0);
            System.out.println("this is area "+area);
            posX = (int) (momX10 / area);
            posY = (int) (momY01 / area);
            return new Dimension(posX, posY);
        }
        public static CvScalar CV_RGB(double r, double g, double b) {
        return cvScalar(b, g, r, 0);
        //    return cvScalar(r, g, b, 0);
    }
    
        static IplImage hsvThreshold(IplImage orgImg) {
            // 8-bit, 3- color =(RGB)
            IplImage imgHSV = cvCreateImage(cvGetSize(orgImg), 8, 3);  // creating a copy of an image
            //cvSaveImage("monochromatic.jpg", imgHSV);
            //System.out.println(cvGetSize(orgImg));
            cvCvtColor(orgImg, imgHSV, CV_BGR2HSV);
            // 8-bit 1- color = monochrome
            IplImage imgThreshold = cvCreateImage(cvGetSize(orgImg), 8, 1);
    
            // cvScalar : ( H , S , V, A)
    
    
            cvInRangeS(imgHSV, cvScalar(hueLowerR, 100, 100, 0), cvScalar(hueUpperR, 255, 255, 0), imgThreshold);
    
           // cvInRangeS(imgHSV, cvScalar(160, 218, 0, 0), cvScalar(180, 220 , 0, 0), imgThreshold);
    
    
            cvReleaseImage(imgHSV);
            cvSmooth(imgThreshold, imgThreshold, CV_MEDIAN, 13);
             cvSaveImage("monochromatic.jpg", imgThreshold);
            // save
            return imgThreshold; 
        }
    }
    

    Kindly tell me how can I get the HSV ranges for Blue , Green and Orange colors or Just tell me the ranges for these required colors. Thanks

  • farhangdon
    farhangdon about 10 years
    I did a lot of search but was unable to search for a suitable HSV range which can work for me. I have given the sample ranges for red and yellow color in my code which works fine. Can you please tell me HSV ranges for Green , Orange or Blue color ? Thanks in advance.
  • skm
    skm about 10 years
    ok, i have already provided you a color wheel above which i have used myself too. You just need to divide the values by 2 and you will get the range as used by opencv.
  • farhangdon
    farhangdon about 10 years
    Thanks Bro. It helped. :)
  • farhangdon
    farhangdon almost 10 years
    I have detected almost every color from the above wheel , But Can You please guide me that How can I detect the skin color of hand(front side of hand) ? What's its HSV ?
  • skm
    skm almost 10 years
    Sorry, for that either you must hit and trial....or else i think that opencv provides some method for skin color detection.