天天看點

圖檔序列與視訊之間的轉換

    • 視訊轉成圖檔序列
    • 圖檔序列轉成視訊
    • 調用測試
    • 視訊的讀取
    • 圖檔序列的讀取

視訊轉成圖檔序列

//将視訊轉化問AVI格式,參考了網上的部分資料,希望對大家有幫助

    int  VideoToImage(char* videoName, char* outDir, char* imgExt, int maxFrameCount)
    {
        VideoCapture cap(videoName);
        if (!cap.isOpened())
        {
            cout << "Failed open video file!" << endl;
            return ;
        }
        if (cap.get(CAP_PROP_FRAME_COUNT) < )
        {
            cout << "The video must have at least two frames." << endl;
            return ;
        }
        //儲存圖檔的檔案夾路徑一定要有,因為OpenCV不會自動建立檔案夾
        if (_access(outDir, ) == -)
        {
            recursive_mkdir(outDir);
            std::cout << "the ouput directory does not exist, and the have been created autonomously!" << std::endl;
        }
        char cur_fn[];//儲存目前幀所得圖檔的檔案名
        cv::Mat pImg;
        int frame = ;
        double rate = cap.get(CAP_PROP_FPS);
        double delay =  / rate;
        cap.read(pImg);
        bool stop = true;
        //while (!pImg.empty() && (frame<maxFrameCount))
        while (cap.isOpened() && stop)
        {
            if (frame < maxFrameCount)
            {
                frame++;
                strcpy_s(cur_fn, "");
                sprintf_s(cur_fn, "%s%d%s", outDir, frame, imgExt);//這裡的設定适合形如 123.jpg 124.jpg的圖檔序列
                imwrite(cur_fn, pImg);
                cap.read(pImg);
            }
            else
                stop = false;

        }
        pImg.release();
        cap.release();
        return frame;
    }
           
int recursive_mkdir(char *dir)
    {
        //分解路徑名E:\\AA\\BB\\CC\\
         //
        string str = dir;
        int index = ;
        int i = ;
        while ()
        {
            string::size_type pos = str.find("\\", index);
            string str1;
            str1 = str.substr(, pos);
            if (pos != - && i > )
            {
                if (_access(str1.c_str(), ) == -)
                {
                    _mkdir(str1.c_str());
                }
            }
            if (pos == -)
            {
                break;
            }
            i++;
            index = pos + ;
        }
        return ;
    }
           

圖檔序列轉成視訊

int ImageToVideo(char* outDir, char* videoName, char* inputDir, int startFrame, int endFrame, int imgW, int imgH, char* imgExt, double fps, int isColor, int fourcc)
    {
        //判斷輸入檔案夾是否存在
        if (_access(inputDir, ) == -)
        {
            std::cout << "the input directory does not exist!" << std::endl;
            return ;
        }
        //判斷輸出檔案夾是否建立 若沒有則建立;若為NULL則預設目前工作目錄
        char fullVideoName[];//輸出視訊的完整檔案名:路徑+檔案名
        strcpy_s(fullVideoName, "");
        if (outDir == NULL)
        {
            sprintf_s(fullVideoName, "%s", videoName);//把videoName列印成一個字元串儲存在fullVideoName 中 
        }
        else
        {
            if (_access(outDir, ) == -)
            {
                _mkdir(outDir);
            }
            sprintf_s(fullVideoName, "%s%s", outDir, videoName);//将字元串outDir和videoName連接配接起來,列印,儲存在fullVideoName中
        }
        int frameCount = ;
        //CvVideoWriter *pWriter = NULL;
        Size size = Size(imgW, imgH);
        VideoWriter pWriter(videoName, fourcc, fps, size, isColor);//CREATE WRITER

        cv::Mat pImg;
        char cur_fn[];//表示某張圖檔的路徑
        while (startFrame <= endFrame)
        {
            strcpy(cur_fn, "");
            char name[] = ".jpg";
            sprintf(cur_fn, "%s%s%07d%s", inputDir, imgExt, startFrame, name);//注:這裡需要根據你的檔案名來做相應的更改
            //cout <<"輸入檔案夾名為:"<< cur_fn << endl;
            pImg = imread(cur_fn, isColor);
            if (pImg.empty())
            {
                cout << "can't open an image file" << endl;
                return frameCount;
            }
            pWriter << pImg;
            waitKey();
            cout << "Write frame " << startFrame << std::endl;
            startFrame++;
            pImg.release();
            frameCount++;
        }
        //cvReleaseVideoWriter(&pWriter);
        pWriter.release();
        rename(videoName, fullVideoName);//移動檔案到指定檔案夾
        return  frameCount;
    }
           

調用測試

char* inputDir = "D:/zhlWorkDocs/運動跟蹤/vot2015/pedestrian2/";
    char* videoName = "pedestrian.avi";
    char* outDir = "D:/zhlWorkDocs/video/";
    double t = getTickCount();
    int frames = ImageToVideo(outDir, videoName, inputDir, , , , , "0", , , CAP_PROP_FOURCC);
    cout << "ImageToVideo resumes: " << (getTickCount() - t) / getTickFrequency() <<"ms"<< endl;
    std::cout << "total frames " << frames << " have been write to video." << std::endl;
    char out_file[] = "";
    sprintf(out_file,"%s%s",outDir,videoName);
    capVideo.open(out_file);
    if (!capVideo.isOpened()) {                                                 // if unable to open video file
        cout << "error reading video file!" << endl << endl;      // show error message
        _getch();                    // it may be necessary to change or remove this line if not using Windows
        return ;                                                              // and exit program
    }

    if (capVideo.get(CAP_PROP_FRAME_COUNT) < ) {
        cout << "error: video file must have at least two frames!";
        _getch();
        return ;
    }
           

視訊的讀取

VideoCapture capVideo;
cv::Mat imgFrame1;
capVideo.open("D:/zhlWorkDocs/video/768x576.avi");

    if (!capVideo.isOpened()) {                                                 // if unable to open video file
        cout << "error reading video file!" << endl << endl;      // show error message
        _getch();                    // it may be necessary to change or remove this line if not using Windows
        return ;                                                              // and exit program
    }

    if (capVideo.get(CAP_PROP_FRAME_COUNT) < ) {
        cout << "error: video file must have at least two frames!";
        _getch();
        return ;
    }
capVideo.read(imgFrame1);
           

圖檔序列的讀取

Mat image;
    VideoCapture sequence;
    for(int i = ;i < ;i ++)  
    {  
        char first_file[];
        sprintf(first_file, "D:\\zhlWorkDocs\\image_sequences\\4\\%d.jpg", i);
        sequence.open(first_file);

        if (!sequence.isOpened())
        {
            cerr << "Failed to open the image sequence!\n" << endl;
            return ;
        }


        //namedWindow("Image sequence", );
        sequence.read(image);  

        if(image.empty())  
        {  
            cout << "End of Sequence" << endl;  
            break;  
        }  

        imshow("Image sequence", image);  
        waitKey();
    }