基于C++和OpenCV实现的二维图像配准工具

目录

  1. 概述 1
  2. 应用问题 1
  3. 数据来源 2
  4. 实现算法 3
    4.1 软件界面 3
    4.2 优化算法 4
    4.3 实现细节 8
  5. 实验结果与分析 9
    5.1 目标函数值可视化 9
    5.2 结果 9
    5.2.1 暴力算法 10
    5.2.2 梯度下降法 11
    5.2.3 模拟退火算法 11
    5.3 参数调整 12
    5.4 分析与结论 12
    1.概述

本次实验中,我基于OpenCV,实现了一个二维图像配准工具,全部代码均为自行实现,OpenCV用于计算图像变 换与相似度。
该工具能够将一幅图像进行变换,并与另一幅图像相匹配。支持包括平移、旋转(含平移、缩放)、仿射与透视共四 种变换,使用L1、L2、无穷范数作为优化的目标函数,实现了暴力算法、梯度下降法、模拟退火算法来求解该优化 问题。
2.应用问题
如果两幅图像,它们是在同一场景、不同角度下拍摄的,那么,存在一种图像变换,使得其中一幅图像经过变换 后,能与另一图像大部分重合。
上述图像变换被称为配准(registration)T,被变换的图像被称为参考图像I_M,另一图像被称为目标图像I_F。优化 的目标是使变换后的参考图像T(I_M)与目标图像I_F的差异尽可能低。
最简单的图像变换是平移变换,需要确定两个参数: x和 y; 旋转变换通常与缩放、平移共同进行,需要确定四个参数: x、y、theta、scale; 仿射变换将矩形图像线性映射至一个平行四边形,需要确定三个坐标点,共六个参数,三个坐标点分别表示原图左上、右上、左下角变换至新图像的坐标位置; 透视变换与仿射变换相似,不同的是原图像的四个顶点可变换至任意的四边形,所以需要确定四个坐标点,共八个参数。此外,也有更为精细的图像变换方 法,但相比于上述简单变换,其参数较多,难以优化,故本次实验不予考虑。
对于图像相似度,需针对使用场景选择合适的度量方法。本实验中,实现的方法有L1(1范数)、L2(2范数)、无穷范 数三种。
总的来说,问题可以总结为如下步骤:
输入参考图像、目标图像;
选择合适的变换,确定参数范围;
设置初始参数,在这个参数下变换参考图像,并计算与目标图像的差异; 调整参数,使上述差异达到最小值;
输出最优参数作为配准变换。

#include "stdafx.h"
#include "Manager.h"
#include <string>
#include <opencv2\opencv.hpp>
#include "RegistrationThread.h"
#include "ResultWindow.h"

Manager::Manager(QObject *parent, ResultWindow* r_window)
    : QObject(parent)
{
    
    
    result_window = r_window;
}

Manager::~Manager()
{
    
    
    //r_thread->exit(0);
    //delete r_thread;
}

cv::Mat Manager::loadImage() {
    
    
    QString filename;
    while (filename.isEmpty()) {
    
    
        filename = QFileDialog::getOpenFileName(NULL, "Open image", "", "*.jpg *.png *.bnp", 0);
    }
    cv::Mat img = cv::imread(filename.toLocal8Bit().toStdString());
    if (img.channels() == 3) {
    
    
        cv::cvtColor(img, img, CV_BGR2RGB);
    }
    return img;
}

void Manager::loadReferenceImage() {
    
    
    ref_img = loadImage();
    emit referenceImageReady();
}

void Manager::loadTargetImage() {
    
    
    tar_img = loadImage();
    emit targetImageReady();
}

void Manager::runRegistration(Registration::TransformType t, Registration::SimilarityType s, Registration::OptimizationType o) {
    
    
    r_thread = new RegistrationThread(this, ref_img, tar_img, t, s, o);
    connect(r_thread, SIGNAL(transformedImageReady(cv::Mat*)), result_window, SLOT(updateTransformedImage(cv::Mat*)));
    connect(r_thread, SIGNAL(newDataPoint(int, double, double)), result_window, SLOT(addDataPoint(int, double, double)));
    r_thread->start();
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/newlw/article/details/129578739
今日推荐