算法思路:将4张打乱顺序的碎片拼接复原并展示原图
源码展示:
将x张碎片的左右边缘提取保存
左右边缘两两对比,将相似度超过预设阈值的碎片执行拼接操作,得到左右拼接好的碎片
提取左右拼接好的碎片的上下边缘
上下边缘两两对比,将相似度超过预设阈值的碎片执行拼接操作,得到原图
#include#include "opencv2/core/core.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #include #include #include #include #include using namespace std; using namespace cv; int n = 0; //左右拼接时需要的迭代器 int m = 0; //上下拼接时需要的迭代器 //读取碎片 vector fragments_Imread(string files_name); vector fragments_LR_Imread(string files_name); //读取左右拼接好的碎片 //保存每张碎片的左右边缘 vector > edge_resection_LR(const vector & fragments); //直方图对比 bool compare_by_hist(const Mat& img1, const Mat& img2); //左右拼接 void picture_stitching_LR(const Mat& img1, const Mat& img2); //对每张碎片的左右边缘相互对比拼接 void alignment_and_splicing_LR(const vector & fragments, const vector >& resection_LR);//参数:碎片;碎片的左右边缘 //保存每张碎片的上下边缘 vector > edge_resection_TB(const vector & fragments_LR); //上下拼接 void picture_stitching_TB(const Mat& img1, const Mat& img2); //对左右拼接好的碎片进行上下对比拼接 void alignment_and_splicing_TB(const vector & fragments_LR, const vector >& resection_TB); int main() { vector fragments = fragments_Imread("res/fragments/"); //读取碎片 vector > resection_LR = edge_resection_LR(fragments); //保存每张碎片的左右边缘 alignment_and_splicing_LR(fragments,resection_LR); //对每张碎片的左右边缘相互对比拼接 vector fragments_LR = fragments_LR_Imread("res/fragments_LR/"); //读取左右拼接好的碎片 vector > resection_TB = edge_resection_TB(fragments_LR); //保存拼接好的左右碎片的上下边缘 alignment_and_splicing_TB(fragments_LR, resection_TB); //对左右拼接好的碎片的上下边缘相互对比拼接 Mat result = imread("res/result/0.jpg"); imshow("Restoration map",result); //展示结果 waitKey(0); return 0; } //读取碎片 vector fragments_Imread(string files_name){ vector files; glob(std::move(files_name),files); vector fragments; for(auto &file : files){ fragments.push_back(imread(file)); } return fragments; } vector fragments_LR_Imread(string files_name){ vector files; glob(std::move(files_name),files); vector fragments_LR; for(auto &file : files){ fragments_LR.push_back(imread(file)); } return fragments_LR; } //保存每张碎片的左右边缘 vector > edge_resection_LR(const vector & fragments){ vector > resection_LR(fragments.size(), vector (2)); for(int i = 0; i = 0.95; } //左右拼接 void picture_stitching_LR(const Mat& img1, const Mat& img2){ Mat result; hconcat(img1,img2,result); imwrite("res/fragments_LR/"+to_string(n)+".jpg", result); n++; } //对每张碎片的左右边缘相互对比拼接 void alignment_and_splicing_LR(const vector & fragments, const vector >& resection_LR){ for(int i = 0; i l){ //当j>l时被对比的边缘应该在对比右边 picture_stitching_LR(fragments.at(i),fragments.at(k+1)); } else if(j > edge_resection_TB(const vector & fragments_LR){ vector > resection_TB(fragments_LR.size(), vector (2)); for(int i = 0; i & fragments_LR, const vector >& resection_TB){ for(int i = 0; i l){ //当j>l时被对比的边缘应该在对比下边 picture_stitching_TB(fragments_LR.at(i),fragments_LR.at(k+1)); } else if(j 结果演示 碎片:
拼接结果:
参考文章
OpenCV学习笔记——判断两张图的相似度代码尚完善,还有些地方存在小bug(因为又菜又懒),如果在运行过程中报错就把直方图比对函数compare_by_hist()的返回值调小直到运行成功
项目地址



