【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拼接有误

相关推荐
runnerdancer7 小时前
LLM是怎么处理messages数组的,提示词缓存又是什么
前端·agent
陈随易8 小时前
VSCode的Copilot扩展支持接入DeepSeek,Kimi了!
前端·后端·程序员
我不是外星人9 小时前
有了 Harness Engineering ,真的还需要研发工程师吗?
前端·后端·ai编程
冬奇Lab9 小时前
Agent 系列(23):Web Agent——让 Agent 真正浏览网页
人工智能·llm·agent
冬奇Lab9 小时前
每日一个开源项目(第135篇):codebase-memory-mcp - 给 AI Agent 一张代码库的知识图谱
人工智能·开源·llm
IT_陈寒12 小时前
JavaScript的闭包把我坑惨了,说好的内存会自动回收呢?
前端·人工智能·后端
Jackson__13 小时前
分享一个横向滚动案例,带悬停暂停,通用性很强
前端
MariaH13 小时前
git rebase的使用
前端