APAP代码(1)「建议收藏」

APAP代码(1)「建议收藏」staticintVideoStitch(intargc,char*argv[]){ for(inti=0;i<argc;i++) printf(“%s\n”,argv[i]); intretval=parseCmdArgs(argc,argv); /*if(retval) returnretval;*/ is_camera=false; for(inti=0;i<video_names.size();i++) .

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

static int VideoStitch(int argc, char* argv[])
{
	for(int i = 0; i < argc; i++)
		printf("%s\n", argv[i]);
	int retval = parseCmdArgs(argc, argv);
	/*if(retval)
		return retval;*/
	
	is_camera = false;
	for(int i = 0; i < video_names.size(); i++)
		cout << video_names[i] << endl;

	//	输入视频流
	vector<VideoCapture> captures;
	if(is_camera)
	{
		for(int cam_idx = 0; cam_idx < cam_num; cam_idx++)
		{
			VideoCapture cam_cap;
			if(cam_cap.open(cam_idx))
			{
				cam_cap.set(CAP_PROP_FRAME_WIDTH, cam_width);
				cam_cap.set(CAP_PROP_FRAME_HEIGHT, cam_height);
				cam_cap.set(CAP_PROP_FPS, 15);
				captures.push_back(cam_cap);
				cout << "camera " << cam_idx << " opened successfully." << endl;
			}
			else
				break;
		}
		if(captures.size() == 0)
		{
			cout << "No camera captured. Please check!" << endl;
			return -1;
		}
	}
	else
	{
		int video_num = video_names.size();
		captures.resize(video_num);
		for(int i = 0; i < video_num; i++)
		{
			captures[i].open(video_names[i]);
			if(!captures[i].isOpened())
			{
				cout << "Fail to open " << video_names[i] << endl;
				for(int j = 0; j < i; j++) captures[j].release();
				return -1;
			}
		}
	}
	cout << "Video capture success" << endl;

	MyVideoStitcher video_stitcher;

	//	显示/保存
	video_stitcher.setPreview(is_view);
	video_stitcher.setSave(is_save);
	video_stitcher.setRange(range_start, range_end);

	//	拼接参数
	video_stitcher.setTryGPU(is_try_gpu);
	video_stitcher.setTrim(is_trim);
	if(cam_param_path != "")
		video_stitcher.loadCameraParam(cam_param_path);
	if(is_debug)
		video_stitcher.setDebugDirPath(debug_path);
	if(is_trim_rect)
		video_stitcher.setTrim(trim_rect);
	video_stitcher.setWarpType(warp_type);

	//	拼接
	video_stitcher.stitch(captures, save_path);

	//	释放资源
	for(int i = 0; i < captures.size(); i++)
		captures[i].release();

	cout << "Released all" << endl;
	
	return 0;
}


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(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, CAP_OPENCV_MJPEG, 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;
}

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/190798.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • GiD 自定义 简介

    GiD 自定义 简介目录BlogLinks一、前言二、GiD的程序架构六、参考文献BlogLinksDalNur|博客总目录GiD实用教程GiD前处理实例GiD自定义简介GiD后处理实例一、前言  随着计算机技术的发展,有限元法已成为非常强大的数值模拟工具,广泛应用于各个领域。目前,比较常用的大型商用有限元程序有ANSYS,ABAQUS,MARC,ADINA等,由于它们是通用有限元程序,在某些领域的特殊方面(如对于应力场、渗流场、温度场的耦合问

    2022年10月23日
  • fsync、synchronous_commit 的简单测试

    fsync、synchronous_commit 的简单测试fsync(boolean)如果打开这个参数,PostgreSQL服务器将尝试确保更新被物理地写入到磁盘,做法是发出fsync()系统调用或者使用多种等价的方法(见wal_sync_method)。这保证了数据库集簇在一次操作系统或者硬件崩溃后能恢复到一个一致的状态。虽然关闭fsync常常可以得到性能上的收益,但当发生断电或系统崩溃时可能造成不可恢复的数据损坏。因此,只有在能很容易地从外部数据中重

  • navicat for mysql激活码【中文破解版】2022.02.19

    (navicat for mysql激活码)这是一篇idea技术相关文章,由全栈君为大家提供,主要知识点是关于2021JetBrains全家桶永久激活码的内容https://javaforall.cn/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~LGWSVFD4PZ-eyJsaWNlb…

  • [029] 微信公众帐号开发教程第5篇-各种消息的接收与响应[通俗易懂]

    [029] 微信公众帐号开发教程第5篇-各种消息的接收与响应[通俗易懂]前一篇文章里我们已经把微信公众平台接口中消息及相关操作都进行了封装,本章节将主要介绍如何接收微信服务器发送的消息并做出响应。明确在哪接收消息从微信公众平台接口消息指南中可以了解到,当用户向公众帐号发消息时,微信服务器会将消息通过POST方式提交给我们在接口配置信息中填写的URL,而我们就需要在URL所指向的请求处理类CoreServlet的doPost方法中接收消息、处理消息和响应

  • 史上最全面的Neo4j使用指南「建议收藏」

    史上最全面的Neo4j使用指南「建议收藏」Neo4j图形数据库教程Neo4j图形数据库教程第一章:介绍Neo4j是什么Neo4j的特点Neo4j的优点第二章:安装1.环境2.下载3.开启远程访问4.测试第三章:CQL1.CQL简介2.Neo4jCQL命令/条款3.Neo4jCQL函数4.Neo4jCQL数据类型第四章:…

  • Java开源博客源码完整汇总(持续更新)

    Java开源博客源码完整汇总(持续更新)程序员需要拥有一个属于自己的独立博客网站。所以我从网站收集了一些好的Java开源博客系统。既然是属于开源,当然支持我们广大程序员二次开发了。其实搭建属于自己的技术博客网站很简单,只需要一个域名,一台服务器,然后进行网站备案(个人备案很简单)就可以拥有属于自己的博客网站了。程序员一定要及早的打造个人独立IP,拥有自己的独立博客,学会扩大自己的影响力。在公司,你能力最多影响公司的同事。但是在互联网,拥有自己的网站,你就可以影响千千万万的程序员和即将入行的新手程序员1.OneBlog一个简洁美观、功能.

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号