태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.

'2012/12'에 해당되는 글 1건

  1. 2012.12.07 라즈베리파이에 웹캠 연결해서 비디오 덤프 (4)

라즈베리파이에 웹캠 연결해서 비디오 덤프

Daily life/Hard study 2012.12.07 23:22

# 목표: 동영상을 캡쳐한다

# 들어가기 전에
    * opencv 라이브러리 설치: sudo apt-get install libopencv-*
    * pyopencv 설치: sudo pip install pyopencv
    * Doc: http://docs.opencv.org/

    * OpenCV 튜토리얼: http://docs.opencv.org/doc/tutorials/tutorials.html
    * OpenCV Python: http://opencv.willowgarage.com/wiki/PythonInterface
    튜토리얼이 많이 부족하다. 아직 작업중인데, 당신이 쓸거면 연락달라고 쓰인걸로 봐서 한동안은 기대할 수 없을듯.


# Modules:
     * core
     * imgproc
     * video
     * calib3d
     * features2d
     * objdetect
     * highgui
     * gpu
     * and so on …


# API Concepts

    * 모든 클래스와 함수는 cv 이름공간 안에 있다.
    * OpenCV 는 메모리 해제를 스스로 한다. 레퍼런스 카운트 시스템이 있다.
    * 대부분의 경우 함수의 결과물에 대한 메모리 할당도 스스로 한다.
    * 라이브러리 전체적으로 Saturation arithmetic 사용
    * 템플릿은 좀 자제했음 - 파이썬, 자바 등 다른 언어로 바인딩을 쉽게하고 인터페이스/구현 분리를 잘 하기 위해
    * 편의성 및 중복 제거를 위해 InputArray, OutputArray 가 여기저기서 사용됨
    * OpenCV 는 예외를 사용한다 (derived from cv::Exception)
    * fully re-enterable


# How to capture video?

내가 필요한건 highgui(http://docs.opencv.org/modules/highgui/doc/highgui.html) 에 있는 것 같다.
highgui 문서 앞쪽에 보면 아래와 같은 설명이 있다.

   * Create and manipulate windows that can display images and “remember” their content (no need to handle repaint events from OS).
   * Add trackbars to the windows, handle simple mouse events as well as keyboard commands.
   * Read and write images to/from disk or memory.
   * Read video from camera or file and write video to a file.


cv::VideoCapture 클래스가 있다. 그리고 API 페이지(http://docs.opencv.org/modules/highgui/doc/reading_and_writing_images_and_video.html#videocapture)를 보니, python, C 인터페이스까지 나와 있다. C/C++ 인터페이스가 별도라는 데 주의. 일단 C++ 로 먼저 해본다.

VideoCapture 클래스로 웹캠에서 프레임을 얻어내고, 이렇게 얻어낸 프레임들을 imwrite 로 이미지파일로 각각 저장하거나 VideoWriter 을 사용해서 영상파일로 덤프하자.


# C++ 코드 컴파일

    * /usr/include/opencv, /usr/include/opencv2 이렇게 디렉토리가 두개다. opencv 는 이전 인터페이스를 하위호환성때문에 유지하는 듯. opencv2/opencv.hpp 를 가져다 쓰자.
    * 링크할 때 -lopencv_core -lopencv_highgui 이렇게 core 와 사용할(한) 모듈을 주어야 한다. -lopencv 이 아니다.


# Code

#include <cstdio>
#include <boost/format.hpp>
#include <opencv2/opencv.hpp>

int main(int, char**) {
    cv::VideoCapture cap(0);
    if (!cap.isOpened()) return -1;

    cv::Mat frame;
    for (int i=0; i<10; ++i) {
        cv::Mat image;
        while (!cap.read(image))
            usleep(1000*100);
        std::fprintf(stderr, "%d\n", i);
        cv::imwrite((boost::format("%05d.jpg") % i).str(), image);
    }
    return 0;
}

근데 망했다. 파일이 나오긴 나오지만 다 그냥 까만 화면이다. 카메라에 설정값이 뭔가 안좋은듯 하다. BRIGHTNESS, CONTRAST, SATURATION, GAIN 를 모두 적당한 값(중간값)으로 세팅해봐야겠다. 일단 지금 값을 확인하기 위한 함수를 하나 만들고 스케일에 맞춰 적당한 값을 넣자.



0~255 스케일이라고 생각했는데 0.0~1.0 스케일이다. 0.5 를 넣는다.

#include <cstdio>
#include <boost/format.hpp>
#include <opencv2/opencv.hpp>

void printProperties(cv::VideoCapture& cap) {
    fprintf(stdout, "CV_CAP_PROP_POS_MSEC    : %f\n", cap.get(CV_CAP_PROP_POS_MSEC));
    fprintf(stdout, "CV_CAP_PROP_FRAME_WIDTH : %f\n", cap.get(CV_CAP_PROP_FRAME_WIDTH));
    fprintf(stdout, "CV_CAP_PROP_FRAME_HEIGHT: %f\n", cap.get(CV_CAP_PROP_FRAME_HEIGHT));
    fprintf(stdout, "CV_CAP_PROP_FPS         : %f\n", cap.get(CV_CAP_PROP_FPS));
    fprintf(stdout, "CV_CAP_PROP_MODE        : %f\n", cap.get(CV_CAP_PROP_MODE));
    fprintf(stdout, "CV_CAP_PROP_BRIGHTNESS  : %f\n", cap.get(CV_CAP_PROP_BRIGHTNESS));
    fprintf(stdout, "CV_CAP_PROP_CONTRAST    : %f\n", cap.get(CV_CAP_PROP_CONTRAST));
    fprintf(stdout, "CV_CAP_PROP_SATURATION  : %f\n", cap.get(CV_CAP_PROP_SATURATION));
    fprintf(stdout, "CV_CAP_PROP_GAIN        : %f\n", cap.get(CV_CAP_PROP_GAIN));
    fprintf(stdout, "CV_CAP_PROP_HUE         : %f\n\n", cap.get(CV_CAP_PROP_HUE));
}

int main(int, char**) {
    cv::VideoCapture cap(0);
    if (!cap.isOpened()) return -1;

    printProperties(cap);
    cap.set(CV_CAP_PROP_BRIGHTNESS, 0.5);
    cap.set(CV_CAP_PROP_CONTRAST, 0.5);
    cap.set(CV_CAP_PROP_SATURATION, 0.5);
    cap.set(CV_CAP_PROP_GAIN, 0.5);
    cap.set(CV_CAP_PROP_FRAME_WIDTH, 160);
    cap.set(CV_CAP_PROP_FRAME_HEIGHT, 120);
    printProperties(cap);

    cv::Mat frame;
    for (int i=0; i<10; ++i) {
        cv::Mat image;
        while (!cap.read(image))
            usleep(1000*100);
        std::fprintf(stderr, "%f\n", i);
        cv::imwrite((boost::format("%05d.jpg") % i).str(), image);
    }
    return 0;
}




select timeout 이 뜨면서 계속 까만 화면만 나온다. 구글링 결과 http://www.raspberrypi.org/phpBB3/viewtopic.php?f=37&t=11745 이런 페이지를 발견했다! 그리고 원래 잘 동작하던 uvccapture 로도 까만 스샷만 나오고 있다. 파이를 리붓해보자.



현재 라즈베리파이와 웹캠을 던져둔 방에 불이 꺼져서 어두운 상태라는 것이 확인되었다 -_-; 집으로 컴백 후 장소를 옮기고 나서 작업해야겠다. ㅠㅠ


Trackbacks 0 : Comments 4