趣味は車輪の再発明♪

[opencv] 動画ファイルの全フレーム平均画像を生成


詳解 OpenCV ―コンピュータビジョンライブラリを使った画像処理・認識
Gary Bradski Adrian Kaehler
オライリージャパン
売り上げランキング: 25,746


■ たかみんつ / ソフト開発メモINDEX / OpenCVリファレンス(じぶん用) / 関数・クラスの使い方・サンプルなど /


動画ファイルの全てのフレームを走査し、平均画像を生成する関数です。

createVideoAverageImage

  • 各フレームの画素の走査に、ImageDataPtrクラスを使用しています。
  • 出力画像の形式は、キャプチャの最初のフレームと同じ形式(サイズ、ビット深度、チャネル数が同じ)になります。
  • 途中でフレーム形式が切り替わるような動画は正しく処理できません。異常終了する可能性があります。
  • 戻り値のイメージを使い終えたら、cvReleaseImageで破棄してください。
  • 内部的には、画素単位でのオーバーフローを防ぐため、IPL_DEPTH_32F(画素の値が32ビットの浮動小数点)のイメージを使用しています。
IplImage* createVideoAverageImage(CvCapture* capture) {
    CvSize frameSize;
    int depth = 0;
    int channels = 0;

    frameSize.width = (int)cvGetCaptureProperty(
        capture, CV_CAP_PROP_FRAME_WIDTH);
    frameSize.height = (int)cvGetCaptureProperty(
        capture, CV_CAP_PROP_FRAME_HEIGHT);
    int frame_count = (int)cvGetCaptureProperty(
        capture, CV_CAP_PROP_FRAME_COUNT);
    
    ImageDataPtr sumPtr;
    ImageDataPtr imgPtr;
    IplImage* sum = 0;

    //最初のフレーム
    IplImage* captured_frame = cvQueryFrame(capture);
    if(captured_frame != 0) {
        depth = captured_frame->depth;
        channels = captured_frame->nChannels;
        sum = cvCreateImage(
            frameSize, IPL_DEPTH_32F, channels);
        sumPtr = sum;
    }

    //ピクセルごとの全フレームの総和
    while(captured_frame != 0) {
        imgPtr = captured_frame;
        for(int y = 0; y < frameSize.height; y++) {
            sumPtr.setLine(y);
            imgPtr.setLine(y);
            for(int x = 0; x < frameSize.width; x++) {
                for(int c = 0; c < channels; c++) {
                    sumPtr = sumPtr + imgPtr;
                    sumPtr++;
                    imgPtr++;
                }
            }
        }
        captured_frame = cvQueryFrame(capture);
    }

    //出力画像
    IplImage* avg = cvCreateImage(frameSize, depth, channels);
    sumPtr = sum;
    imgPtr = avg;
    for(int y = 0; y < frameSize.height; y++) {
        sumPtr.setLine(y);
        imgPtr.setLine(y);
        for(int x = 0; x < frameSize.width; x++) {
            for(int c = 0; c < channels; c++) {
                imgPtr = sumPtr / frame_count;
                sumPtr++;
                imgPtr++;
            }
        }
    }
    cvReleaseImage(&sum);
    return avg;
}

main関数

int main(int argc, char* argv[])
{
    if(argc < 2) {
        exit(-1);
    }
    cvInitSystem(argc, argv);
    CvCapture* capture = cvCreateFileCapture(argv[1]);
    
    IplImage* image_average = createVideoAverageImage(capture);
    
    cvNamedWindow("Average Image", CV_WINDOW_AUTOSIZE);
    cvShowImage("Average Image", image_average);
    cvWaitKey(0);

    cvDestroyAllWindows();
    cvReleaseImage(&image_average);
    cvReleaseCapture(&capture);

    return 0;
}

関連文書

  • ImageDataPtr - IplImageのimageDataをカプセル化したクラス

Pythonプロフェッショナルプログラミング 第2版
秀和システム (2015-05-21)
売り上げランキング: 1,813


クラウドではじめる機械学習 Azure MLでらくらく体験
脇森浩志 杉山雅和 羽生貴史
リックテレコム
売り上げランキング: 2,081

実践Node.js プログラミング (Programmer's SELECTION)
Mike Cantelon Marc Harter T.J. Holowaychuk Nathan Rajlich
翔泳社
売り上げランキング: 40,213

■ たかみんつ / ソフト開発メモINDEX / OpenCVリファレンス(じぶん用) / 関数・クラスの使い方・サンプルなど /



RSS Feed Widget
[opencv] 動画ファイルの全フレーム平均画像を生成
(http://bicycle.life.coocan.jp/takamints/index.php/doc/opencv/doc/createVideoAverageImage)
by Koji Takami ( email: vzg03566@gmail.com, GitHub: takamin )