C++实现批量图片拼接

 更新时间:2021年07月23日 14:58:31   作者:Lijilong0303  
这篇文章主要为大家详细介绍了C++实现批量图片拼接,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了C++实现批量图片拼接的具体代码,供大家参考,具体内容如下

/**函数功能:不同图片拼接
 *     参数:
 *          vector<string> pic_list      : 图片名称列表
 *          int pic_cols_rows           : horizontal==true,pic_cols_rows为生成图片的行数
                                           horizontal==false,pic_cols_rows为生成图片的列数
 *          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;
    //获取图片数量
    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;
        //生成的图片行数
        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;
        }
        //创建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坐标)
                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);
    
}
//调用
#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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • C语言数据结构之二叉树的非递归后序遍历算法

    C语言数据结构之二叉树的非递归后序遍历算法

    这篇文章主要介绍了C语言数据结构之二叉树的非递归后序遍历算法的相关资料,希望通过本文能帮助到大家,让大家实现这样的功能,需要的朋友可以参考下
    2017-10-10
  • 解决C++ 无法从void 转换为LRESULT的方法详解

    解决C++ 无法从void 转换为LRESULT的方法详解

    本篇文章是对C++中无法从void转换为LRESULT的解决方法进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C++实现LeetCode(189.旋转数组)

    C++实现LeetCode(189.旋转数组)

    这篇文章主要介绍了C++实现LeetCode(189.旋转数组),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • C语言 动态分配数组案例详解

    C语言 动态分配数组案例详解

    这篇文章主要介绍了C语言 动态分配数组案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • C++ STL容器stack和queue详解

    C++ STL容器stack和queue详解

    这篇文章主要介绍了C++ STL容器stack和queue详解的相关资料,需要的朋友可以参考下
    2016-10-10
  • C语言圣诞树的实现示例

    C语言圣诞树的实现示例

    本篇主要介绍了C语言圣诞树的实现示例,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12
  • C++编程语言实现单链表详情

    C++编程语言实现单链表详情

    这篇文章主要介绍的是利用C语言实现单链表,实现的是链表中最简单的一种单链表且每个结点中只含有一个指针域,下面将详细举例说明,需要的朋友可以参考一下
    2021-10-10
  • VisualStudio2019构建C/C++静态库和动态库dll的问题 附源码

    VisualStudio2019构建C/C++静态库和动态库dll的问题 附源码

    这篇文章主要介绍了VisualStudio2019构建C/C++静态库和动态库(dll)(文末附源码),本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-03-03
  • C++实现LeetCode(211.添加和查找单词-数据结构设计)

    C++实现LeetCode(211.添加和查找单词-数据结构设计)

    这篇文章主要介绍了C++实现LeetCode(211.添加和查找单词-数据结构设计),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • 聊聊C语言中sizeof运算符的一个陷阱

    聊聊C语言中sizeof运算符的一个陷阱

    在C语言中,sizeof()是一个判断数据类型或者表达式长度的运算符,下面这篇文章主要给大家介绍了关于C语言中sizeof运算符的一个陷阱的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-11-11

最新评论