上文说到使用OpenCV进行模板匹配的函数matchTemplate,下面就matchTemplate函数的内部处理过程做一个简单的说明。matchTemplate函数的源代码在OpenCV的源代码目录下的 modules/imgproc/src/templmatch.cpp 文件中。其核心函数代码如下(其中的注释是我添加的):

void matchTemplate( const Mat& _img, const Mat& _templ, Mat& result, int method )
{
CV_Assert( CV_TM_SQDIFF <= method && method <= CV_TM_CCOEFF_NORMED );
    //numType用来表示模板匹配的方式,0表示相关匹配法,1表示相关系数匹配法,2表示平方差匹配法
//isNormed表示是否进行归一化处理,true表示进行归一化,false表示不进行归一化处理
    int numType = method == CV_TM_CCORR || method == CV_TM_CCORR_NORMED ? 0 :
method == CV_TM_CCOEFF || method == CV_TM_CCOEFF_NORMED ? 1 : 2;
bool isNormed = method == CV_TM_CCORR_NORMED ||
method == CV_TM_SQDIFF_NORMED ||
method == CV_TM_CCOEFF_NORMED;
    //判断两幅图像的大小关系,如果输入的原始图像比匹配图像要小,则将原始图像作为模板,原来的模板图像作为搜索图
    Mat img = _img, templ = _templ;
if( img.rows < templ.rows || img.cols < templ.cols )
std::swap(img, templ);
CV_Assert( (img.depth() == CV_8U || img.depth() == CV_32F) &&
img.type() == templ.type() );
   //crossCorr函数是将输入图像做了一次DFT变换(离散傅里叶变换),将空间域的图像转换到频率域中来进行处理,并将处理的结果存放在result中
    int cn = img.channels();
crossCorr( img, templ, result,
Size(img.cols - templ.cols + 1, img.rows - templ.rows + 1),
CV_32F, Point(0,0), 0, 0);
//如果是相关匹配方法,此处已经计算完毕,返回
    if( method == CV_TM_CCORR )
return;
//将模板看作单位1,计算每一个像元所占的百分比(也可以理解为整个模板面积为1,计算每个像元的面积)
    double invArea = 1./((double)templ.rows * templ.cols);
Mat sum, sqsum;
Scalar templMean, templSdv;
double *q0 = 0, *q1 = 0, *q2 = 0, *q3 = 0;
double templNorm = 0, templSum2 = 0;
//相关系数匹配算法
    if( method == CV_TM_CCOEFF )
{
integral(img, sum, CV_64F);//对原始图像进行求和
templMean = mean(templ);//计算模板图像的均值向量
}
else//其他匹配算法
{
integral(img, sum, sqsum, CV_64F);//计算原始图像的和以及平方和
meanStdDev( templ, templMean, templSdv );//计算模板图像的均值向量和方差向量
templNorm = CV_SQR(templSdv[0]) + CV_SQR(templSdv[1]) +
CV_SQR(templSdv[2]) + CV_SQR(templSdv[3]);//计算所有通道的方差和
if( templNorm < DBL_EPSILON && method == CV_TM_CCOEFF_NORMED )
{//如果所有通道的方差的和等于0,并且使用的方法是归一化相关系数匹配方法,则返回
result = Scalar::all(1);
return;
}
templSum2 = templNorm +
CV_SQR(templMean[0]) + CV_SQR(templMean[1]) +
CV_SQR(templMean[2]) + CV_SQR(templMean[3]);//计算所有通道的均值的平方和
if( numType != 1 )//匹配方式不是相关系数,对模板均值向量和templNorm重新赋值
{
templMean = Scalar::all(0);
templNorm = templSum2;
}
templSum2 /= invArea;
templNorm = sqrt(templNorm);
templNorm /= sqrt(invArea); // care of accuracy here
q0 = (double*)sqsum.data;
q1 = q0 + templ.cols*cn;
q2 = (double*)(sqsum.data + templ.rows*sqsum.step);
q3 = q2 + templ.cols*cn;
}
//下面就是在结果图像中进行查找匹配的结果位置,代码略去,具体可参考OpenCV源代码

在测试过程中,发现直接用OpenCV打开超过1G(可能比这个大小还要小)的图像就会导致错误,查看OpenCV代码,发现其一次将所有的图像数据全部载入内存,导致内存不够出错,而且OpenCV只支持普通的常用的图像数据格式,并不能直接打开Erdas的img格式或者PCI的pix格式,针对这两个问题,我提出的解决思路是实用GDAL来作为图像数据的读取库,然后分块读取一部分数据(指定一个大小,我指定的是每次读64M的数据),如果图像数据超过该大小,则分块处理,每次处理一块,OpenCV可以建立一个内存数据,就是将图像的RGB值按照特定的顺序读取到内存中,然后将该指针交给OpenCV,OpenCV可以通过该内存数据来构建一个图像,然后再调用模板匹配算法,计算出的结果在还原到原来大的图像中的位置。

在实际的执行过程中,上述方式是可行的,执行效率大概在一个1G的img图像查找一个128*128的模板需要1分钟左右,相比按照前一篇博客中的方式速度提升了很多倍(1G的数据大概计算了4个小时还没有算完)。对于1min中查找出结果应该是可以接受的,但是感觉还是有点慢,于是想到首先将模板和原始图像同时按照一定的采样比例建立金字塔,然后从金字塔的顶层开始进行匹配,根据顶层找到的位置,再到下一层对应的区域中查找,依次知道查找到原始图像级别。这样就可以减少很多的运算。经过测试,使用这种方式,还是上面的1G的数据,查找只要10S钟即可完成,而且查找的结果也是很准确的。

在编写程序的过程中,可以使用GDAL的RasteIO函数,直接使用最后面的三个参数,可以直接将图像中的数据读取成OpenCV中的图像存储方式 BGRBGRBGR…

对于OpenCV在进行第一步匹配的时候,是在频率域中进行处理的,相关的函数也在OpenCV的源代码目录下的 modules/imgproc/src/templmatch.cpp 文件中,关于DFT变换(离散傅里叶变换)比较复杂,理论知识尤其是需要很好的数学功底才能够理解,感兴趣的童鞋可以google或者参考相关的数字图像处理的书籍,一般的数字图像处理的书籍中都会有的,因为DFT和FFT在数字图像处理以及信号处理方面使用的非常广泛。

Technorati 标签: OpenCV,模板匹配

关于遥感图像的控制点片匹配算法的一点想法(二)相关推荐

  1. 关于遥感图像的控制点片匹配算法的一点想法(一)

    在遥感图像的几何纠正过程中,可能会用到控制点库的点片自动匹配.关于控制点片匹配的算法有很多种,从最基本的分类可以分为基于像元的点片匹配和基于特征的点片匹配,由于基于特征的算法难度较大,一般使用的都是基 ...

  2. 自主开发的遥感图像数据处理系统

    功能包括: 遥感图像的控制点数据库管理,入库.检索.查找等 基于航空影像的三维地形重建,生成DEM.DOM数据 可见光.SAR.红外图像,相互之间的配准.融合 序列图像(可见光.红外)的配准镶嵌 基本 ...

  3. 【论文阅读】SCAttNet:具有空间和通道注意机制的高分辨率遥感图像语义分割网络

    [论文阅读]SCAttNet:具有空间和通道注意机制的高分辨率遥感图像语义分割网络 文章目录 [论文阅读]SCAttNet:具有空间和通道注意机制的高分辨率遥感图像语义分割网络 一.总体介绍 二.概述 ...

  4. 学习笔记-基于全局和局部对比自监督学习的高分辨率遥感图像语义分割-day2

    高分辨率遥感图像语义分割-day2 摘要 一.引言 二.方法 2.1 对比学习 2.2 全局风格与局部匹配对比学习网络(GLCNet) 2.2.1 全局风格对比学习模块: 2.2.2局部匹配对比学习: ...

  5. erdas遥感图像几何校正_定量/高光谱遥感之—光谱分析技术

    文章转载自微信公众号CSDN,作者冰清-小魔鱼,版权归原作者及刊载媒体所有. 在定量遥感或者高光谱遥感中,信息提取主要用到光谱/波谱分析技术.本专题对光谱/波谱分析中涉及的流程及一些技术进行讲解,包括 ...

  6. QT中使用GDAL多线程读取遥感图像到QImage

    GDAL 是一个很强大的可以读取很多格式 的带有GIS信息的栅格型图像.前阵子项目中需要读取遥感图像,并显示到QT界面,由于遥感图像一般很大,所以采取新开一个读图线程的方式来读取,防止界面假死.下面是 ...

  7. Arcgis软件应用(五)遥感图像地理配准、矢量化与地图制作

    目的: 将遥感图像进行地理配准.矢量化,并且制作地图. 要求: 对的遥感图像进行地理配准: 矢量化建筑物.绿地.道路.水体等主要地物要素: 对各类地物要素进行符号化设置并对其名称进行标注: 添加指北针 ...

  8. 高光谱遥感图像相关知识梳理大全

    前言 ​ 本资料整理了高光谱遥感图像概念定义.分析处理与分类识别的基本知识.第一部分介绍高光谱图像的一般性原理和知识,第二部分介绍了高光谱图像的噪声问题:第三部分介绍高光谱图像数据冗余问题以及数据降维 ...

  9. erdas几何校正_ERDAS遥感图像的几何校正

    1 实习二 遥感图像的几何校正 一.目的和要求 1 .了解图像几何校正的基本含义 2 .掌握图像几何校正的方法和过程 二.实习内容 这里的几何校正实质上的含义是将图像数据投影到平面上, 使其符合地图投 ...

最新文章

  1. 灭霸来了!微软发布BugLab:无需标注,GAN掉bug
  2. 深入剖析Vue源码 - 响应式系统构建(上)
  3. NLP的神经网络训练的新模式
  4. 转载:Android开发相关的Blog推荐——跟随大神的脚步才能成长为大神
  5. linux 环境变量设置错误导致 command not found
  6. linux下slow,慢查询日志的分析工具mysqlsla的使用
  7. 5. 直接三角形分解法
  8. python12_Python 12 基础知识
  9. ad09只在一定范围内查找相似对象_重磅!Excel更新了超级查找函数XLOOKUP,可以对VLOOKUP说拜拜了...
  10. 计算机图形学完整笔记(七):曲线曲面 - 1
  11. opencv 安装及配置
  12. 高频交易揭:美国五大高频易访录
  13. matlab绘制符号函数的ezplot函数
  14. 在线编辑Word——插入公式
  15. Sketch 使用快捷键记录
  16. Trafodion之DTM介绍
  17. 关于while循环终止循环的三种方式
  18. 2019年 电赛C题 全国大学生电子设计竞赛试题解析与总结
  19. 介绍一种冷门但简单的双拼方案——紫光双拼
  20. 什么是大数据开发?大数据开发要学什么?一个Java转行过程和经历

热门文章

  1. java 小数 乘法_javascript(js)的小数点乘法除法-Java架构师必看
  2. 天下谁人不识君:awt如何使用弹窗功能?
  3. git 小乌龟 TortoiseGit 记住账号密码
  4. JavaScript:堆栈溢出内存泄漏
  5. TypeScript学习(五):数组的定义方式及常见数组操作方法使用
  6. yii2 提供接口给java_Yii2 基于RESTful架构的 advanced版API接口开发 配置、实现、测试 (转)...
  7. OpenCV Laplacian 拉普拉斯变换
  8. 一次性搞懂JavaScript 执行机制
  9. Media Session API 为当前正在播放的视频,音频,提供元数据来自定义媒体通知
  10. Linux命令解释之find