opencv處理攝像頭或視訊並儲存為MP4視訊
阿新 • • 發佈:2021-10-15
程式語言: C++(C11標準)
OpenCV: 4.1.1
Platform: Windows / Linux
大致邏輯:
- 讀取攝像頭或者讀取視訊檔案;
- 獲取視訊幀的相關資訊:影象尺寸和幀數;
- 建立儲存視訊檔案,並設定視訊編碼格式等資訊;
- 逐幀讀取並處理,然後寫入到輸出視訊檔案中;
- 關閉攝像頭或源視訊檔案,關閉輸出視訊檔案;
程式碼如下:
// // Created by Administrator on 2019\10\24 0024. // #include "TCLStereoDepthAlg.h" #include "iostream" #include "tcl_dualcam_def.h" #include <opencv2/opencv.hpp> #include <regex> // phone series #define P_VENICE 0 #define P_OAKLAND 1 #define P_AK57 2 #define P_HONGKONG 3 #define P_HONGKONG_PRO 4 #define P_VGA 5 #define P_T1PRO 6 #define P_OTTAWA 7 #define PRODUCT_ID P_OTTAWA #if PRODUCT_ID >= P_T1PRO #define CALIB_VERSION 8 #else #define CALIB_VERSION 7 #endif #if CALIB_VERSION == 7 #define DIST_PARAM_NUM 5 #else #define DIST_PARAM_NUM 8 #endif struct CalibrationFile { #if CALIB_VERSION == 8 int phone_id; #endif int full_size_w; int full_size_h; int crop_size_w; int crop_size_h; int orientation; int size_w; int size_h; float MIN_DISP; float MAX_DISP; float delta_disp_per_degree; double M1[3][3]; double D1[1][DIST_PARAM_NUM]; double M2[3][3]; double D2[1][DIST_PARAM_NUM]; double R[3][3]; double T[3][1]; }; int main(int argc, const char ** argv){ TCL_DEPTH_VIDEO_VERSION_CHECK(2.0, 2021, 06, 17, 10, 19); cv::String base_dir = "F:/dump/TEST-ALL/Dataset/EIS/"; cv::String date_id = "20211013"; cv::String phone_id = "Prague-WH03-0101"; cv::String video_id = "easy.mp4"; cv::String ori_dir = "ori/"; cv::String cal_dir = "cal/"; cv::String out_dir = "out/"; cv::String dump_dir = "dump/"; #if CALIB_VERSION == 7 cv::String cal_ver = "version7"; #else cv::String cal_ver = "version8"; #endif double beg_, end_; double freq = cv::getTickFrequency(); tcl_depth_video::TCLStereoDepthAlg_prv *m_DepthAlgorithmPtr = new tcl_depth_video::TCLStereoDepthAlg_prv; tcl_depth_video::Param_DepthPreview param_depth; // calibration settings int orientation; cv::Size cali_size; cv::Size full_size; cv::Size crop_size; cv::Mat M1, D1, M2, D2; String cali_bin = base_dir + "/" + cal_dir + "/" + phone_id + "/" + cal_ver + "/dualcam_cali.bin"; std::fstream ifs(cali_bin, std::ios::in | std::ios::binary); CalibrationFile califile_in; if (!ifs.is_open()) { VIDEO_DEPTH_LOGE("dualcam_cali.bin not found!"); return -1; } ifs.read((char*)&califile_in, sizeof(califile_in)); orientation = califile_in.orientation; cali_size.width = califile_in.size_w; cali_size.height = califile_in.size_h; full_size.width = califile_in.full_size_w; full_size.height = califile_in.full_size_h; crop_size.width = califile_in.crop_size_w; crop_size.height = califile_in.crop_size_h; M1 = cv::Mat(Size(3, 3), CV_64FC1, califile_in.M1); D1 = cv::Mat(Size(1, DIST_PARAM_NUM), CV_64FC1, califile_in.D1); M2 = cv::Mat(Size(3, 3), CV_64FC1, califile_in.M2); D2 = cv::Mat(Size(1, DIST_PARAM_NUM), CV_64FC1, califile_in.D2); ///////////////// Calibration Data Settings ////////////////// param_depth.orientation = orientation; param_depth.cali_size = cali_size; param_depth.full_size = full_size; param_depth.crop_size = crop_size; param_depth.intrinsics.M1 = M1; param_depth.intrinsics.D1 = D1; param_depth.intrinsics.M2 = M2; param_depth.intrinsics.D2 = D2; // algorithm settings param_depth.depth_size = cv::Size(384, 288); param_depth.dump_enabled = true; param_depth.dump_path = base_dir + dump_dir + date_id + "/" + phone_id; m_DepthAlgorithmPtr->Init(param_depth); cv::String input_video = base_dir + ori_dir + date_id + "/" + phone_id + "/" + video_id; cv::VideoCapture input_stream(input_video); ASSERT(input_stream.isOpened(), "video not found: %s", input_video.c_str()); float frame_width = input_stream.get(cv::CAP_PROP_FRAME_WIDTH); float frame_height = input_stream.get(cv::CAP_PROP_FRAME_HEIGHT); int frame_count = input_stream.get(cv::CAP_PROP_FRAME_COUNT); //create a video writer for saving processed frames cv::String output_dir = base_dir + out_dir + date_id + "/" + phone_id + "/"; tcl_depth_video::MakeDir(output_dir); cv::String output_video = output_dir + video_id; cv::VideoWriter output_stream; int fps = 30; int fourcc = cv::VideoWriter::fourcc('m', 'p', '4', 'v'); cv::Size frame_size(frame_width, frame_height); output_stream.open(output_video, fourcc, fps, frame_size, true); ASSERT(output_stream.isOpened(), "video cannot be created: %s", output_video.c_str()); // create a global uid for synchronize log/dump information char uid[16]; // output frame cv::Mat input_frame(cv::Size(frame_width, frame_height), CV_8UC3); cv::Mat output_frame(cv::Size(frame_width, frame_height), CV_8UC3); for (int i=0; i<frame_count; ++i) { memset(uid, 0, sizeof(uid)); sprintf_s(uid, "%08d", i); VIDEO_DEPTH_LOGI("filename: %s", uid); ASSERT(input_stream.read(input_frame), "video broken or incomplete!"); ASSERT(input_frame.size().width == frame_width, "width mismatch"); ASSERT(input_frame.size().height == frame_height, "width mismatch"); ASSERT(input_frame.channels() == 3, "unexpected channel number of frame"); beg_ = cv::getTickCount(); //float err_code = m_DepthAlgorithmPtr->Compute(output_frame, input_frame, cv::String(uid)); // here's your code // a demo one is to convert color into HSV cv::cvtColor(input_frame, output_frame, cv::COLOR_BGR2HSV); end_ = cv::getTickCount(); VIDEO_DEPTH_LOGI("frame %d cost: %.4f ms.", i, (1000 * (end_ - beg_) / freq)); // save this frame to the output video stream output_stream.write(output_frame); } input_stream.release(); output_stream.release(); delete(m_DepthAlgorithmPtr); PAUSE(); return 0; }
完畢。