本人小白一枚,"Hello World!"级别C++程序员,也是个OpenCV词典使用者。因项目需要,需实现4张图片(左上、右上、左下、右下)融合的功能。虽然应该先完成标定工作,奈何没经验,在标定环节卡了几天后决定还是先完成融合工作。搜了两天都没有搜到适合的代码或demo,只有搜到拼接左右两张图片,或者连续拼接多张图片的代码。今天突然想到该怎么拼接了,废话不多说,先看"算法"图:
是不是很直观。
在实验室随手拍了几张,因为上传照片的大小有限制,所以拼接的不是原图,效果比原图的拼接效果要差一些。
左上(/home/nvidia/21.jpg):
右上(/home/nvidia/22.jpg):
左下(/home/nvidia/23.jpg):
右下(/home/nvidia/24.jpg):
直接上代码 main.cpp
#include <iostream>
#include <opencv2/highgui.hpp>
#include <opencv2/stitching.hpp>
using namespace std;
using namespace cv;
bool try_use_gpu = false;
vector<Mat> imgs0; //用于存放左上和右上
vector<Mat> imgs1; //用于存放左下和右下
vector<Mat> imgs; //用于存放左上和右上拼接图、左下和右下拼接图
string result_name = "/home/nvidia/result.jpg"; //用于保存结果
int main(/*int argc, char * argv[]*/)
{
Mat img1 = imread("/home/nvidia/21.jpg"); //读图
Mat img2 = imread("/home/nvidia/22.jpg");
Mat img3 = imread("/home/nvidia/23.jpg");
Mat img4 = imread("/home/nvidia/24.jpg");
if (img1.empty() || img2.empty())
{
cout << "Can't read image 21.jpg or 22.jpg" << endl;
return -1;
}
if (img3.empty() || img4.empty())
{
cout << "Can't read image 23.jpg or 24.jpg" << endl;
return -1;
}
imgs0.push_back(img1);
imgs0.push_back(img2);
imgs1.push_back(img3);
imgs1.push_back(img4);
Stitcher stitcher = Stitcher::createDefault(try_use_gpu);
Mat pano0_0, pano0_1;
Mat pano1_0, pano1_1;
Mat pano2 ,pano3, pano4, pano_final;
// 使用stitch函数进行拼接
Stitcher::Status status1 = stitcher.stitch(imgs0, pano0_0);
if (status1 != Stitcher::OK)
{
cout << "Can't stitch img1 & img2, error code = " << int(status1) << endl;
return -1;
}
Stitcher::Status status2 = stitcher.stitch(imgs1, pano1_0);
if (status2 != Stitcher::OK)
{
cout << "Can't stitch img3 & img4, error code = " << int(status2) << endl;
return -1;
}
transpose(pano0_0,pano0_1); //左上和右上拼完后的图片左转90度
transpose(pano1_0,pano1_1); //左下和右下拼完后的图片左转90度
imgs.push_back(pano0_1);
imgs.push_back(pano1_1);
Stitcher::Status status = stitcher.stitch(imgs, pano2);
if (status != Stitcher::OK)
{
cout << "Can't stitch images, error code = " << int(status) << endl;
return -1;
}
transpose(pano2,pano3); //4张图片拼完之后再经过三次左转90度,就变成正的了
transpose(pano3,pano4);
transpose(pano4,pano_final);
imwrite(result_name, pano_final);//将拼接结果保存到/home/nvidia/result.jpg
// 显示结果图像
namedWindow("全景图像",0);
resizeWindow("全景图像",1920,1080); //全景图像的尺寸,我这设置的和屏幕分辨率一样
imshow("全景图像", pano_final);
if (waitKey() == 27)
return 0;
}
.pro文件这样配置
TEMPLATE = app
CONFIG += console c++11
CONFIG -= app_bundle
CONFIG -= qt
SOURCES += main.cpp
INCLUDEPATH += /usr/local/include \
/usr/local/include/opencv \
/usr/local/include/opencv2
LIBS += /usr/local/lib/libopencv_calib3d.so \
/usr/local/lib/libopencv_core.so \
/usr/local/lib/libopencv_features2d.so \
/usr/local/lib/libopencv_flann.so \
/usr/local/lib/libopencv_highgui.so \
/usr/local/lib/libopencv_imgcodecs.so \
/usr/local/lib/libopencv_imgproc.so \
/usr/local/lib/libopencv_ml.so \
/usr/local/lib/libopencv_objdetect.so \
/usr/local/lib/libopencv_photo.so \
/usr/local/lib/libopencv_shape.so \
/usr/local/lib/libopencv_stitching.so \
结果图:
虽然运行结果看着还可以(四周没拼接好主要是因为我照片没拍好),但是足足用了10秒钟,可能是控制器的CPU不行吧(拼接原图用了大约45秒,4张原图每张大约6M,效果比这个结果图要好一些)。
第一次写文章,写的不对不好的地方还请各路大神指点一二。
https://blog.csdn.net/luckyfairy17/article/details/81239356
https://blog.csdn.net/hongtao_6/article/details/82183403
https://blog.csdn.net/hongtao_6/article/details/81910691