2016-06-20 4 views
0

私は、C++アプリケーションで、OpenCVでキャプチャ/作成されたフレームから、avconvライブラリを使用してグレースケールビデオを作成するための、迅速で信頼できる方法を探してきました。avconvでグレースケールビデオを作成するには?

私は、OpenCVがビデオを作成する内部的な方法を持っていることを知っていますが、エンコーディングのパフォーマンスとオプションの制限があります。

このように、このタスクを達成するためのオプションはどれですか?私のニーズに適合して、このタスクは、私が見つけたのいずれかのオプションを、達成するため

答えて

0

は以下のクラスである:Ubuntuの16.04でこれをコンパイルするための

extern "C" { 
#include <libavcodec/avcodec.h> 
#include <libavutil/mathematics.h> 
} 
class AVConvVideoMaker 
{ 
    AVCodec* codec; 
    AVCodecContext* context; 
    AVFrame* picture; 
    int imgWidth, imgHeight, imgBufferSize; 
    FILE* outputFile; 
    int outputBufferSize; 
    uint8_t* outputBuffer; 
    int pictureBufferSize; 
    uint8_t* pictureBuffer; 
    int outputSize; 

public: 
    AVConvVideoMaker(std::string outputFilePath, int imgWidth, int imgHeight) 
     : codec(NULL) 
     , context(NULL) 
     , picture(NULL) 
     , imgWidth(imgWidth) 
     , imgHeight(imgHeight) 
     , imgBufferSize(imgWidth*imgHeight) 
     , outputFile(fopen(outputFilePath.c_str(), "wb")) 
     , outputBufferSize(100000) 
     , outputBuffer(new uint8_t[outputBufferSize]) 
     , pictureBufferSize((imgBufferSize*3)/2) 
     , pictureBuffer(new uint8_t[pictureBufferSize]) 
     , outputSize(0) 
    { 
     avcodec_register_all(); 

     this->codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO); 
     if (!this->codec) 
     { 
      throw std::runtime_error("Codec not found"); 
     } 
     this->context = avcodec_alloc_context3(codec); 
     this->picture = avcodec_alloc_frame(); 

     this->context->bit_rate = 400000; 
     this->context->width = this->imgWidth; 
     this->context->height = this->imgHeight; 
     this->context->time_base = (AVRational){1, 25}; 
     this->context->gop_size = 10; 
     this->context->max_b_frames = 1; 
     this->context->pix_fmt = PIX_FMT_YUV420P; 
     if(avcodec_open2(this->context, this->codec, NULL) < 0) 
     { 
      throw std::runtime_error("Could not open codec"); 
     } 
     if(!this->outputFile) 
     { 
      throw std::runtime_error("Could not open video output file"); 
     } 
     this->picture->data[0] = this->pictureBuffer; 
     this->picture->data[1] = this->picture->data[0] + imgBufferSize; 
     this->picture->data[2] = this->picture->data[1] + imgBufferSize/4; 
     this->picture->linesize[0] = this->imgWidth; 
     this->picture->linesize[1] = this->imgWidth/2; 
     this->picture->linesize[2] = this->imgWidth/2; 
    } 

    void insertFrame(cv::Mat1b& img) 
    { 
     fflush(stdout); 

     /* Y */ 
     for(int y=0; y < this->context->height; y++) 
     { 
      for(int x=0; x < this->context->width; x++) 
      { 
       this->picture->data[0][y * picture->linesize[0] + x] = img.at<uchar>(y,x); 
      } 
     } 

     /* Cb and Cr */ 
     for(int y=0; y < this->context->height/2; y++) 
     { 
      for(int x=0; x < this->context->width/2; x++) 
      { 
       this->picture->data[1][y * this->picture->linesize[1] + x] = 128; 
       this->picture->data[2][y * this->picture->linesize[2] + x] = 128; 
      } 
     } 
     this->outputSize = avcodec_encode_video(this->context, this->outputBuffer, this->outputBufferSize, this->picture); 
     fwrite(this->outputBuffer, 1, outputSize, this->outputFile); 
    } 

    ~AVConvVideoMaker() 
    { 
     this->outputBuffer[0] = 0x00; 
     this->outputBuffer[1] = 0x00; 
     this->outputBuffer[2] = 0x01; 
     this->outputBuffer[3] = 0xb7; 
     fwrite(this->outputBuffer, 1, 4, this->outputFile); 
     fclose(this->outputFile); 

     avcodec_close(this->context); 
     av_free(this->context); 
     av_free(this->picture); 

     delete outputBuffer; 
     delete pictureBuffer; 
    } 

}; 

、あなたがリンクする必要があります。

g++ --std=c++11 main.cpp -lopencv_core -lopencv_highgui -lavutil -lavcodec 
関連する問題