Opencv將處理後的視頻保存出現的問題

問題描述:
代碼運行過程中,imshow出來的每幀的效果圖是正確的,但是按照網上的方法保存下來卻是0kb,打開不了。
參考的網上的一些方法,均是失敗的,具體原因我也不清楚:
1、例如我這樣設置,會報這樣的錯:
錯誤
2、後來經過查找,這種表示方法更換成:

int outCompressCodec = CAP_OPENCV_MJPEG;// 設置要保存視頻的格式。

這回不報錯了,但是產生的視頻文件仍然是爲0kb;
3、
設置爲和輸入視頻一樣的格式:

int outCompressCodec = capture.get(CAP_PROP_FOURCC);

不報錯,但是產生的視頻文件仍然是爲0kb;
4、還有不知道是那種操作,導致這樣的提示:
程序運行的過程中面板上彈出的錯誤是:這個應該是涉及到編碼與解碼的庫,但老實說不需要下載相關庫,自帶的也可以實現我所需要的功能的。

[ INFO:0] VIDEOIO: Enabled backends(5, sorted by priority): FFMPEG(1000); MSMF(990); DSHOW(980); CV_IMAGES(970); CV_MJPEG(960)

Failed to load OpenH264 library: openh264-1.8.0-win64.dll
        Please check environment and/or download library: https://github.com/cisco/openh264/releases

[libopenh264 @ 00000232d8d77f00] Incorrect library version loaded
Could not open codec 'libopenh264': Unspecified error

5、最後發現原來按照CAP_OPENCV_MJPEG設置的話,輸出的視頻必須爲MP4格式,我還傻逼呼呼地用avi格式,最終結果很好!!

這是我寫的代碼:(將avi輸出爲MP4)

#include <opencv2/opencv.hpp>
#include "opencv2/features2d.hpp"
#include<opencv2/highgui.hpp>
#include <iostream>
#include "windows.h"
#include <stdio.h>
#include <time.h>
#include <math.h>  
#include "My_ImageProssing_base.h"
#define WINDOW_NAME "【程序窗口】"			
using namespace cv;
using namespace std;
//RNG g_rng(12345);


//失敗

//對視頻進行動漫化一般需要四個步驟
//1、邊緣檢測
//2、將邊緣檢測得到的邊緣 以黑色的形式貼在原來的畫上。
//3、對貼了邊緣的圖進行雙邊濾波,雙邊濾波可以較好的濾波的同時保留邊緣。
//4、修改圖像的顏色的飽和度,本文采用的是將RGB轉化爲HSV空間,然後調整S分量。

//*--------------------------【全局變量聲明】-------------------------------------*/
int g_nThresholdValue = 71;	//canny參數值
int g_nkernelValue = 21;	//雙邊濾波核大小
int g_nS = 248;	//
Mat g_srcImage, g_grayImage,g_cannyImage,g_dstImage;

void H_mul_k(Mat* srcImage, Mat* dstImage, float k)
{
	int height = (*srcImage).rows;
	int width = (*srcImage).cols;
	for (int j = 0; j < height; j++)
	{
		for (int i = 0; i < width; i++)
		{
			int zhi = (*srcImage).at<uchar>(j, i) * k;
			if (zhi >= 255) zhi = 255;
			else if (zhi <= 0) zhi = 0;
			else zhi = zhi;
			(*dstImage).at<uchar>(j, i) = zhi;
		}
	}
}
int main(int argc, char* argv[])
{
	Point pt1, pt2;
	Mat g_srcImage;
	cv::VideoCapture capture("D:\\opencv_picture_test\\毛概期中作業\\路上風景.avi");//關聯讀入視頻文件
	if (!capture.isOpened()) {
		std::cout << "fail to load video";
		return 1;
	}
	/*獲取視頻fps*/
	double rate = capture.get(CAP_PROP_FPS);
	/*獲取視頻幀的尺寸*/
	int width = capture.get(CAP_PROP_FRAME_WIDTH);
	int height = capture.get(CAP_PROP_FRAME_HEIGHT);
	// 獲取當前視頻的編碼格式,輸出的視頻要和輸入視頻編碼相同纔可以保存。
	//int outCompressCodec = capture.get(CAP_PROP_FOURCC);
	int outCompressCodec = CAP_OPENCV_MJPEG;// 設置要保存視頻的格式。
	cout << outCompressCodec << endl;
	/*根據打開視頻的參數初始化輸出視頻格式*/
	//D:\\opencv_picture_test\\毛概期中作業\\re_video.avi
	cv::VideoWriter w_cap("D:\\opencv_picture_test\\毛概期中作業\\re_video.mp4", outCompressCodec, rate, cv::Size(width, height),true);
	/*自定義輸出視頻的尺寸,需要將讀取的視頻幀尺寸進行變換,下文使用的resize函數完成*/
	//cv::VideoWriter w_cap("re_video.avi", outCompressCodec, rate, cv::Size(width,height));
	
	/*循環讀取視頻的幀*/
	while (capture.read(g_srcImage)) {
		/****************************************************************************************************************************/
		/*對讀取的視頻幀進行處理*/
		g_grayImage.create(g_srcImage.size(), g_srcImage.type());		//創建一個同大小類型的矩陣
		cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);
		//imshow("【原圖的灰度圖】", g_grayImage);
		//進行均值濾波操作
		blur(g_grayImage, g_grayImage, Size(3, 3));
		//【4】創建滑動條來控制閾值
		//【1】運行canny算子
		Canny(g_grayImage, g_cannyImage, g_nThresholdValue, g_nThresholdValue / 3, 3);
		cv::Mat g_canny3Image(g_srcImage.rows, g_srcImage.cols, CV_8UC3, cv::Scalar(0, 0, 0));
		//【2】貼圖
		//將canny圖反轉(將邊緣變爲黑色)
		Mat change_g_cannyImage;
		//change_g_cannyImage = g_cannyImage < 100;		//非邊緣轉化爲255,邊緣轉化爲0;非邊緣會在之後的處理會變爲透明,而邊緣則會保持原有的數據0
		change_g_cannyImage = 255 - g_cannyImage;
		//將單通道轉化爲三通道
		cvtColor(change_g_cannyImage, g_canny3Image, COLOR_GRAY2BGR);
		//image.copyTo(imageROI,mask), 作用是把mask和image重疊以後把mask中像素值爲0(black)的點對應的image中的點變爲透明,而保留其他點。
		Mat bianyuan_dst;
		g_srcImage.copyTo(bianyuan_dst, g_canny3Image);
		//【3】雙邊濾波
		Mat lvbo_dst;
		bilateralFilter(bianyuan_dst, lvbo_dst, g_nkernelValue, g_nkernelValue * 2, g_nkernelValue / 2);
		//【4】修改圖像的顏色的飽和度
		Mat hsv_image, hsv_dst;
		cvtColor(lvbo_dst, hsv_image, COLOR_BGR2HSV);
		vector<Mat> channels;
		split(hsv_image, channels);
		Mat S_Mat;
		float k = g_nS * 1.0f / 100;
		channels.at(1).copyTo(S_Mat);
		cv::Mat S_dst(S_Mat.rows, S_Mat.cols, CV_8UC1, cv::Scalar(0));
		//S_dst = S_Mat * k;
		H_mul_k(&S_Mat, &S_dst, k);
		//將修改後的S與原來的H,V進行merge
		channels[1] = S_dst.clone();	//深複製
		merge(channels, hsv_dst);
		//將修改後的HSV轉爲RGB圖
		Mat RGB_dst;
		cvtColor(hsv_dst, RGB_dst, COLOR_HSV2BGR);
		/****************************************************************************************************************************/

		/*保存處理後的幀爲視頻*/
		w_cap.write(RGB_dst);
		//這裏我們不展示
		//imshow("src", RGB_dst);
		if (waitKey(10)=='q')
		{
			break;
		}
	}
	capture.release();
	cout << "處理好了" << endl;
	return 0;
}

參考鏈接們:

opencv視頻讀取與幀處理後保存爲視頻的方法
利用opencv加快視頻播放速度,並保存avi視頻文件
opencv4.0.0裏面CV_FOURCC找不到標識符
opencv VideoWriter保存視頻失敗原因
opencv視頻保存
OpenCV視頻寫入詳解_Python,視頻保存0kb問題
解決c++ - openh264 - bEnableFrameSkip=0, bitrate can’t be controlled
常見的視頻格式以及視頻編解碼標準(附帶OpenCV實現視頻的讀取與保存)

十分感謝上面的鏈接!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章