• chaoren05
    了解作者
  • C/C++
    开发工具
  • 27KB
    文件大小
  • zip
    文件格式
  • 0
    收藏次数
  • 1 积分
    下载积分
  • 19
    下载次数
  • 2017-01-26 14:43
    上传日期
VideoStitch视频拼接,视频拼接代码,git上下载
master.zip
  • VideoStitch-master
  • composer_gpu.h
    314B
  • blender.h
    1KB
  • stdafx.h
    218B
  • apap.h
    2.1KB
  • targetver.h
    228B
  • video_stitch.cpp
    5.1KB
  • exposure_compensator.h
    1.2KB
  • video_stitcher.cpp
    39.3KB
  • stdafx.cpp
    214B
  • apap.cpp
    11.6KB
  • video_stitcher.h
    5.4KB
  • gutil.h
    411B
  • composer.cu
    7.2KB
  • blender.cpp
    2.5KB
  • exposure_compensator.cpp
    4KB
内容介绍
#include "stdafx.h" #include <iostream> #include <fstream> #include <string> #include <time.h> #include <Windows.h> #include "composer_gpu.h" #include "video_stitcher.h" #include "apap.h" #include "gutil.h" MyVideoStitcher::MyVideoStitcher() { is_preview_ = true; is_save_video_ = false; start_frame_index_ = 0; end_frame_index_ = -1; is_try_gpu_ = false; is_debug_ = false; trim_type_ = MyVideoStitcher::TRIM_NO; work_megapix_ = 1.0;//-1;// seam_megapix_ = 0.2;//-1;// is_prepared_ = false; conf_thresh_ = 1.f; features_type_ = "orb";//"surf";// ba_cost_func_ = "ray"; ba_refine_mask_ = "xxxxx"; is_do_wave_correct_ = true; wave_correct_ = detail::WAVE_CORRECT_HORIZ; is_save_graph_ = false; warp_type_ = "cylindrical";//"plane";//"apap";//"paniniA2B1";//"transverseMercator";//"spherical";// expos_comp_type_ = ExposureCompensator::GAIN_BLOCKS;//ExposureCompensator::GAIN;// match_conf_ = 0.3f; seam_find_type_ = "gc_color";//"voronoi";// blend_type_ = Blender::FEATHER;//Blender::MULTI_BAND;//Blender::NO;// blend_strength_ = 5; // 获取当前系统的核数 SYSTEM_INFO sys_info; GetSystemInfo(&sys_info); parallel_num_ = sys_info.dwNumberOfProcessors; } int MyVideoStitcher::stitch( vector<VideoCapture> &captures, string &writer_file_name ) { int video_num = captures.size(); vector<Mat> src(video_num); Mat frame, dst, show_dst; // Debug用信息 bool is_save_input_frames = false; bool is_save_output_frames = true; double fps = captures[0].get(CV_CAP_PROP_FPS); // skip some frames for(int j = 0; j < video_num; j++) for(int i = 0; i < start_frame_index_; i++) captures[j].read(frame); // 第一帧,做一些初始化,并且确定结果视频的分辨率 for(int j = 0; j < video_num; j++) { if( !captures[j].read(frame)) return -1; frame.copyTo(src[j]); if(is_debug_) { char img_save_name[100]; sprintf(img_save_name, "/%d.jpg", j+1); imwrite(debug_dir_path_ + img_save_name, src[j]); } } long prepare_start_clock = clock(); int prepare_status = Prepare(src); // 先用ORB特征测试,错误的话再使用SURF,仍然错误则报错,输入视频不符合条件 if( prepare_status == STITCH_CONFIG_ERROR ) { cout << "video stitch config error!" << endl; return -1; } if( prepare_status != STITCH_SUCCESS) { features_type_ = "surf"; cout << "video stitch first try failed, second try ... " << endl; if( Prepare(src) != STITCH_SUCCESS) { cout << "videos input are invalid. Initialization failed." << endl; return -1; } } long prepare_end_clock = clock(); cout << "\tprepare time: " << prepare_end_clock - prepare_start_clock << "ms" << endl; StitchFrame(src, dst); if(is_debug_) //保存第一帧拼接结果和mask { imwrite(debug_dir_path_ + "/res.jpg", dst); vector<Mat> img_masks(video_num); for(int i = 0; i < video_num; i++) { img_masks[i].create(src[i].rows, src[i].cols, CV_8UC3); img_masks[i].setTo(Scalar::all(255)); } Mat dst_mask; StitchFrame(img_masks, dst_mask); imwrite(debug_dir_path_ + "/mask.jpg", dst_mask); } // 创建结果视频 VideoWriter writer; if(is_save_video_) { writer.open(writer_file_name, CV_FOURCC('D', 'I','V', '3'), 20, Size(dst.cols, dst.rows)); writer.write(dst); } // 开始拼接 double stitch_time = 0; FrameInfo frame_info; frame_info.src.resize(video_num); int frameidx = 1; cout << "Stitching..." << endl; string window_name = "视频拼接"; if(is_preview_) namedWindow(window_name); double show_scale = 1.0, scale_interval = 0.03; int frame_show_interval = cvFloor(1000 / fps); int failed_frame_count = 0; char log_string[1000]; char log_file_name[200]; SYSTEMTIME sys_time = {0}; GetLocalTime(&sys_time); sprintf(log_file_name, "%d%02d%02d-%02d%02d%02d.log", sys_time.wYear, sys_time.wMonth, sys_time.wDay, sys_time.wHour, sys_time.wMinute, sys_time.wSecond); ofstream log_file; if(is_debug_) log_file.open(debug_dir_path_ + log_file_name); long long startTime = clock(); while(true) { long frame_time = 0; // 采集 long cap_start_clock = clock(); int j; for(j = 0; j < video_num; j++) { if( !captures[j].read(frame)) break; frame.copyTo(frame_info.src[j]); } frame_info.frame_idx = frameidx; frameidx++; if(j != video_num || (end_frame_index_ >= 0 && frameidx >= end_frame_index_)) //有一个视频源结束,则停止拼接 break; // 拼接 long stitch_start_clock = clock(); frame_info.stitch_status = StitchFrame(frame_info.src, frame_info.dst); long stitch_clock = clock(); sprintf(log_string, "\tframe %d: stitch(%dms), capture(%dms)", frame_info.frame_idx, stitch_clock - stitch_start_clock, stitch_start_clock - cap_start_clock); printf("%s", log_string); if(is_debug_) log_file << log_string << endl; stitch_time += stitch_clock - stitch_start_clock; frame_time += stitch_clock - cap_start_clock; // 拼接失败 if(frame_info.stitch_status != 0) { cout << "failed\n"; if(is_debug_) log_file << "failed" << endl; failed_frame_count++; break; } // 保存视频 if(is_save_video_) { cout << ", write("; if(is_save_output_frames) { char img_save_name[100]; sprintf(img_save_name, "/images/%d.jpg", frame_info.frame_idx); imwrite(debug_dir_path_ + img_save_name, frame_info.dst); } long write_start_clock = clock(); writer.write(frame_info.dst); long write_clock = clock(); cout << write_clock - write_start_clock << "ms)"; frame_time += write_clock - write_start_clock; } cout << endl; // 显示--- if(is_preview_) { int key = waitKey(std::max(1, (int)(frame_show_interval - frame_time))); if(key == 27) // ESC break; else if(key == 61 || key == 43) // + show_scale += scale_interval; else if(key == 45) // - if(show_scale >= scale_interval) show_scale -= scale_interval; resize(frame_info.dst, show_dst, Size(show_scale * dst.cols, show_scale * dst.rows)); imshow(window_name, show_dst); } } long long endTime = clock(); cout << "test " << endTime - startTime << endl; cout << "\nStitch over" << endl; cout << failed_frame_count << " frames failed." << endl; cout << "\tfull view angle is " << cvRound(view_angle_) << "°" << endl; if(is_debug_) log_file << "\tfull view angle is " << cvRound(view_angle_) << "°" << endl; writer.release(); cout << "\ton average: stitch time = " << stitch_time / (frameidx-1) << "ms" << endl; cout << "\tcenter: (" << -dst_roi_.x << ", " << -dst_roi_.y << ")" << endl; if(is_debug_) { log_file << "\ton average: stitch time = " << stitch_time / (frameidx-1) << "ms" << endl; log_file << "\tcenter: (" << -dst_roi_.x << ", " << -dst_roi_.y << ")" << endl; log_file.close(); } return 0; } void MyVideoStitcher::InitMembers(int num_images) { } /* * 初始图像可能分辨率很高,先做一步降采样,可以提高时间效率 */ void MyVideoStitcher::SetScales(vector<Mat> &src) { if(work_megapix_ < 0) work_scale_ = 1.0; else work_scale_ = min(1.0, sqrt(work_megapix_ * 1e6 / src[0].size().area())); if(seam_megapix_ < 0) seam_scale_ = 1.0; else seam_scale_ = min(1.0, sqrt(seam_megapix_ * 1e6 / src[0].size().area())); } /* * 特征提取,支持SURF和ORB */ int MyVideoStitcher::FindFeatures(vector<Mat> &src, vector<ImageFeatures> &features) { Ptr<FeaturesFinder> finder; if (features_type_ == "surf") { #ifdef HAVE_OPENCV_GPU if (is_try_gpu_ && gpu::getCudaEnabledDeviceCount() > 0) finder = new SurfFeaturesFinderGpu(); else #endif finder = new SurfFeaturesFinder(); } else if (features_type_ == "orb") { finder = new OrbFeaturesFinder();//Size(3,1), 1500, 1.3, 5); } else { cout << "Unknown 2D features type: '" << features_type_ << "'.\n"; return STITCH_CONFIG_ERROR; } int num_images = static_cast<int>(src.size()); Mat full_img, img; for (int i = 0; i < num_images; ++i) { full_img = src[i].clone();// if (work_megapix_ < 0) img = full_img; else resize(full_img, img, Size(), work_scale_, work_scale_); (*finder)(img, features[i]); //LOGLN("Features in image #" << i+1 <<
评论
    相关推荐