Full width home advertisement

OpenCV

HTML

Post Page Advertisement [Top]

    In this Post I demonstrating how object can be segmented using OpenCV inRange function, where we use HSV colour space instead of BGR. HSV (hue, saturation, value) color-space is a model to represent the colorspace similar to the RGB. And hue channel is the only color type, it is easier to segment color in HSV color space.

OpenCV HSV Colour Segmentation

    The source code below will do the colour segmentation based on the HSV Minimum and Max Value selected using slider, the Min and Max value can be selected by clicking the color rectangle on HSV MIN and HSV MAX sub-window. See the demo video for how the value can be selected. The output show HSV representation of image, the threshold after inrange operation and segmented RGB image.

Demo Video


C++ Code

Here is the steps in the source code in brief.
  1. Load image
  2. Convert To HSV
  3. inRange create mask image for segment ion.
  4. Segment the image using above mask

int R,G,B,H,S,V;
int hue_val =50;
int sat_val =100;
int val_val =100;

int winWidth = 1920;
int winHeight = 1080;

int H_MIN = 50;
int S_MIN = 100;
int V_MIN = 100;

int H_MAX = 179;
int S_MAX = 255;
int V_MAX = 255;
int skip_counter = 3;

Rect HSV_MIN_RECT = Rect(winWidth*.04,winHeight*.6,winWidth*.08,winWidth*.08);
Rect HSV_MAX_RECT = Rect(winWidth*.19,winHeight*.6,winWidth*.08,winWidth*.08);



Rect SUB_WIN1_RECT = Rect(0, 0, winWidth/2,winHeight/2);
Rect SUB_WIN2_RECT = Rect(winWidth/2, 0, winWidth/2,winHeight/2);


bool hsv_min_selected = true;
char window_name[30] = "HSV Color Segmentation";

Mat window;
Mat src_Img;

Scalar Scalar_HSV_TO_BGR(uchar H, uchar S, uchar V) {
    Mat rgb;
    Mat hsv(1,1, CV_8UC3, Scalar(H,S,V));
    cvtColor(hsv, rgb, COLOR_HSV2BGR);
    return Scalar(rgb.data[0], rgb.data[1], rgb.data[2]);
     //return Scalar(hsv.data[0], hsv.data[1], hsv.data[2]);
}

void highlight_HSV_Draw(){

    skip_counter = 0;
    Mat subWin1 = window(Rect(0,window.rows*.5,window.cols*.33,window.rows/2));
    subWin1.setTo(Scalar::all(0));

    Scalar hsv_max_color(255,255,255);
    Scalar hsv_min_color(255,255,255);

    if(hsv_min_selected){

        hsv_min_color = Scalar(0,255,0);

        setTrackbarPos("HUE", window_name,H_MIN);
        setTrackbarPos("SAT", window_name,S_MIN);
        setTrackbarPos("VAL", window_name,V_MIN);
    }
    else{
        hsv_max_color = Scalar(0,255,0);
        setTrackbarPos("HUE", window_name,H_MAX);
        setTrackbarPos("SAT", window_name,S_MAX);
        setTrackbarPos("VAL", window_name,V_MAX);

    }




    cv::putText(window, format("H MIN = %d",H_MIN), cv::Point(winWidth*.05-50,winHeight*.8+40), FONT_HERSHEY_PLAIN,  2, hsv_min_color,  2,LINE_AA);
    cv::putText(window, format("S MIN = %d",S_MIN), cv::Point(winWidth*.05-50,winHeight*.8+80),FONT_HERSHEY_PLAIN,  2, hsv_min_color,  2,LINE_AA);
    cv::putText(window, format("V MIN = %d",V_MIN), cv::Point(winWidth*.05-50,winHeight*.8+120), FONT_HERSHEY_PLAIN,  2, hsv_min_color,  2,LINE_AA);
    cv::putText(window, format("H MAX = %d",H_MAX), cv::Point(winWidth*.2-50,winHeight*.8+40), FONT_HERSHEY_PLAIN,  2, hsv_max_color,  2,LINE_AA);
    cv::putText(window, format("S MAX = %d",S_MAX), cv::Point(winWidth*.2-50,winHeight*.8+80), FONT_HERSHEY_PLAIN,  2, hsv_max_color,  2,LINE_AA);
    cv::putText(window, format("V MAX = %d",V_MAX), cv::Point(winWidth*.2-50,winHeight*.8+120), FONT_HERSHEY_PLAIN,  2, hsv_max_color,  2,LINE_AA);

    //draw HSV value section
    rectangle(window,HSV_MIN_RECT,Scalar_HSV_TO_BGR(H_MIN,S_MIN,V_MIN),FILLED,LINE_AA);
    rectangle(window,HSV_MAX_RECT,Scalar_HSV_TO_BGR(H_MAX,S_MAX,V_MAX),FILLED,LINE_AA);

    //draw window border
    line(window,Point(0,window.rows*.5),Point(window.cols*.33,window.rows*.5),Scalar(255,255,255),2,LINE_AA);
    line(window,Point(window.cols*.33,window.rows*.5),Point(window.cols*.33,window.rows),Scalar(255,255,255),2,LINE_AA);

    //draw window title
    cv::putText(window, "HSV MIN", cv::Point(winWidth*.04,winHeight*.5+60), FONT_HERSHEY_TRIPLEX,  1.0, hsv_min_color,  2,LINE_AA);
    cv::putText(window, "HSV MAX", cv::Point(winWidth*.19,winHeight*.5+60), FONT_HERSHEY_TRIPLEX,  1.0, hsv_max_color,  2,LINE_AA);

    imshow(window_name,window);

}




Mat HSV_Color_Segment(){
    Mat HSV;
    Mat thr;
    // Convert from BGR to HSV colorspace
    cvtColor(src_Img, HSV, COLOR_BGR2HSV);
    // Detect the object based on HSV Range Values
    inRange(HSV, Scalar(H_MIN, S_MIN, V_MIN), Scalar(H_MAX, S_MAX, V_MAX), thr);
    return thr;
}

void updateUI(){

    if(skip_counter<3){
        skip_counter++;
        return;
    }
    Mat subWin1 = window(Rect(0,window.rows*.5,window.cols*.33,window.rows/2));
    subWin1.setTo(Scalar::all(0));

    Scalar hsv_max_color(255,255,255);
    Scalar hsv_min_color(255,255,255);

    if(hsv_min_selected){
        H_MIN = hue_val;
        S_MIN = sat_val;
        V_MIN = val_val;
        hsv_min_color = Scalar(0,255,0);
    }
    else{
        H_MAX = hue_val;
        S_MAX = sat_val;
        V_MAX = val_val;
        hsv_max_color = Scalar(0,255,0);

    }




    cv::putText(window, format("H MIN = %d",H_MIN), cv::Point(winWidth*.05-50,winHeight*.8+40), FONT_HERSHEY_PLAIN,  2, hsv_min_color,  2,LINE_AA);
    cv::putText(window, format("S MIN = %d",S_MIN), cv::Point(winWidth*.05-50,winHeight*.8+80),FONT_HERSHEY_PLAIN,  2, hsv_min_color,  2,LINE_AA);
    cv::putText(window, format("V MIN = %d",V_MIN), cv::Point(winWidth*.05-50,winHeight*.8+120), FONT_HERSHEY_PLAIN,  2, hsv_min_color,  2,LINE_AA);
    cv::putText(window, format("H MAX = %d",H_MAX), cv::Point(winWidth*.2-50,winHeight*.8+40), FONT_HERSHEY_PLAIN,  2, hsv_max_color,  2,LINE_AA);
    cv::putText(window, format("S MAX = %d",S_MAX), cv::Point(winWidth*.2-50,winHeight*.8+80), FONT_HERSHEY_PLAIN,  2, hsv_max_color,  2,LINE_AA);
    cv::putText(window, format("V MAX = %d",V_MAX), cv::Point(winWidth*.2-50,winHeight*.8+120), FONT_HERSHEY_PLAIN,  2, hsv_max_color,  2,LINE_AA);

    //draw HSV value section
    rectangle(window,HSV_MIN_RECT,Scalar_HSV_TO_BGR(H_MIN,S_MIN,V_MIN),FILLED,LINE_AA);
    rectangle(window,HSV_MAX_RECT,Scalar_HSV_TO_BGR(H_MAX,S_MAX,V_MAX),FILLED,LINE_AA);



    //draw window border
    line(window,Point(0,window.rows*.5),Point(window.cols*.33,window.rows*.5),Scalar(255,255,255),2,LINE_AA);
    line(window,Point(window.cols*.33,window.rows*.5),Point(window.cols*.33,window.rows),Scalar(255,255,255),2,LINE_AA);

    //draw window title
    cv::putText(window, "HSV MIN", cv::Point(winWidth*.04,winHeight*.5+60), FONT_HERSHEY_TRIPLEX,  1.0, hsv_min_color,  2,LINE_AA);
    cv::putText(window, "HSV MAX", cv::Point(winWidth*.19,winHeight*.5+60), FONT_HERSHEY_TRIPLEX,  1.0, hsv_max_color,  2,LINE_AA);



    //Do Color segmanetiaon and Draw Image on window
    Mat thr = HSV_Color_Segment();
    Mat thrBGR;
    cvtColor(thr,thrBGR,COLOR_GRAY2BGR);
    resize(thrBGR,thrBGR,Size(winWidth*.33,winHeight/2));
    thrBGR.copyTo(window(Rect(winWidth*.33,winHeight*.5, winWidth*.33,winHeight/2)));

    Mat segmented;
    src_Img.copyTo(segmented,thr);
    resize(segmented,segmented,Size(winWidth*.33,winHeight/2));
    segmented.copyTo(window(Rect(winWidth*.66,winHeight*.5, winWidth*.33,winHeight/2)));

    //Draw output window title
    rectangle(window,Rect(winWidth*.43-30,winHeight*.5+3,250,60),Scalar(0,0,0),FILLED,LINE_AA);
    rectangle(window,Rect(winWidth*.76-30,winHeight*.5+3,250,60),Scalar(0,0,0),FILLED,LINE_AA);
    cv::putText(window, "Threshold", cv::Point(winWidth*.43,winHeight*.5+40), FONT_HERSHEY_TRIPLEX,  1.0, Scalar(255,255,255),  2,LINE_AA);
    cv::putText(window, "Segmented", cv::Point(winWidth*.76,winHeight*.5+40), FONT_HERSHEY_TRIPLEX,  1.0, Scalar(255,255,255),  2,LINE_AA);

    //draw RGB HSV value on mouse pointer
    cv::putText(window, format("B=%d  G=%d  R=%d   H=%d  S=%d  V=%d",B,G,R,H,S,V), cv::Point(10,winHeight-20), FONT_HERSHEY_SIMPLEX,  .7, Scalar(0,0,255), 2,LINE_AA);
    imshow(window_name,window);
}

static void onMouse( int event, int x, int y, int f, void* ){
    if(f&EVENT_FLAG_LBUTTON){

           //check HSV Rect clicked or not
           if(HSV_MIN_RECT.contains(Point(x,y)))
               hsv_min_selected = true;
           else if(HSV_MAX_RECT.contains(Point(x,y)))
               hsv_min_selected = false;
       highlight_HSV_Draw();

    }

    else if(f==EVENT_MOUSEMOVE){

        // Took color on first three window only
        //if(HSV_MIN_RECT.contains(Point(x,y))||HSV_MAX_RECT.contains(Point(x,y))||SUB_WIN1_RECT.contains(Point(x,y))||SUB_WIN2_RECT.contains(Point(x,y))){
            //draw HSV and RGB Value on Image
            Mat subWin = window(Rect(0,winHeight-60,window.cols*.33,60));
            subWin.setTo(Scalar::all(0));
            Mat HSV;
            Mat BGR=window(Rect(x,y,1,1));
            cvtColor(BGR, HSV,COLOR_BGR2HSV);
            B = BGR.data[0];  G = BGR.data[1];  R = BGR.data[2];
            H = HSV.data[0];  S = HSV.data[1];  V = HSV.data[2];

            cv::putText(window, format("B=%d  G=%d  R=%d   H=%d  S=%d  V=%d",B,G,R,H,S,V), cv::Point(10,winHeight-20), FONT_HERSHEY_SIMPLEX,  .7, Scalar(0,0,255), 2,LINE_AA);
            imshow(window_name,window);
        //}

    }

}

static void on_trackbar_changed(int, void*){
   updateUI();
}



int main()
{
    window = Mat(winHeight,winWidth,CV_8UC3,Scalar::all(0));
    src_Img = imread("img/shapes.jpg", IMREAD_COLOR);
    Mat resizeSrc;
    resize(src_Img,resizeSrc,Size(winWidth/2,winHeight/2)); //resize to fit on input widnow
    Mat HSV;
    cvtColor(resizeSrc, HSV,COLOR_BGR2HSV);
    resizeSrc.copyTo(window(SUB_WIN1_RECT)); //copy  input to  window
    HSV.copyTo(window(SUB_WIN2_RECT)); //copy HSV to window



    namedWindow(window_name, WINDOW_NORMAL); // Create Window
    resizeWindow(window_name,winWidth,winHeight);
    createTrackbar( "HUE", window_name, &hue_val, 179, on_trackbar_changed );
    createTrackbar( "SAT", window_name, &sat_val, 255,on_trackbar_changed );
    createTrackbar( "VAL", window_name, &val_val, 255, on_trackbar_changed );
    setTrackbarPos("HUE", window_name,H_MIN);
    setTrackbarPos("SAT", window_name,S_MIN);
    setTrackbarPos("VAL", window_name,V_MIN);
    setMouseCallback( window_name, onMouse, 0 );



    //Title for Window
    rectangle(window,Rect(winWidth*.2-30,5,250,60),Scalar(0,0,0),FILLED,LINE_AA);
    rectangle(window,Rect(winWidth*.72-40,5,150,60),Scalar(0,0,0),FILLED,LINE_AA);
    cv::putText(window, "Input(BGR)", cv::Point(winWidth*.2, 40), FONT_HERSHEY_TRIPLEX,  1.0, CV_RGB(255, 255,255),  2,LINE_AA);
    cv::putText(window, "HSV", cv::Point(winWidth*.72, 40), FONT_HERSHEY_TRIPLEX,  1.0, CV_RGB(255, 255,255),  2,LINE_AA);



    //draw window border
    line(window,Point(0,window.rows*.5),Point(window.cols,window.rows*.5),Scalar(255,255,255),3,LINE_AA);
    line(window,Point(window.cols*.5,0),Point(window.cols*.5,window.rows*.5),Scalar(255,255,255),3,LINE_AA);
    line(window,Point(window.cols*.33,window.rows*.5),Point(window.cols*.33,window.rows),Scalar(255,255,255),3,LINE_AA);
    line(window,Point(window.cols*.66,window.rows*.5),Point(window.cols*.66,window.rows),Scalar(255,255,255),3,LINE_AA);


    updateUI();

     while(true)
      {
        int c;
        c = waitKey( 20 );
        if( (char)c == 27 )
          { break; }
       }
    return 0;
}


No comments:

Post a Comment

Bottom Ad [Post Page]

| Designed by Colorlib