ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • OpenCV 강좌 C++ & Python - 폴리곤(Polygon) 그리는 polylines, fillPoly 함수 사용법
    OpenCV/OpenCV C++&Python 강좌 2019. 8. 11. 23:14



    OpenCV의 폴리곤(Polygon)을 그리는 함수 polylines, .fillPoly에 대해 설명합니다.




    2015.  1. 2 - 최초 작성

    2018.  7. 16 

    2018.  8. 11 - C++ 코드 추가



    폴리곤 그리는 함수를 사용하여 오각형 외곽선과 내부가 채워진 오각형을 그려줍니다.





    Python


    import numpy as np
    import cv2 as cv


    width = 640
    height = 640
    bpp = 3

    img = np.zeros((height, width, bpp), np.uint8)


    red = (0, 0, 255)
    green = (0, 255, 0)
    blue = (255, 0, 0)
    white = (255, 255, 255)
    yellow = (0, 255, 255)
    cyan = (255, 255, 0)
    magenta = (255, 0, 255)



    thickness = 2


    pts = np.array([[315, 50], [570, 240], [475, 550], [150, 550], [50, 240]], np.int32)
    pts = pts.reshape((-1, 1, 2))
    cv.polylines(img, [pts], False, green, thickness) 



    pts = np.array([[315, 160], [150, 280], [210, 480], [420, 480], [480, 280]], np.int32)
    pts = pts.reshape((-1, 1, 2))
    cv.polylines(img, [pts], True, green, thickness) 



    pts = np.array([[320, 245], [410, 315], [380, 415], [265, 415], [240, 315]], np.int32)
    pts = pts.reshape((-1, 1, 2))
    cv.fillPoly(img, [pts], yellow) 



    cv.imshow("drawing", img)
    cv.waitKey(0);



    C++


    #include <opencv2/opencv.hpp>


    using namespace cv;
    using namespace std;


    int main()
    {
    // 컬러 이미지를 저장할 Mat 개체를 생성합니다.
    int width = 640;
    int height = 640;

    Mat img(height, width, CV_8UC3, Scalar(0, 0, 0));


    Scalar red(0, 0, 255);
    Scalar green(0, 255, 0);
    Scalar blue(255, 0, 0);
    Scalar white(255, 255, 255);
    Scalar yellow(0, 255, 255);
    Scalar cyan(255, 255, 0);
    Scalar magenta(255, 0, 255);



    int thickness = 2;

    vector<Point> contour;
    contour.push_back(Point(315, 50));
    contour.push_back(Point(570, 240));
    contour.push_back(Point(475, 550));
    contour.push_back(Point(150, 550));
    contour.push_back(Point(50, 240));

    const Point *pts1 = (const cv::Point*) Mat(contour).data;
    int npts1 = Mat(contour).rows;

    polylines(img, &pts1, &npts1, 1, false, green, thickness);


    contour.clear();
    contour.push_back(Point(315, 160));
    contour.push_back(Point(150, 280));
    contour.push_back(Point(210, 480));
    contour.push_back(Point(420, 480));
    contour.push_back(Point(480, 280));

    const Point *pts2 = (const cv::Point*) Mat(contour).data;
    int npts2 = Mat(contour).rows;

    polylines(img, &pts2, &npts2, 1, true, green, thickness);  


    contour.clear();
    contour.push_back(Point(320, 240));
    contour.push_back(Point(410, 315));
    contour.push_back(Point(380, 415));
    contour.push_back(Point(265, 415));
    contour.push_back(Point(240, 315));

    const Point *pts3 = (const cv::Point*) Mat(contour).data;
    int npts3 = Mat(contour).rows;

    fillPoly(img, &pts3, &npts3, 1, yellow);


    imshow("result", img);
    waitKey(0);


    return 0;
    }





    이제 코드를 설명합니다.



    1. 모든 픽셀값이 0으로 초기화된 이미지를 생성하여 여기에 폴리곤을 그립니다. 자세한 설명은  첫번째 포스팅을 참고하세요.  


    img = np.zeros((height, width, bpp), np.uint8)




    2. 포스팅 작성 편리를 위해 색깔별로 튜플 객체를 생성해두었습니다.  

    튜플의 값은 ( blue, green. red) 순으로 입력해야 합니다. 


    red = (0,0,255)
    green = (0,255,0)
    blue = (255,0,0)
    white = (255,255,255)
    yellow = (0,255,255)
    cyan = (255, 255, 0)
    magenta = (255, 0, 255)




    3.  cv.polylines함수는  이미지(ndarray 객체) img에 폴리곤 외곽선을 그립니다. 

    아규먼트는 다음과 같습니다. (노란색 아규먼트들은 생략가능합니다.)


    img = cv.polylines( img,   폴리곤이 그려질 이미지 

                            pts,   폴리곤을 구성하는 정점(veryes)이 저장되어 있는 배열     

                       isClosed,   pts의 첫번째 정덤과 마지막 정점을 연결할지 여부  

                          color,   폴리곤의 색

                      thickness,   디폴트값 1

                       lineType,   디폴트값 cv.LINE_8(=8-connected line)

                          shift )  디폴트값 0



     cv.fillPoly함수는  이미지(ndarray 객체) img에 내부가 채워진 폴리곤을 그립니다. 

    아규먼트는 다음과 같습니다. (노란색 아규먼트들은 생략가능합니다.)


    img = cv.fillPoly( img, pts, color[, lineType[, shift[, offset]]] )



    img = cv.fillPoly( img,   폴리곤이 그려질 이미지 

                            pts,   폴리곤을 구성하는 정점(veryes)이 저장되어 있는 배열     

                          color,   폴리곤의 색

                       lineType,   디폴트값 cv.LINE_8(=8-connected line)

                          shift 디폴트값 0

                         offset )  모든 정점에 적용되는 오프셋




    4. 선굵기(thickness) 를 2로 고정하고 진행합니다. 


    thickness = 2 




    5.  np.array함수를 사용하여 시계방향으로 다섯개의 정점에 대한 2차원 좌표를 배열에 저장합니다. shape가 (5, 2)인 ndarray 객체가 생성됩니다. 


    ndarray 객체의  shape를 (-1, 1, 2)로 변경하면 (5, 1, 2)인 ndarray 객체로 변경됩니다. -

    shape에서 -1로 적은 차원은 자동으로 계산되어 입력됩니다. 


    cv.polylines 함수는 pts에 저장되어 있는 정점을 사용하여 이미지 img에 폴리곤을 그립니다. 

    세번째 아규먼트가 False라서 pts에 저장되어 있는 첫번째 정점과 마지막 정점을 연결하지 않습니다. 


    pts = np.array([[315, 50], [570, 240], [475, 550], [150, 550], [50, 240]], np.int32)
    pts = pts.reshape((-1, 1, 2))
    cv.polylines(img, [pts], False, green, thickness)





    6. 반시계 방향으로 정점들을 배열에 저장해도 폴리곤이 그려집니다.

    세번째 아규먼트가 True라서 pts에 저장되어 있는 첫번째 정점과 마지막 정점이 연결됩니다.


    pts = np.array([[315, 160],[150,280],[210,480],[420,480], [480, 280]], np.int32)
    pts = pts.reshape((-1,1,2))
    cv.polylines(img,[pts], True, green, thickness)





    7. cv.fillPoly함수를 호출하면 지정한 색으로 폴리곤이 채워집니다. 


    pts = np.array([[320, 245],[410,315],[380,415],[265,415], [240, 315]], np.int32)
    pts = pts.reshape((-1,1,2))
    cv.fillPoly(img, [pts], yellow)  





    8.  이제 윈도우 창 “drawing”에 이미지 img를 보여줍니다. 

    이후 waitKey 함수의 아규먼트가 0이기 때문에 사용자가 키보드를 누르기 전까지 대기합니다. 


    cv.imshow("drawing", img)

    cv.waitKey(0);




    참고

    https://gist.github.com/MareArts/54011c365ec0d66d59562945df13dbfe



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

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

    유튜브 구독하기


    댓글 0

Designed by Tistory.