【opencv】示例-stiching.cpp 图像拼接

cpp 复制代码
#include "opencv2/imgcodecs.hpp" // 导入opencv图像编码功能库
#include "opencv2/highgui.hpp"   // 导入opencv高层用户界面功能库
#include "opencv2/stitching.hpp" // 导入opencv图像拼接功能库


#include <iostream> // 导入输入输出流库


using namespace std;  // 使用std命名空间,便于使用这个命名空间下的功能
using namespace cv;   // 使用cv(opencv)命名空间


bool divide_images = false; // 默认不将图像分块处理的标志位
Stitcher::Mode mode = Stitcher::PANORAMA; // 默认拼接模式为全景模式
vector<Mat> imgs; // 存储所有图像的向量
string result_name = "result.jpg"; // 默认输出图像的文件名


void printUsage(char** argv); // 函数声明,打印程序用法信息
int parseCmdArgs(int argc, char** argv); // 函数声明,解析命令行参数


// 主函数
int main(int argc, char* argv[])
{
    int retval = parseCmdArgs(argc, argv); // 解析命令行参数
    if (retval) return EXIT_FAILURE; // 如果参数有误,返回失败


    //![stitching]
    Mat pano; // 用于存储拼接完的图像
    Ptr<Stitcher> stitcher = Stitcher::create(mode); // 创建拼接器实例,传入模式
    Stitcher::Status status = stitcher->stitch(imgs, pano); // 进行拼接并返回状态


    if (status != Stitcher::OK) // 如果状态不是OK,即拼接失败
    {
        cout << "Can't stitch images, error code = " << int(status) << endl; // 输出错误信息
        return EXIT_FAILURE; // 返回失败
    }
    //![stitching]


    imwrite(result_name, pano); // 写入拼接完成的图像
    cout << "stitching completed successfully\n" << result_name << " saved!"; // 输出成功信息
    return EXIT_SUCCESS; // 返回成功
}


// 打印程序用法信息的函数
void printUsage(char** argv)
{
    cout
            << "Images stitcher.\n\n" 
            << "Usage :\n" << argv[0] <<" [Flags] img1 img2 [...imgN]\n\n"
            << "Flags:\n"
            << "  --d3\n"
            << "      internally creates three chunks of each image to increase stitching success\n"
            << "  --mode (panorama|scans)\n"
            << "      Determines configuration of stitcher. The default is 'panorama',\n"
            << "      mode suitable for creating photo panoramas. Option 'scans' is suitable\n"
            << "      for stitching materials under affine transformation, such as scans.\n"
            << "  --output <result_img>\n"
            << "      The default is 'result.jpg'.\n\n"
            << "Example usage :\n" << argv[0] << " --d3 --mode scans img1.jpg img2.jpg\n";
}


// 解析命令行参数的函数
int parseCmdArgs(int argc, char** argv)
{
    if (argc == 1) // 如果参数只有一个,即没有指定输入图片
    {
        printUsage(argv); // 打印程序用法信息
        return EXIT_FAILURE; // 返回失败
    }


    for (int i = 1; i < argc; ++i) // 遍历参数
    {
        if (string(argv[i]) == "--help" || string(argv[i]) == "/?")
        {
            printUsage(argv); // 如果是帮助标志,打印程序用法信息
            return EXIT_FAILURE; // 返回失败
        }
        else if (string(argv[i]) == "--d3")
        {
            divide_images = true; // 如果设置了分块标志,修改分块处理标志位为真
        }
        else if (string(argv[i]) == "--output")
        {
            result_name = argv[i + 1]; // 设置输出文件名
            i++; // 跳过下一个参数(输出文件名)
        }
        else if (string(argv[i]) == "--mode")
        {
            if (string(argv[i + 1]) == "panorama")
                mode = Stitcher::PANORAMA; // 设置模式为全景
            else if (string(argv[i + 1]) == "scans")
                mode = Stitcher::SCANS; // 设置模式为扫描
            else
            {
                cout << "Bad --mode flag value\n"; // 如果模式设置错误,输出错误信息
                return EXIT_FAILURE; // 返回失败
            }
            i++; // 跳过下一个参数(模式)
        }
        else
        {
            Mat img = imread(samples::findFile(argv[i])); // 读取图像
            if (img.empty()) // 如果读取失败
            {
                cout << "Can't read image '" << argv[i] << "'\n"; // 输出错误信息
                return EXIT_FAILURE; // 返回失败
            }


            if (divide_images) // 如果设置了分块处理标志
            {
                Rect rect(0, 0, img.cols / 2, img.rows); // 计算第一块的位置
                imgs.push_back(img(rect).clone()); // 把第一块图像加入向量
                rect.x = img.cols / 3; // 计算第二块的位置
                imgs.push_back(img(rect).clone()); // 把第二块图像加入向量
                rect.x = img.cols / 2; // 计算第三块的位置
                imgs.push_back(img(rect).clone()); // 把第三块图像加入向量
            }
            else
                imgs.push_back(img); // 如果没有分块处理,直接加入图像
        }
    }
    return EXIT_SUCCESS; // 返回成功
}

此代码用于实现图像的拼接处理,使用了OpenCV库来加载、处理和保存图像。主要功能包括解析命令行参数以获得用户输入的图像文件和其他选项,创建一个拼接器来对图像进行拼接,并根据拼接结果保存为一个文件。用户可以通过特定的标志来影响拼接的模式或增加拼接成功率(例如,通过分块处理)。

bash 复制代码
./test --d3 --mode scans lena.jpg


stitching completed successfully
result.jpg saved!

lena.jpg

result.jpg scan拼接有误

相关推荐
千宇宙航3 小时前
闲庭信步使用SV搭建图像测试平台:第三十一课——基于神经网络的手写数字识别
图像处理·人工智能·深度学习·神经网络·计算机视觉·fpga开发
onceco3 小时前
领域LLM九讲——第5讲 为什么选择OpenManus而不是QwenAgent(附LLM免费api邀请码)
人工智能·python·深度学习·语言模型·自然语言处理·自动化
小小小小宇5 小时前
虚拟列表兼容老DOM操作
前端
悦悦子a啊5 小时前
Python之--基本知识
开发语言·前端·python
安全系统学习6 小时前
系统安全之大模型案例分析
前端·安全·web安全·网络安全·xss
whoarethenext6 小时前
使用 C++/OpenCV 和 MFCC 构建双重认证智能门禁系统
开发语言·c++·opencv·mfcc
jndingxin6 小时前
OpenCV CUDA模块设备层-----高效地计算两个 uint 类型值的带权重平均值
人工智能·opencv·计算机视觉
涛哥码咖6 小时前
chrome安装AXURE插件后无效
前端·chrome·axure
Sweet锦6 小时前
零基础保姆级本地化部署文心大模型4.5开源系列
人工智能·语言模型·文心一言
OEC小胖胖6 小时前
告别 undefined is not a function:TypeScript 前端开发优势与实践指南
前端·javascript·typescript·web