ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • OpenCV 강좌 - 3. OpenCV를 사용하여 특정색 오브젝트 추적하기
    OpenCV/OpenCV C++ 강좌 2019. 6. 26. 14:51


    OpenCV를 사용하여 특정색 오브젝트를 추적(tracking)하는 코드를 만들어봅니다.


    포스팅 아래에 있는 코드는  마우스로 클릭한 픽셀값을 HSV로 변환하여 해당 색에 대한 일정 범위를 만듭니다.

    그리고나서 카메라로부터 캡처한 영상에서 해당 범위의 색만 추출하여 화면에 보여줍니다.

    실행시켜보면 완벽하게 특정색만 추출하지 못합니다.





    영상에서는 이 코드를 개선하여 특정색 오브젝트를 추적하는 코드를 작성합니다.







    #include <opencv2/core.hpp>
    #include <opencv2/imgproc.hpp>
    #include <opencv2/videoio.hpp>
    #include <opencv2/highgui.hpp>
    #include <iostream>

    using namespace cv;
    using namespace std;



    int threshold1 = 30;

    Vec3b lower_blue1, upper_blue1, lower_blue2, upper_blue2, lower_blue3, upper_blue3;
    Mat img_color;

    void mouse_callback(int event, int x, int y, int flags, void *param)
    {
    if (event == EVENT_LBUTTONDOWN)
    {
    Vec3b color_pixel = img_color.at<Vec3b>(y, x);

    Mat bgr_color = Mat(1, 1, CV_8UC3, color_pixel);


    Mat hsv_color;
    cvtColor(bgr_color, hsv_color, COLOR_BGR2HSV);

    int hue = hsv_color.at<Vec3b>(0, 0)[0];
    int saturation = hsv_color.at<Vec3b>(0, 0)[1];
    int value = hsv_color.at<Vec3b>(0, 0)[2];

    cout << "hue = " << hue << endl;
    cout << "saturation = " << saturation << endl;
    cout << "value = " << value << endl;


    if (hue < 10)
    {
    cout << "case 1" << endl;
    lower_blue1 = Vec3b(hue - 10 + 180, threshold1, threshold1);
    upper_blue1 = Vec3b(180, 255, 255);
    lower_blue2 = Vec3b(0, threshold1, threshold1);
    upper_blue2 = Vec3b(hue, 255, 255);
    lower_blue3 = Vec3b(hue, threshold1, threshold1);
    upper_blue3 = Vec3b(hue+10, 255, 255);
    }
    else if (hue > 170)
    {
    cout << "case 2" << endl;
    lower_blue1 = Vec3b(hue, threshold1, threshold1);
    upper_blue1 = Vec3b(180, 255, 255);
    lower_blue2 = Vec3b(0, threshold1, threshold1);
    upper_blue2 = Vec3b(hue + 10 - 180, 255, 255);
    lower_blue3 = Vec3b(hue - 10, threshold1, threshold1);
    upper_blue3 = Vec3b(hue, 255, 255);
    }
    else
    {
    cout << "case 3" << endl;
    lower_blue1 = Vec3b(hue, threshold1, threshold1);
    upper_blue1 = Vec3b(hue + 10, 255, 255);
    lower_blue2 = Vec3b(hue - 10, threshold1, threshold1);
    upper_blue2 = Vec3b(hue, 255, 255);
    lower_blue3 = Vec3b(hue - 10, threshold1, threshold1);
    upper_blue3 = Vec3b(hue, 255, 255);
    }

    cout << "hue = " << hue << endl;
    cout << "#1 = " << lower_blue1 << "~" << upper_blue1 << endl;
    cout << "#2 = " << lower_blue2 << "~" << upper_blue2 << endl;
    cout << "#3 = " << lower_blue3 << "~" << upper_blue3 << endl;
    }
    }



    int main()
    {
    namedWindow("img_color");
    setMouseCallback("img_color", mouse_callback);


    Mat img_hsv;

    VideoCapture cap(0);
    if (!cap.isOpened()) {

    cout << "카메라를 열 수 없습니다." << endl;
    return -1;
    }


    while(1)
    {
    cap.read(img_color);

    cvtColor(img_color, img_hsv, COLOR_BGR2HSV);

    Mat img_mask1, img_mask2, img_mask3, img_mask;
    inRange(img_hsv, lower_blue1, upper_blue1, img_mask1);
    inRange(img_hsv, lower_blue2, upper_blue2, img_mask2);
    inRange(img_hsv, lower_blue3, upper_blue3, img_mask3);
    img_mask = img_mask1 | img_mask2 | img_mask3;


    Mat img_result;
    bitwise_and(img_color, img_color, img_result, img_mask);

    imshow("img_color", img_color);
    imshow("img_mask", img_mask);
    imshow("img_result", img_result);

    if (waitKey(1)>0)
    break;
    }


    return 0;
    }




    포스트 작성시에는 문제 없었지만 이후 문제가 생길 수 있습니다.
    댓글로 알려주시면 빠른 시일내에 답변을 드리겠습니다.

    여러분의 응원으로 좋은 컨텐츠가 만들어집니다. 지금 본 내용이 도움이 되었다면 유튜브 구독 부탁드립니다. 감사합니다 : )

    유튜브 구독하기


    댓글 17

    • 박혁거세 2019.01.08 00:56


      안녕하세요 강의랑 포스팅 잘보고있습니다

      다만, 궁금한점이 CV_EVENT_LBUTTONDOWN 이부분이, 식별자에서 정의가 되어있지않다고 되어있는데, 혹시 해결부분이 없을까요? 코드는 그대로 복사했습니다.

    • ddwkw 2019.02.20 03:20


      안녕하세요 강의랑 포스팅 보면서 코드를 짜보고있습니다.
      헌데 검은색을 구별 하려면 hsv값을 어떻게 설정 해야 할까요?

    • 2019.03.08 10:44


      안녕하세요 혹시 실행후 창이 카메라화면 하나만뜨는데 혹시 어떻게해야하는지 알수있을까요??

    • watchwatch 2019.03.10 17:27


      안녕하세요 강의 잘 보고 있습니다. 프로젝트 진행 중에 궁금한 점이 있어서 글 올립니다.
      마우스로 클릭한 색상을 추적하는 것 까지 완벽하게 되는데, 이 추적되는 물체의 좌표를 출력할 수 있는 방법이 있을까요??

      • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.03.10 17:36 신고


        라벨링을 하면 됩니다. 이미 강좌에 코드가 포함되어 있습니다.

        사각형과 원을 그리는 부분에 추적할 물체의 좌표가 포함되어 있습니다.

        https://webnautes.tistory.com/823

    • 소고기 2019.05.21 19:22


      빨간색과 주황색, 연두색과 노란색 같이 색상의 구분이 모호한 색상들의 구분이 명확하게 되지 않는 문제는 어떻게 해결할수 있을까요?.

      영상에서도 주황색이 많이 섞이는 피부색과 빨간색의 구분이 잘안되는거 같아서요

      • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.05.21 20:09 신고


        영상에서 유사한 색을 구분하는 것은 어렵습니다.

        조명에 따라 유사한 색이 같은 색으로 검출되기 때문입니다

        저도 아직은 확실한 해결방법은 모릅니다..

    • hjhj 2019.05.28 02:28


      안녕하세요 opencv를 공부하는 학생입니다. 항상 강의 자료 잘 보고 있습니다 . 너무너무 감사합니다!!
      궁금한게 있는데 왜 HSV색상을 lower_blue1,2,3 와upper_blue1,2,3로 3단계로 나눠놧는지 이해가 잘 안되서 여쭤봅니다!!

      • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.05.28 05:50 신고


        OpenCV에서 HSV 색공간의 Hue값이 0 ~ 180도의 범위를 가지며

        코드에서는 지정한 hue값 -10에서 hue값 + 10의 범위로 색 범위를 지정합니다.

        그런데 Hue값이 10도 이하거나 170도 이상인 경우 Hue 범위 처음이나 범위 끝에 걸치기 때문에 범위를 셋으로 분리한 것입니다.

      • HJ 2019.05.30 16:35


        감사합니다!!!

    • weme 2019.11.26 23:44


      지금 이와 관련된 코드를 짜야하는데 도와주실수있나요?

    • weme 2019.11.27 11:28


      따로 연락드릴방법이 있을까요? 아니면 여기다 올려야하나요?

Designed by Tistory.