Win10+vs2019配置与运行RenderMatch
RenderMatch旨在解决aerial images 和ground images 匹配问题,其思路可参考原论文 “Leveraging Photogrammetric Mesh Models for Aerial-Ground Feature Point Matching Toward Integrated 3D Reconstruction”
1.源码下载
Github: https://github.com/saedrna/RenderMatch
2.环境配置与编译
按照作者提供的readme文档,首先创建虚拟环境
依次在cmd命令行执行上面红色框中的命令,创建虚拟环境
其中,build.bat文件里可以修改使用的VS版本,可根据实际进行修改
3 .代码生成
1.用vs2019打开build文件夹中的RenderMatch.sln, 使用 release x64模式
对每个项目都依次右键进行生成,也可以直接对CMakePredefinedTargets里的INSTALL右键一次性生成所有项目。
问题1: 生成时会出现几百个报错,都是“未定义的标识符”“未声明的变量”之类的等等问题
原因是编码的问题,双击错误提示定位到错误所在的源文件,在代码区域的右下角将LF类型编码修改为CRLF。将所有报错提示所在的源文件都照此修改。
问题2:
错误提示fatal error LNK1104: 无法打开文件"tbb12.lib”
解决方法:给项目添加库文件路径,配置属性–>链接器–>常规–>附加目录 。在里面填上库文件所在的路径即可。
再次生成,无报错。
4.运行demo案例
首先在github上下载数据集,解压后按照给的作者给的routine执行
。
可以选择在cmd使用命令执行,也可以在vs里右键项目属性-调试-命令 里输入参数,并设置该项目为启动项,然后运行。
问题3: 出现了下图问题
找了很久原因,甚至重新配了环境,最后发现是因为这个dll与vcpkg里的dll冲突了,所有右键项目属性-vcpkg,将使用vcpkg改成否
**问题4:**执行 TileImage -i Aerial.xml -o ./AerialTiled 时,要将语句中的Aerial.xml修改为所下数据集中的aerial.xml对应的路径和名字,我这里就是 SWJTU-LIB-UAV.xml
同时,还需要打开该xml文件,将里面的ImagePath全部修改成自己的图片存放路径,否则会报错无法找到图片。
运行成功,继续运行下一个语句:FeatureExtract -i ./AerialTiled/Aerial.json 注意这里的json文件的名字也要改成自己生成的json文件的名字,运行完就生成了很多sift文件
问题5 按照他的demo运行最后一个语句结果发现什么都没有。。。
查看代码发现这里是错误的,-g 参数后面应该对应的是ground的json文件,因此,需要对ground image也执行一遍TileImage 和FeatureExtract
然后修改RenderMeshMatch命令 为:
-a G:\study\Dataset\SWJTU-LIB\AerialTiled\SWJTU-LIB-UAV.json -g G:\study\Dataset\SWJTU-LIB\AerialTiled\SWJTU-LIB-TER.json -m G:\study\Dataset\SWJTU-LIB\model\Data\root.osgb -c G:\study\RenderMatch-master\config.json
路径需要根据自己的路径进行修改。
问题6 再次运行,还是报错,发现是osgb模型加载失败
错误信息:Could not find plugin to read objects from file
原因是缺一些库,去conda环境下把库都拷进来
问题7 不报错了,但是还是什么结果都没有。。。最后发现是还有个坐标没有输入。。。在数据集中model文件夹里拷贝metadata.xml里的坐标,加到命令中,如下
-a G:\study\Dataset\SWJTU-LIB\AerialTiled\SWJTU-LIB-UAV.json -g G:\study\Dataset\SWJTU-LIB\AerialTiled\SWJTU-LIB-TER.json -m G:\study\Dataset\SWJTU-LIB\model\Data\root.osgb -c G:\study\RenderMatch-master\config.json -t 2967,5742,0
可以运行了,最终会生成一个match.bin文件,里面是匹配结果,这个bin文件是一个二进制文件
发现在输入的命令参数,加上 -r G:\study\Dataset\SWJTU-LIB\AerialTiled\SWJTU-LIB-TER_match.bin
那么每次运行时,就不会在进行匹配,而是直接加载匹配结果,像酱紫
match_results对应的结构体是
可以看出分别是点的三维坐标,在renderImg、aerialImg、GroundImg中对应的影像序号和像点坐标,可以选择自己想要的方式输出匹配结果。
5. 生成匹配结果图
这里我想将一张aerial image 和ground image 影像的匹配结果对应起来,在一张影像中显示出来
于是添加opencv的画线代码
cv::Mat aerial_image = cv::imread(block_aerial.photos[60].path);
cv::Mat ground_image = cv::imread(block_ground.photos[25].path);
int w_a = aerial_image.cols;
int h_a = aerial_image.rows;
int w_g = ground_image.cols;
int h_g = ground_image.rows;
int w_new = std::max(w_a, w_g); // the width and height of the combined image
int h_new = h_a + h_g;
cv::Mat combined_img = cv::Mat(h_new, w_new, CV_8UC3, cv::Scalar::all(0));
cv::Mat ROI_1 = combined_img(cv::Rect(0, 0, w_a, h_a));
cv::Mat ROI_2 = combined_img(cv::Rect(0, h_a, w_g, h_g));
aerial_image.copyTo(ROI_1);
ground_image.copyTo(ROI_2);
for (int i = 0; i < match_results.size(); i++) {
//combine aerial-ground images in one to show the correspondences
for (int j = 0; j < match_results[i].iid_aerials.size(); j++) {
if (match_results[i].iid_aerials[j] == 60) {
for (int k = 0; k < match_results[i].iid_grounds.size(); k++) {
if (match_results[i].iid_grounds[k] == 25) {
// draw points on combined image
cv::line(combined_img,
cv::Point(match_results[i].pt_aerials[j][0] - 10,
match_results[i].pt_aerials[j][1]),
cv::Point(match_results[i].pt_aerials[j][0] + 10,
match_results[i].pt_aerials[j][1]),
CV_RGB(0, 255, 255), 2, CV_AA, 0);
cv::line(combined_img,
cv::Point(match_results[i].pt_aerials[j][0],
match_results[i].pt_aerials[j][1] - 10),
cv::Point(match_results[i].pt_aerials[j][0],
match_results[i].pt_aerials[j][1] + 10),
CV_RGB(0, 255, 255), 2, CV_AA, 0);
cv::line(combined_img,
cv::Point(match_results[i].pt_grounds[k][0] - 10,
match_results[i].pt_grounds[k][1] + h_a),
cv::Point(match_results[i].pt_grounds[k][0] + 10,
match_results[i].pt_grounds[k][1] + h_a),
CV_RGB(0, 255, 255), 2, CV_AA, 0);
cv::line(combined_img,
cv::Point(match_results[i].pt_grounds[k][0],
match_results[i].pt_grounds[k][1] - 10 + h_a),
cv::Point(match_results[i].pt_grounds[k][0],
match_results[i].pt_grounds[k][1] + 10 + h_a),
CV_RGB(0, 255, 255), 2, CV_AA, 0);
cv::line(
combined_img,
cv::Point(match_results[i].pt_aerials[j][0], match_results[i].pt_aerials[j][1]),
cv::Point(match_results[i].pt_grounds[k][0],
match_results[i].pt_grounds[k][1] + h_a),
CV_RGB(0, 0, 255), 2, CV_AA, 0);
}
}
}
}
}
cv::imwrite("combine_image_matching.jpg", combined_img);
6. 匹配结果
准确率还是很客观的
缺点就是代码开源的时候readme文档写的太草率,routine没有写清楚,参数也没有写清楚,很崩溃