適当な処理は、VideoCaptureクラスの説明[2]を参考にして、
- グレースケールに変換
- ガウスフィルターでぼかしを入れる
- Cannyでエッジ検出
出来たもの
ソースコード
#include <iostream> #include <sys/time.h> #include "opencv2/opencv.hpp" using namespace cv; /** * return time elapsed in millisecond */ inline double getElapsedTime(const timeval &s, const timeval &t) { double ts = s.tv_sec * 1e6 + s.tv_usec; double tt = t.tv_sec * 1e6 + t.tv_usec; return (tt - ts) / 1000; } /** * PCのカメラに写った映像を編集して、ビデオファイルに出力する。 */ int main() { VideoCapture cap(0); // open the default camera if (!cap.isOpened()) { std::cout << "Could not access the default camera" << std::endl; return -1; } Size size = Size((int) cap.get(CV_CAP_PROP_FRAME_WIDTH), (int) cap.get(CV_CAP_PROP_FRAME_HEIGHT)); int codec = CV_FOURCC('X', 'V', 'I', 'D'); double fps = 30.0; // frames per second VideoWriter writer("sample.avi", codec, fps, size, true); if (!writer.isOpened()) { std::cout << "Could not open the output video." << std::endl; return -1; } Mat frame, edges; struct timeval startTime, endTime; for (;;) { gettimeofday(&startTime, NULL); cap >> frame; cvtColor(frame, edges, CV_BGR2GRAY); GaussianBlur(edges, edges, Size(9, 9), 3.0, 3.0); Canny(edges, edges, 0, 30, 3); cvtColor(edges, frame, CV_GRAY2BGR); // before write a frame to VideoWriter, conver it to BGR img. imshow("live", frame); writer << frame; gettimeofday(&endTime, NULL); int waitTime = max(1.0, 1000 / fps - getElapsedTime(startTime, endTime)); // std::cout << (int)(1000 / fps) << " - > " << waitTime << std::endl; if (waitKey(waitTime) >= 0) // consider fps and the time elapsed break; } std::cout << "finished" << std::endl; return 0; }
メモ
- 出力ビデオのコーデックはintでエンコードして渡さないといけない。ビット演算を使って自分でエンコードすることも出来るが、CV_FOURCCというマクロがあるのでそれを使うとよい。
- 1チャネルのフレームをVideoWriterに出力すると、動画ファイルが再生できなかった。グレースケールのフレームの場合は、3チャネルに変換して出力しないといけない。
- 定義したFPS(Frame Per Second)と処理に要した時間を考慮して、適切なタイミングでVideoWriterに出力しなければならない。
参考URL
[1] Creating a video with OpenCV [2] Reading and Writing Images and Video
0 件のコメント:
コメントを投稿