C++實(shí)現(xiàn)批量圖片拼接
本文實(shí)例為大家分享了C++實(shí)現(xiàn)批量圖片拼接的具體代碼,供大家參考,具體內(nèi)容如下
/**函數(shù)功能:不同圖片拼接
* 參數(shù):
* vector<string> pic_list : 圖片名稱列表
* int pic_cols_rows : horizontal==true,pic_cols_rows為生成圖片的行數(shù)
horizontal==false,pic_cols_rows為生成圖片的列數(shù)
* bool horizontal : true-先橫向后縱向合成圖片 false-先縱向后橫向合成圖片
* bool draw_rect : true-在圖片邊緣畫矩形框 false-不在圖片邊緣畫矩形框
*
*/
void mergeDiffPic(vector<string> pic_list, int pic_cols_rows, string output_file, bool horizontal=true, bool draw_rect=false)
{
int pic_cols = 0;
int pic_rows = 0;
int max_cols=0;
int max_rows=0;
int size_cols=0;
int size_rows=0;
vector<int> tmp_cols;
vector<int> tmp_rows;
//獲取圖片數(shù)量
int pic_num = pic_list.size();
vector<Mat>input(pic_num);
Mat merge;
for(int i=0; i<pic_num; i++){
input[i] = imread(pic_list[i]);
//draw_rect為true,畫矩形
if(draw_rect){
Rect rect = Rect(0,0,input[i].cols,input[i].rows);
rectangle(input[i],rect,Scalar(0, 0, 255));
}
}
//按水平方向合成
if (horizontal){
pic_cols = pic_cols_rows;
pic_rows = pic_num/pic_cols;
//生成的圖片行數(shù)
if (pic_num%pic_cols != 0) pic_rows += 1;
int i = 0;
int j = 0;
for (i=0;i<pic_rows;i++){
max_cols = 0;
//保存每行圖片的最大高度,方便后面確定圖片的擺放位置
tmp_rows.push_back(size_rows);
max_rows = 0;
for (j=0;j<pic_cols;j++){
if ((i*pic_cols+j) >= pic_num) break;
//保存每行圖片的最大寬度,用于確定合成圖的寬度
max_cols += input[i*pic_cols+j].cols;
max_rows = (max_rows>input[i*pic_cols+j].rows?max_rows:input[i*pic_cols+j].rows);
}
//合成圖的寬度和高度
size_cols = (max_cols>size_cols?max_cols:size_cols);
size_rows += max_rows;
if ((i*pic_cols+j) >= pic_num) break;
}
//創(chuàng)建size_cols×size_rows大小的空白圖片,用于擺放小圖
Size mergesize(size_cols,size_rows);
merge.create(mergesize, CV_MAKETYPE(input[0].depth(), 3));//rgb 3通道
merge = Scalar::all(0);
vector<Mat>temp(pic_num);
//擺放圖片
for (i=0;i<pic_rows;i++){
int sum_cols = 0;
for (j=0;j<pic_cols;j++){
if ((i*pic_cols+j) >= pic_num) break;
//確定第(i*pic_cols+j)張圖在merge上的位置
temp[i*pic_cols+j] = merge(Rect(sum_cols, tmp_rows[i], input[i*pic_cols+j].cols, input[i*pic_cols+j].rows));
//下一張圖的起始位置(x坐標(biāo))
sum_cols += input[i*pic_cols+j].cols;
input[i*pic_cols+j].copyTo(temp[i*pic_cols+j]);
}
if ((i*pic_cols+j) >= pic_num) break;
}
}else{
pic_rows = pic_cols_rows;
pic_cols = pic_num/pic_rows;
if (pic_num%pic_rows != 0) pic_cols += 1;
int i = 0;
int j = 0;
for (i=0;i<pic_cols;i++){
max_rows = 0;
tmp_cols.push_back(size_cols);
max_cols = 0;
for (j=0;j<pic_rows;j++){
if ((i*pic_rows+j) >= pic_num) break;
max_rows += input[i*pic_rows+j].rows;
max_cols = (max_cols>input[i*pic_rows+j].cols?max_cols:input[i*pic_rows+j].cols);
}
size_rows = (max_rows>size_rows?max_rows:size_rows);
size_cols += max_cols;
if ((i*pic_rows+j) >= pic_num) break;
}
//std::cout<<size_cols<<std::endl;
//std::cout<<size_rows<<std::endl;
Size mergesize(size_cols,size_rows);
vector<Mat>temp(pic_num);
merge.create(mergesize, CV_MAKETYPE(input[0].depth(), 3));//rgb 3通道
merge = Scalar::all(0);
for (i=0;i<pic_cols;i++){
int sum_rows = 0;
for (j=0;j<pic_rows;j++){
if ((i*pic_rows+j) >= pic_num) break;
temp[i*pic_rows+j] = merge(Rect(tmp_cols[i], sum_rows, input[i*pic_rows+j].cols, input[i*pic_rows+j].rows));
sum_rows += input[i*pic_rows+j].rows;
input[i*pic_rows+j].copyTo(temp[i*pic_rows+j]);
}
if ((i*pic_rows+j) >= pic_num) break;
}
}
//顯示圖片
//imshow("merge", merge);
//保存圖片
imwrite(output_file.c_str(), merge);
//waitKey(0);
}
//調(diào)用
#include<iostream>
#include<string>
#include<vector>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main(){
vector<string> pic_list;
pic_list.push_back("1.jpg");
pic_list.push_back("2.jpg");
pic_list.push_back("3.jpg");
mergeDiffPic(pic_list, 2, "merge1.jpg");
mergeDiffPic(pic_list, 1, "merge2.jpg",false);
mergeDiffPic(pic_list, 3, "merge3.jpg",false,true);
return 0;
}
//編譯 g++ merge.cpp `pkg-config --cflags --libs opencv`
merge1.jpg

merge2.jpg

merge3.jpg

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C語言數(shù)據(jù)結(jié)構(gòu)之二叉樹的非遞歸后序遍歷算法
這篇文章主要介紹了C語言數(shù)據(jù)結(jié)構(gòu)之二叉樹的非遞歸后序遍歷算法的相關(guān)資料,希望通過本文能幫助到大家,讓大家實(shí)現(xiàn)這樣的功能,需要的朋友可以參考下2017-10-10
解決C++ 無法從void 轉(zhuǎn)換為LRESULT的方法詳解
本篇文章是對C++中無法從void轉(zhuǎn)換為LRESULT的解決方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
C++實(shí)現(xiàn)LeetCode(189.旋轉(zhuǎn)數(shù)組)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(189.旋轉(zhuǎn)數(shù)組),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07
VisualStudio2019構(gòu)建C/C++靜態(tài)庫和動態(tài)庫dll的問題 附源碼
這篇文章主要介紹了VisualStudio2019構(gòu)建C/C++靜態(tài)庫和動態(tài)庫(dll)(文末附源碼),本文通過實(shí)例圖文相結(jié)合給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03
C++實(shí)現(xiàn)LeetCode(211.添加和查找單詞-數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì))
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(211.添加和查找單詞-數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08

