读入批量图像+切割视频为规定格式的帧图像

读入批量图像

读入两帧图像直接使用imread即可,但是读入文件夹内的图像文件夹有点复杂。

一、十四讲第八章使用LK光流法

在视觉SLAM十四讲第八章使用LK光流法时,第一帧图像提取FAST特征点,之后的帧使用LK跟踪特征点,需要批量导入图像。

这里提供的方式如下:

string path_to_dataset="../TUM";
string associate_file=path_to_dataset+"/associate.txt";// string+"" 复合
ifstream fin(associate_file);  //string转流

string rgb_file, depth_file,time_rgb,time_depth;
for (int index=0;index<100;index++)
{
 fin>>rgb_file>>depth_file>>time_rgb>>time_depth;// 流的功能>>
 color=cv::imread(path_to_dataset+"/"+rgb_file);// imread参数为string类型
 depth=cv::imread(path_to_dataset+"/"+depth_file,-1);
}

1、其中,associate.txt对depth和rgb图像的采集时间进行配对,时间上对齐。

运行:python associate.py rgb.txt depth.txt > associate.txt

2、imread(flag); 彩色图像为8位3通道,深度图为16位单通道图像。

flags = 1:imread按三通道方式读入图像,即彩色图像

flags = 0:imread按单通道的方式读入图像,即灰白图像

flags = -1:imread按解码得到的方式读入图像

3、groundtruth.txt为标准轨迹,外部运动捕捉系统采集到的相机位姿。(time,tx,ty,tz,qx,qy,qz,qw)


二、VINS-mono读取图像

void PubImuData()
{
	string sImu_data_file = sConfig_path + "MH_05_imu0.txt";// string+""复合

	ifstream fsImu;// 流形式fsImu
	fsImu.open(sImu_data_file.c_str());//string转char*
	if (!fsImu.is_open())
	{
		cerr << "Failed to open imu file! " << sImu_data_file << endl;
		return;
	}

	std::string sImu_line;// 每一行imu数据string类型
	double dStampNSec = 0.0;
	Vector3d vAcc;
	Vector3d vGyr;
	while (std::getline(fsImu, sImu_line) && !sImu_line.empty()) // read imu data,getline出来的是string形式
	{
		std::istringstream ssImuData(sImu_line);// string转流形式
		ssImuData >> dStampNSec >> vGyr.x() >> vGyr.y() >> vGyr.z() >> vAcc.x() >> vAcc.y() >> vAcc.z();
		// cout << "Imu t: " << fixed << dStampNSec << " gyr: " << vGyr.transpose() << " acc: " << vAcc.transpose() << endl;
		pSystem->PubImuData(dStampNSec / 1e9, vGyr, vAcc);
		usleep(5000*nDelayTimes);
	}
	fsImu.close();
}


void PubImageData()
{
	string sImage_file = sConfig_path + "MH_05_cam0.txt";// string+""复合

	cout << "1 PubImageData start sImage_file: " << sImage_file << endl;

	ifstream fsImage;// 流形式
	fsImage.open(sImage_file.c_str());//string转char*
	if (!fsImage.is_open())
	{
		cerr << "Failed to open image file! " << sImage_file << endl;
		return;
	}

	std::string sImage_line;
	double dStampNSec;
	string sImgFileName;

    // 循环读取每一行getline出来为string类型
	while (std::getline(fsImage, sImage_line) && !sImage_line.empty())
	{
		std::istringstream ssImuData(sImage_line);//流文件
		ssImuData >> dStampNSec >> sImgFileName;
		// cout << "Image t : " << fixed << dStampNSec << " Name: " << sImgFileName << endl;
		string imagePath = sData_path + "cam0/data/" + sImgFileName;

		Mat img = imread(imagePath.c_str(), 0);
		if (img.empty())
		{
			cerr << "image is empty! path: " << imagePath << endl;
			return;
		}
		pSystem->PubImageData(dStampNSec / 1e9, img);
		// cv::imshow("SOURCE IMAGE", img);
		// cv::waitKey(0);
		usleep(50000*nDelayTimes);
	}
	fsImage.close();
}

三、简单的视觉里程计

在实现里,需要读入KITTI的图像。

要求:图像为顺序排列1、2、3....

char filename[100];
for(int index=2;index<100;index++)
{
 sprintf(filename,"/home/avisingh/Datasets/KITTI_VO/00/image_2/%06d.png",index);
 Mat currImage_c=imread(filename);
 cvtColor(currImage_c,currImage,COLOR_BGR2GRAY);
}

1、sprintf()把格式化的数据写入某个字符串中

2、照片格式为000011.png,所以这里用sprintf(filename,"../%06d.png",index)形式,字长6位,不够的前面补零

     相同效果的是:

     stringstream ss;

     ss << "../"  << setw(6) << setfill('0') << index<< ".png";

    Mat img(imread(ss.str(),0));


切割视频

#include <iostream>  
#include <vector>  
#include "opencv2\highgui\highgui.hpp"  
#include <string>
#include <iomanip>//setw和setfill要用

using namespace std;
using namespace cv;

void video2image(string video, string path)
{
	VideoCapture capture(video);
	if (!capture.isOpened())
	{
		cerr << "Failed to open a video" << endl;
		return;
	}

	//设置开始帧、结束帧、当前帧初始化为初始帧
	long frameToStart = 40;
	int frameToStop = 200;
	long currentFrame = frameToStart;

	Mat frame;
	int num = 1;
	string filename;
	
	bool stop = false;//标志位
	while (!stop)
	{
		capture >> frame;//视频流读入帧中
		if (frame.empty())//读完,直接break
			break;

		stringstream str;//以流的形式
		str << path << setw(5) << setfill('0') << num << ".jpg";//命名从1开始计数

		cout << "now is reading" << currentFrame << "." << endl;
		imshow("Extractedframe", frame);

		cout << "now is writing" << currentFrame << "." << endl;
		imwrite(str.str(), frame);

		//按下ESC或者到达指定的结束帧后退出读取视频  
		if ( currentFrame > frameToStop)
		{
			stop = true;
		}

		num++;//命名从1开始计数
		currentFrame++;//当前帧计数
	}
	capture.release();//关闭视频文件
	waitKey(0);
}

int main(int argc, char** argv)
{
	string videoFromfile = "./2.avi";  //读取视频  
	string Imagespath = "./2/";    // 保存图片的文件夹路径一定要有,因为OpenCV不会自动创建文件夹  
	video2image(videoFromfile, Imagespath);
	return 0;

}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值