OpenCV 핸드북 (cheatsheet)

프로그래밍/opencv 2013.02.27 18:47

제가 개인적 참고용으로 만든 opencv 함수들 사용법 목록입니다. 간단한 함수라 하더라도 함수이름이나 사용법이 잘 기억나지 않을 때가 종종 있습니다. 한 부 출력해 놓고 이럴 때 보면 꽤 유용합니다.


1. 이미지 읽기 & 저장

2. 이미지 생성, 복사, 형변환, 색상변환, roi 설정

3. 행렬 원소접근 및 생성초기화

4. 영상 크기변경 및 상하좌우 반전

5. 이미지에 그리기 (drawing)

6. 이미지 디스플레이하기 (display)

7. 웹캠 연결하기

8. avi 비디오 파일 읽어오기

9. avi 비디오 녹화하기

10. 창에 Trackbar 붙이기



1. 이미지 읽기 & 저장

Mat img_color = imread("sample.jpg"); // color load

Mat img_gray = imread("sample.jpg", 0);// gray load

imwrite("fname.jpg", img);


2. 이미지 생성, 복사, 형변환, 색상변환, roi 설정

int w = 320;// width

int h = 240;// height


// 생성

Mat img(h,w,CV_8UC1);//1채널 unsigned char

Mat img(h,w,CV_8UC3);//3채널 unsigned char

Mat img = Mat::zeros(h,w,CV_32FC1);//1채널 float

Mat img = Mat::ones(h,w,CV_64FC3);//3채널 double


unsigned char * img_buffer;// 이미지버퍼 포인터

Mat img(h, w, CV_8UC3, img_buffer);//메모리 공유


// 타입 만들기

CV_MAKETYPE(CV_32F, 3);    // CV_32FC3


// 원소 초기화

Mat img(h,w,CV_8UC1);

img = Scalar(3); // img 모든 원소값 3으로 초기화


// 참조, 복사

Mat img2 = img; // 메모리 공유

Mat img2 = img.clone(); // 별도 메모리

Mat img2; img.copyTo(img2);//별도 메모리


// 형변환 복사

Mat img1(h,w,CV_32FC1);

Mat img2;

img1.convertTo(img2, CV_8U);


// gray-color 변환

cvtColor(color, gray, CV_BGR2GRAY);

cvtColor(gray, color, CV_GRAY2BGR);


// roi 설정

Rect roi;

Mat sub_img = img(roi);//메모리공유

Mat sub_img = img(roi).clone();//별도메모리


3. 행렬 원소접근 및 생성초기화

Mat A = (Mat_<int>(3,1) << 1, 2, 3);

Mat B = (Mat_<double>(3,2) << 1, 1, 2, 2, 3, 3); // 첫 번째 행부터 채워짐

A.at<int>(2,0) = 3; // .at<type>(y, x)

B.at<double>(2,1) = -0.1;


Mat C(h, w, CV_8UC3);

C.at<Vec3b>(y, x)[0]; // blue

C.at<Vec3b>(y, x)[1]; // green 

C.at<Vec3b>(y, x)[2]; // red


4. 영상 크기변경 및 상하좌우 반전

// 크기 변경

Mat dst;

resize(img, dst, Size(new_w,new_h));

resize(img, dst, Size(), 0.5, 0.5);//scalex, scaley


// 영상 반전(flip)

flip(img, dst, 0);// vertical flip

flip(img, dst, 1);// horizontal flip

flip(img, dst, -1);// vertial & horizontal flip


5. 이미지에 그리기 (drawing)

Rect rc(x,y,w,h);

Scalar color(B,G,R);

int thickness=1; // line thickness


line(img, Point(x1,y1), Point(x2,y2), color, thickness);


rectangle(img, rc, color, thickness);

rectangle(img, rc.tl(), rc.br(), color, thickness);

rectangle(img, rc, color, CV_FILLED); // filled rectangle


Point center(rc.x+rc.width/2, rc.y+rc.height/2);

Size radius(rc.width/2, rc.height/2);

double rot_deg = 0; // rotation of ellipse

double s_deg = 0; // start angle of arc

double e_deg = 360; // end angle of arc

ellipse(img,center,radius,rot_deg,s_deg,e_deg,color,thickness);

ellipse(img,center,radius,rot_deg,s_deg,e_deg,color,CV_FILLED);


int circle_radius = 10;

circle(img, center, circle_radius, color, thickness);

circle(img, center, circle_radius, color, CV_FILLED);


putText(img, "text", Point(x,y), FONT_HERSHEY_SIMPLEX, 1., color, thickness);

putText(img, "text", Point(x,y), FONT_HERSHEY_DUPLEX, 1., color, thickness);


6. 이미지 디스플레이하기 (display)

namedWindow("name"); // auto resized

namedWindow("name",CV_WINDOW_NORMAL); // manual resize


imshow("name", img);

char ch = waitKey(); // 무한 대기

char ch = waitKey(10); // 10 msec 대기

if(ch == 27) ... // ESC key

if(ch == 32) ... // SPACE key


destroyWindow("name");

destroyAllWindows();


7. 웹캠 연결하기

VideoCapture vc(0);

if (!vc.isOpened()) return; // 연결실패

vc.set(CV_CAP_PROP_FRAME_WIDTH, 640);

vc.set(CV_CAP_PROP_FRAME_HEIGHT, 480);


Mat img;

while(1){

vc >> img;

if(img.empty()) break;

imshow("cam",img);

if(waitKey(10)==27) break; //ESC

}

destroyAllWindows();


8. avi 비디오 파일 읽어오기

VideoCapture vc("sample.avi");

if (!vc.isOpened()) return; // 불러오기 실패


Mat img;

while(1){

vc >> img;

if(img.empty()) break;

imshow("video",img);

if(waitKey(10)==27) break; //ESC

}

destroyAllWindows();

9. avi 비디오 녹화하기

double fps = 15;

int fourcc = CV_FOURCC('X','V','I','D'); // codec (opencv3.0이하)

int fourcc = VideoWriter::fourcc('X','V','I','D'); // opencv3.0이상


bool isColor = true;


VideoWriter *video = new VideoWriter;

if(!video->open("result.avi", fourcc, fps, Size(img_w, img_h), isColor)){

delete video;

return;

}


Mat img;

while(1){

// ...

*video << img;

// ...

}

delete video;


※ 코덱 목록: http://www.fourcc.org/codecs.php


10. 창에 Trackbar 붙이기

int threshold = 10;

cv::namedWindow("display");

cv::createTrackbar("thr:", "display", &threshold, 1000);


11. 다운로드


OpenCV핸드북v1.txt



참고로 영상처리 라이브러리인 OpenCV 공식 홈페이지에서 제공하는 cheatsheet라는게 있습니다. opencv 함수 사용법을 요약해 놓은 2페이지짜리 pdf 파일입니다.


by 다크 프로그래머

저작자 표시 비영리 변경 금지
신고
  • 따옥 2014.02.26 17:57 신고 ADDR 수정/삭제 답글

    오늘 입문하였는데 덕분에...
    감사합니다.

  • 챗동 2014.11.01 14:34 신고 ADDR 수정/삭제 답글

    정말 잘쓰고 있습니다.

  • 2014.11.17 19:06 ADDR 수정/삭제 답글

    비밀댓글입니다

    • BlogIcon 다크pgmr 2014.11.17 22:55 신고 수정/삭제

      네, 일단 imwrite('fname.jpg', img)는 img라는 변수의 내용을 이미지로 저장해 주는 함수입니다. 따라서, img라는 변수는 2차원의 행렬 형태의 변수여야 하는데 opencv에서는 행렬을 Mat이라는 클래스로 나타냅니다. Mat이라는 클래스로 이미지 변수를 생성하는 방법은 위 본문 내용에서 2. 이미지 생성, 복사, ... 단락의 //생성 부분에 5가지 방법이 설명되어 있습니다(Mat img(h,w,CV_8UC1), Mat img(h,w,CV_8U3C), ...).
      제 생각에는 일단은 opencv 관련 서적을 초반부라도 먼저 읽어보시는게 좋을 것 같습니다.

  • elect 2015.08.22 23:23 신고 ADDR 수정/삭제 답글

    글 잘봤습니다.
    한가지 질문이있는데 비디오 저장을 위와같이 제대로 저장하였는데
    imshow에서는 제대로 출력되는데 왜 저장된 파일을 곰플레이어로 키면 검정화면만나올까요

    • BlogIcon 다크pgmr 2015.08.23 16:38 신고 수정/삭제

      비디오 코덱에는 정말 다양한 종류가 있습니다. XVID외의 다른 비디오 코덱 종류도 시도해 보시면 좋을 것 같습니다. 다른 사용 가능한 코덱에 대한 fourcc에 대해서는 http://www.fourcc.org/codecs.php을 참조하시기 바랍니다. 그리고 곰플레이어에는 자체 코덱이 내장되어 있어서 어지간하면 플레이가 될텐데 조금 이상하긴 합니다. 별도로 통합코덱을 설치해 보시거나 다른 동영상 플레이어를 사용해 보시는 것도 방법입니다.

  • 123 2015.08.22 23:24 신고 ADDR 수정/삭제 답글

    그냥 저렇게 return이라고 하면 main함수는 값을 반환해야한다고 뜹니다!!

    • BlogIcon 다크pgmr 2015.08.23 16:41 신고 수정/삭제

      네, c나 c++에서 기본적인 문법에 관련된 내용입니다. 사용하는 함수의 반환값이 void면 그냥 return만 하면 되고, 함수의 반환값이 int형이면 int형을 반환해야 합니다.

  • dndhkdrnt 2015.12.04 20:14 신고 ADDR 수정/삭제 답글

    우와!
    감사합니다!

  • 11 2016.01.14 17:20 신고 ADDR 수정/삭제 답글

    videocapture 사용해서 웹캠 연결하고 캡쳐후 저장하는 코드는 어떻게 작성하나요?

    • BlogIcon 다크pgmr 2016.01.14 17:56 신고 수정/삭제

      vc >> img; 로 캡쳐후 imwrite("tt.jpg", img); 등으로 저장하면 됩니다.

  • cv 2016.01.27 13:27 신고 ADDR 수정/삭제 답글

    CvvImgae를 사용해서 Picture control에 영상을 집어넣을때, 640x480해상도의 캠은 인식되나, 1920x1080해상도의 캠을 사용했을때는 회색화면만 나오는 문제가 발생합니다.
    혹시 videocapture함수를 사용해서 picture control에 영상을 집어넣을 수 있는 방법이 있을까요???
    videocpature를 사용해서 1920x1080해상도의 캠 영상을 받아들이는 부분까지는 해봤습니다만, 어딜 뒤져봐도 picture control과 연동하는 방법에 대해서는 쓰여있지 않아서 여쭤봅니다.

    • BlogIcon 다크pgmr 2016.01.29 14:55 신고 수정/삭제

      말씀하신 picture control이 무엇인지는 잘 모르지만 당연히 가능할 것이라고 생각합니다. 하지만 구체적인 프로그래밍에 관련된 부분은 제가 답변해 드릴 수 있는 사항이 아닙니다. 이미지의 메모리 구조에 대해 공부해 보시면 좋을 것 같습니다.

  • 비젼 2016.04.02 20:18 신고 ADDR 수정/삭제 답글

    다크님 제가 매트랩 코드를 open cv포팅중인데.. 디버깅중에 이미지데이터를 추적해보니 rgb데이터를 2차원으로 받아오는걸 발견했습니다. 3차원이어야 맞는 것 같은데 혹시 이유를 알 수 있을까요?

    • BlogIcon 다크pgmr 2016.04.03 07:12 신고 수정/삭제

      이유는 알수 없습니다만, 혹시 imread 함수를 사용한 것이라면 함수의 파라미터를 어떻게 주느냐에 따라서 color로도 gray로도 이미지를 읽을 수 있으니 함수 설명을 참조해 보시기 바랍니다.

  • 후으 2016.05.17 12:01 신고 ADDR 수정/삭제 답글

    Rect roi;
    Mat sub_img = img(roi);//메모리공유
    Mat sub_img = img(roi).clone();//별도메모리

    혹시 이 부분에서 img(roi) img 메소드가 자바에서 무슨 메소드로 되있는지 알 수 있을까요??

  • 입원중 2016.07.07 18:25 신고 ADDR 수정/삭제 답글

    cheatsheet pdf 링크가 깨진것 같습니다. 필요하신 분은 아래 주소에서 받으시면 될것같습니다.
    http://docs.opencv.org/3.0-last-rst/opencv_cheatsheet.pdf

    • BlogIcon 다크pgmr 2016.07.07 19:22 신고 수정/삭제

      말씀하신 주소로 링크를 수정하였습니다. 감사합니다 ^^

  • 김공자 2016.07.17 16:31 신고 ADDR 수정/삭제 답글

    7번에 emplty() 오타 있는것같습니다!

    • BlogIcon 다크pgmr 2016.07.17 23:08 신고 수정/삭제

      오타 제보 감사합니다. ^^ 수정하였습니다.

  • 하하하 2017.03.14 23:16 신고 ADDR 수정/삭제 답글

    namedwindow(" ") 이게 확실히 무슨뜻인가요 ..?? ㅜㅜ

    • BlogIcon 다크pgmr 2017.03.15 12:30 신고 수정/삭제

      opencv의 온라인 문서(http://docs.opencv.org/3.2.0/)를 보면 함수들에 대한 설명을 볼 수 있습니다. namedWindow는 입력한 이름(name)으로 창(window)을 하나 생성해서 띄워주는 일을 합니다.

  • opencv 2017.03.21 17:22 신고 ADDR 수정/삭제 답글

    혹시 imread로 파일을 읽었을 경우 이미지가 회전된 상태로 mat에 저장되는 현상을 겪어 보셨는지요? 윈도우 화면에서는 제대로 나오는데 mat에 이미지를 불러오기만 하면 자동으로 회전이 된 이미지로 불러와집니다.

    • BlogIcon 다크pgmr 2017.03.21 17:55 신고 수정/삭제

      저는 그런 현상을 겪어보지 않았지만 opencv의 imread에 대한 함수설명을 보니 IMREAD_IGNORE_ORIENTATION라고 회전에 관련된 파라미터가 있는 것 같습니다. opencv의 online api를 참고해 보시기 바랍니다 (http://docs.opencv.org/3.2.0/)

  • help 2017.07.06 16:52 신고 ADDR 수정/삭제 답글

    영상을 저장후 재생을 하면 영상속도가 몇배로 빨리 재생이됩니다.
    혹시 이런경우는 어떤식으로 해야되는지 아시나요..??
    아 길이를 아주 길게 저장해도 재생을 하면 동영상이 1초로 압축되서 재생이됩니다ㅠㅠ

    • BlogIcon 다크pgmr 2017.07.06 18:48 신고 수정/삭제

      실제 녹화속도가 비디오객체 생성시 설정한 fps보다 느리면 그러한 현상이 나타납니다. 비디오객체를 생성할 때 fps를 낮춰보시면 어떨지요. 1초로 압축되는건 저도 잘 모르겠네요.. 그럴 수 있나요?

  • 키넥트 2017.11.10 22:40 신고 ADDR 수정/삭제 답글

    혹시 키넥트관련해서 소스를 병합할 수 있나요?

    • BlogIcon 다크pgmr 2017.11.11 00:10 신고 수정/삭제

      네?? 소스를 병한합다는 것이 무슨 의미인가요?