main函数
本程序用于从klg日志文件中提取RGB图像和Depth图像信息,klg文件在ElasticFusion中被用于保存数据集。
涉及的相关开源代码如下:
LogView
mp3guy/Logger1
mp3guy/Logger2
HTLife/png_to_klg
#include "Resolution.h"
#include "RawLogReader.h"
#include
#include
#include
#include
int find_argument(int argc, char** argv, const char* argument_name)
{
for(int i = 1; i < argc; ++i)
{
if(strcmp(argv[i], argument_name) == 0)
{
return i;
}
}
return -1;
}
int parse_argument (int argc, char** argv, const char* str, int &val)
{
int index = find_argument (argc, argv, str) + 1;
if (index > 0 && index < argc )
val = atoi (argv[index]);
return (index - 1);
}
int parse_argument (int argc, char** argv, const char* str, std::string &val)
{
int index = find_argument (argc, argv, str) + 1;
if (index > 0 && index < argc )
val = argv[index];
return index - 1;
}
int main(int argc, char * argv[])
{
int width = 640;
int height = 480;
parse_argument(argc, argv, "-w", width);
parse_argument(argc, argv, "-h", height);
Resolution::getInstance(width, height);
Bytef * decompressionBuffer = new Bytef[Resolution::getInstance().numPixels() * 2]; //存储深度图的指针
IplImage * deCompImage = 0; //存储rgb图的指针
std::string logFile;
assert(parse_argument(argc, argv, "-l", logFile) > 0 && "Please provide a log file");
RawLogReader logReader(decompressionBuffer,
deCompImage,
logFile,
find_argument(argc, argv, "-f") != -1);
cv::Mat1b tmp(height, width);
cv::Mat3b depthImg(height, width);
while(logReader.hasMore())
{
logReader.getNext();
cv::Mat3b rgbImg(height, width, (cv::Vec<unsigned char, 3> *)logReader.deCompImage->imageData);
cv::Mat1w depth(height, width, (unsigned short *)&decompressionBuffer[0]);
cv::normalize(depth, tmp, 0, 255, cv::NORM_MINMAX, 0);
cv::cvtColor(tmp, depthImg, CV_GRAY2RGB);
// cv::imshow("RGB", rgbImg);
std::cout<<setiosflags(std::ios::fixed)<<logReader.timestamp<<std::endl;
cv::imwrite("rgb"+std::to_string(logReader.timestamp)+".png",rgbImg);
cv::imwrite("depth"+std::to_string(logReader.timestamp)+".png",depth);
// cv::imshow("Depth", depthImg);
char key = cv::waitKey(1);
if(key == 'q')
break;
else if(key == ' ')
key = cv::waitKey(0);
if(key == 'q')
break;
}
delete [] decompressionBuffer;
if(deCompImage)
{
cvReleaseImage(&deCompImage);
}
return 0;
}
Resolution.h文件
/*
* Resolution.h
*
* Created on: 18 Nov 2012
* Author: thomas
*/
#ifndef RESOLUTION_H_
#define RESOLUTION_H_
#include
class Resolution
{
public:
static const Resolution & getInstance(int width = 0, int height = 0)
{
static const Resolution instance(width, height);
return instance;
}
const int & width() const
{
return imgWidth;
}
const int & height() const
{
return imgHeight;
}
const int & cols() const
{
return imgWidth;
}
const int & rows() const
{
return imgHeight;
}
const int & numPixels() const
{
return imgNumPixels;
}
private:
Resolution(int width, int height)
: imgWidth(width),
imgHeight(height),
imgNumPixels(width * height)
{
assert(width > 0 && height > 0);
}
const int imgWidth;
const int imgHeight;
const int imgNumPixels;
};
#endif /* RESOLUTION_H_ */
RawLogReader.h文件
/*
* RawLogReader.h
*
* Created on: 19 Nov 2012
* Author: thomas
*/
#ifndef RAWLOGREADER_H_
#define RAWLOGREADER_H_
#include
#include "Resolution.h"
#include
#include
#include
#include
#include
class RawLogReader
{
public:
RawLogReader(Bytef *& decompressionBuffer,
IplImage *& deCompImage,
std::string file,
bool flipColors);
virtual ~RawLogReader();
void getNext();
int getNumFrames();
bool hasMore();
Bytef *& decompressionBuffer;
IplImage *& deCompImage;
unsigned char * depthReadBuffer;
unsigned char * imageReadBuffer;
int64_t timestamp;
int32_t depthSize;
int32_t imageSize;
private:
const std::string file;
FILE * fp;
int32_t numFrames;
int currentFrame;
bool flipColors;
bool isCompressed;
};
#endif /* RAWLOGREADER_H_ */
RawLogReader.cpp文件
/*
* RawLogReader.cpp
*
* Created on: 19 Nov 2012
* Author: thomas
*/
#include "RawLogReader.h"
/**
* @brief
* @param [in] deCompImage 指向depth图的指针
* @param [in] decompressionBuffer 指向RGB图的指针
* @param [in] file 输入的klg文件地址
* @param [in] flipColors 是否翻转颜色的bool变量
* */
RawLogReader::RawLogReader(Bytef *& decompressionBuffer,
IplImage *& deCompImage,
std::string file,
bool flipColors)
: decompressionBuffer(decompressionBuffer),
deCompImage(deCompImage),
file(file),
flipColors(flipColors),
isCompressed(false)
{
assert(boost::filesystem::exists(file.c_str()));
fp = fopen(file.c_str(), "rb"); //以binary方式读入文件,得到文件指针fp
currentFrame = 0;
assert(fread(&numFrames, sizeof(int32_t), 1, fp)); //文件的第一行是一个int32_t类型的帧数
depthReadBuffer = new unsigned char[Resolution::getInstance().numPixels() * 2]; //深度图是16UC1的,所以一个像素占用16bit
imageReadBuffer = new unsigned char[Resolution::getInstance().numPixels() * 3]; //RGB图是8UC1的,一个像素占用8bit
}
RawLogReader::~RawLogReader()
{
delete [] depthReadBuffer;
delete [] imageReadBuffer;
fclose(fp);
}
void RawLogReader::getNext()
{
assert(fread(×tamp, sizeof(int64_t), 1, fp));
assert(fread(&depthSize, sizeof(int32_t), 1, fp));
assert(fread(&imageSize, sizeof(int32_t), 1, fp));
assert(fread(depthReadBuffer, depthSize, 1, fp));
if(imageSize > 0)
{
assert(fread(imageReadBuffer, imageSize, 1, fp));
}
if(deCompImage != 0)
{
cvReleaseImage(&deCompImage);
}
CvMat tempMat = cvMat(1, imageSize, CV_8UC1, (void *)imageReadBuffer);
if(imageSize == Resolution::getInstance().numPixels() * 3)
{
isCompressed = false;
deCompImage = cvCreateImage(cvSize(Resolution::getInstance().width(), Resolution::getInstance().height()), IPL_DEPTH_8U, 3);
memcpy(deCompImage->imageData, imageReadBuffer, Resolution::getInstance().numPixels() * 3);
}
else if(imageSize > 0)
{
isCompressed = true;
deCompImage = cvDecodeImage(&tempMat);
}
else
{
isCompressed = false;
deCompImage = cvCreateImage(cvSize(Resolution::getInstance().width(), Resolution::getInstance().height()), IPL_DEPTH_8U, 3);
memset(deCompImage->imageData, 0, Resolution::getInstance().numPixels() * 3);
}
if(depthSize == Resolution::getInstance().numPixels() * 2)
{
//RGB should not be compressed in this case
assert(!isCompressed);
memcpy(&decompressionBuffer[0], depthReadBuffer, Resolution::getInstance().numPixels() * 2);
}
else if(depthSize > 0)
{
//RGB should also be compressed
assert(isCompressed);
unsigned long decompLength = Resolution::getInstance().numPixels() * 2;
uncompress(&decompressionBuffer[0], (unsigned long *)&decompLength, (const Bytef *)depthReadBuffer, depthSize);
}
else
{
isCompressed = false;
memset(&decompressionBuffer[0], 0, Resolution::getInstance().numPixels() * 2);
}
if(flipColors)
{
cv::Mat3b rgb(Resolution::getInstance().rows(), Resolution::getInstance().cols(), (cv::Vec<unsigned char, 3> *)deCompImage->imageData, Resolution::getInstance().width() * 3);
cv::cvtColor(rgb, rgb, CV_RGB2BGR);
}
currentFrame++;
}
int RawLogReader::getNumFrames()
{
return numFrames;
}
bool RawLogReader::hasMore()
{
return currentFrame + 1 < numFrames;
}