背景
GTAV是一个非常好的游戏,目前也已经被广泛应用到深度学习之中了。本篇博客简单介绍一下如何采集数据。
1.数据采集
1. 代码修改
本篇博客的代码来源于GTAVisionExport。但是上述代码中,存在些许问题,经过调整后的代码如下:
https://github.com/Yannnnnnnnnnnn/GTAVisionExport。
主要修改的模块是:
- 使用二进制保存数据
- 调整深度渲染器分辨率,保持与游戏界面大小一致
此处,简单提一下GTAVisionExport的使用规则:
- 需要拷贝ScriptHookV的bin目录下的文件和上述代码编译生成的GTAVisionNative.asi & GTAVisionNative.lib到游戏根目录
- 关闭界面上的所有提示,包括地图、警告、字母等等;
- 采集数据前,应多次按键
V
,调整视角至第一人称。
2.去掉相机畸变
下图展示了一个使用上述代码采集数据的结果,可以发现在边缘部分,深度图和原始照片并不完全对应;产生的主要原因是因为相机畸变。
本文使用mod(https://www.gta5-mods.com/misc/no-chromatic-aberration-lens-distortion-1-41)修正相机畸变,方法是下载一个OpenVI,然后首先Tools->ASI Manger
安装mod
然后把刚刚mod解压的三个timecycle_mods_1.xml
、timecycle_mods_3.xml
、timecycle_mods_4.xml
拷贝到Grand Theft Auto V \ update \ update.rpf / common / data / timecycle
下即可(使用openVI打开rpf文件)。
修正畸变后的结果如下,明显相机畸变不存在了。
2.数据读取
GTAVisionExport生成的数据是原始二进制块,可以借助opencv转换成上述图,基本代码如下:
1. depth
FILE *fp;
fp = fopen('depth.raw',"rb");
float *data = new float[1920 * 1080];
fread((void*)data, sizeof(float), 1920 * 1080, fp);
fclose(fp);
// 深度值需要矫正
double b = 10003.814*0.15 / (-0.15 + 10003.814);
double k = 10003.814 / (-0.15 + 10003.814) - 1.0;
Mat img = cv::Mat::zeros(cv::Size(1920, 1080), CV_32FC1);
for (int y = 0; y < 1080; y++)
{
for (int x = 0; x < 1920; x++)
{
img.at<float>(y, x) = b / (data[(y * 1920 + x)] + k);
}
}
double minValue, maxValue;
cv::minMaxIdx(img, &minValue, &maxValue);
img = 255*(img - minValue) / (maxValue - minValue);
img.convertTo(img, CV_8UC1);
cv::Mat out;
cv::applyColorMap(img, out, cv::COLORMAP_JET);
cv::imwrite("depth.jpg", out);
delete[]data;
return 0;
2.rgb
FILE *fp;
fp = fopen("rgb.raw","rb");
unsigned char *data = new unsigned char[4*1920 * 1080];
fread((void*)data, sizeof(unsigned char), 4*1920 * 1080, fp);
fclose(fp);
Mat img = cv::Mat::zeros(cv::Size(1920, 1080), CV_8UC3);
for (int y = 0; y < 1080; y++)
{
for (int x = 0; x < 1920; x++)
{
unsigned char r = data[ (y * 1920 + x) * 4 + 2 ];
unsigned char g = data[ (y * 1920 + x) * 4 + 1];
unsigned char b = data[ (y * 1920 + x) * 4 + 0];
img.at<Vec3b>(y, x)[0] = r;
img.at<Vec3b>(y, x)[1] = g;
img.at<Vec3b>(y, x)[2] = b;
}
}
cv::imwrite("color.jpg", img);
delete[]data;
return 0;