opencv–相关系数法影像匹配

参考博客(5条消息) opencv–相关系数法影像匹配(数字摄影测量)_qiulanz的博客-CSDN博客_相关系数影像匹配

参考的代码分成了3部分,将3部分代码整合并且由于使用的opencv编译版本不一样,部分opencv自带的函数使用不一样

ZQLImgPro.h
#pragma once
#include"opencv2\core\core.hpp"
using namespace cv;
class CZQLImgPro
{
public:
  CZQLImgPro(void);
  ~CZQLImgPro(void);
  CZQLImgPro(int n_windowsize,float d_sigma);//构造函数重载(设置高斯滤波参数)
  CZQLImgPro(int i_binaryT);                //构造函数重载(设置阈值分割参数)
private:
int nwindowsize; //高斯滤波器的大小
float sigma;     //高斯滤波器方差
Mat Gauss;       //高斯滤波器
int binaryT;     //二值化阈值
private:
void CreatGauss();                               //生成高斯滤波器
public:
void setGauss(int n_windowsize,float d_sigma);   //设置高斯滤波参数
void setBinaryT(int i_binaryT);                  //设置二值化阈值
void BinaryImg(const Mat srcimg,Mat &result);    //阈值分割函数
void Gaussianfilter(const Mat srcimg,Mat &result);//高斯滤波
};

ZQLImgPro.cpp
#include"ZQLImgPro.h"
#include"math.h"
const float PI=4.0*atan(1.0);

//默认构造函数
CZQLImgPro::CZQLImgPro(void)
{
    nwindowsize=0;
    sigma=0;
    Gauss.create(nwindowsize,nwindowsize,CV_32F);
}
//析构函数
CZQLImgPro::~CZQLImgPro(void)
{
}
//构造函数重载(设置高斯滤波参数)
CZQLImgPro::CZQLImgPro(int n_windowsize,float d_sigma)
{
    nwindowsize=n_windowsize;
    sigma=d_sigma;
    Gauss.create(nwindowsize,nwindowsize,CV_32F);
}
//构造函数重载(设置阈值分割参数)
CZQLImgPro::CZQLImgPro(int iBinaryT)
{
    binaryT=iBinaryT;
}
//设置高斯滤波参数
void CZQLImgPro::setGauss(int n_windowsize,float d_sigma)
{
    nwindowsize=n_windowsize;
    sigma=d_sigma;
    Gauss.create(nwindowsize,nwindowsize,CV_32F);
}
//设置二值化阈值
void CZQLImgPro::setBinaryT(int iBinaryT)
{
    binaryT=iBinaryT;
}
//阈值分割函数
void CZQLImgPro::BinaryImg(const Mat srcimg,Mat&result)
{
    //给目标影像分配内存
    result.create(srcimg.rows,srcimg.cols,srcimg.type());
    for (int i=0;i(i,j);
            if (graytmp>binaryT) //大于阈值赋予255否则赋予0
                result.at(i,j)=255;
            else
                result.at(i,j)=0;
        }
    }
}
//生成高斯滤波器
void CZQLImgPro::CreatGauss()
{
    float sum=0;
    for(int i=0;i(i,j)=exp(-(x*x+y*y)/(2*sigma*sigma))
                    /(2*PI*sigma*sigma);//利用高斯公式计算计算滤波器

            //float m=exp(-(x*x+y*y)/(2*sigma*sigma));
            //float q=Gauss.at(i,j);
            sum+=Gauss.at(i,j);
        }
    }

    //进行归一化处理
    for(int i=0;i(i,j)/=sum;
        }
    }
}

//高斯滤波
void CZQLImgPro::Gaussianfilter(const Mat srcimg,Mat&result)
{
    CreatGauss();//计算高斯滤波器
    //给目标影像分配内存
    result.create(srcimg.rows,srcimg.cols,srcimg.type());
    int rows=srcimg.rows;
    int cols=srcimg.cols;
    for (int i=0;i(i,j)=0;
            //将结果矩阵初始化为零矩阵
        }
    }
    int nhalfw=nwindowsize/2;
    int sum=0;
    for (int i=nhalfw;i(m+nhalfw,n+nhalfw)*srcimg.at(i+m,j+n);
                    //利用高斯滤波器进行卷积
                }
            }
            result.at(i,j)=sum;
        }
    }
}
CMoravec.h
#pragma once
#include "opencv2\highgui\highgui.hpp"
using namespace cv;

class CMoravec
{
public:
  CMoravec(void);
  ~CMoravec(void);
  Mat Interest;         //兴趣值矩阵
  int IVwindowsize;     //兴趣值计算窗口大小
  int NMSwindowsize;    //抑制局部非最大窗口大小
  int intvalueT;        //兴趣阈值
  int FeatureNum;       //特征点个数
private:
  void InterestValue(const Mat srcimg);   //计算兴趣值
  void CandidatePoint();                  //选择候选点
  void FeaturePoint ();                   //抑制局部非最大
  void Mark (Mat &dstimg);                //标记特征点
public:
  void Moravec(const Mat srcimg,Mat &dstimg,Mat Interest);// Moravec算法主函数
};
CMoravec.cpp
#include
#include "Moravec.h"
#include "ZQLImgPro.h"

CMoravec::CMoravec(void)
{
    IVwindowsize=5;
    NMSwindowsize=5;
    intvalueT=200;
}
CMoravec::~CMoravec(void)
{

}

//计算兴趣值
void CMoravec::InterestValue(const Mat srcimg)
{
    Interest.create(srcimg.rows,srcimg.cols,CV_32S);
    int rows=srcimg.rows;
    int cols=srcimg.cols;
    for (int i=0;i(i,j)=0;
            //将兴趣值矩阵初始化为零矩阵
        }
    }
    int k=int(IVwindowsize/2);
    for (int r=k;r(r,c+i)-srcimg.at(r,c+i+1))*
                        (srcimg.at(r,c+i)-srcimg.at(r,c+i+1));
                v2+=(srcimg.at(r+i,c+i)-srcimg.at(r+i+1,c+i+1))*
                        (srcimg.at(r+i,c+i)-srcimg.at(r+i+1,c+i+1));
                v3+=(srcimg.at(r+i,c)-srcimg.at(r+i+1,c))*
                        (srcimg.at(r+i,c)-srcimg.at(r+i+1,c));
                v4+=(srcimg.at(r-i,c+i)-srcimg.at(r-i-1,c+i+1))*
                        (srcimg.at(r-i,c+i)-srcimg.at(r-i-1,c+i+1));
            }
            Interest.at(r,c)=min(min(min(v1,v2),v3),v4);
            //取v1,v2,v3,v4中的最小值作为兴趣值
        }
    }
}
//选择候选点
void CMoravec::CandidatePoint()
{
    for (int i=0;i(i,j)(i,j)=0;
        }
    }
}
//抑制局部非最大
void CMoravec::FeaturePoint()
{
    int halfw=NMSwindowsize/2;
    for (int i=halfw;i(i,j)(i+m,j+n))
                        Interest.at(i,j)=0;
                }
            }
        }
    }
}
//标记特征点
void CMoravec::Mark(Mat &dstimg)
{
    FILE *fp=fopen("result.txt","w");
    if (fp == NULL)
    {
        return;
    }
    fprintf(fp,"%s\t%s\n","像素位置","兴趣值");

    for (int i=3;i(i,j)!=0)
            {
                circle(dstimg,Point(j,i),1,Scalar(0,0,255),-1);
                //将特征点标记为实心点
                fprintf(fp,"(%1i,\t%1i)\t%1i\n",i,j,Interest.at(i,j));
                //
                FeatureNum++;
            }
        }
    }
    fclose(fp);
    //显示影像
    //imshow(_T("结果影像"),dstimg);
    //waitKey();
}
void CMoravec::Moravec(const Mat srcimg, Mat &dst, Mat Gauss)
{
    CZQLImgPro CIP(3,1.5);
    CIP.Gaussianfilter(srcimg,Gauss);// 高斯滤波
    InterestValue(Gauss);
    CandidatePoint();
    FeaturePoint();
    Mark(dst);
}

FeatureMatch.h

//FeatureMatch.h:头文件
#pragma once
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/core/core.hpp"
#include "Moravec.h"
using namespace cv;

struct MatchPt2i//同名点结构体
{
  Point2i lpt;//左核线影像上的点
  Point2i rpt;//右核线影像上的点
};

class CFeatureMatch
{
public:
  CFeatureMatch(void);
  ~CFeatureMatch(void);
private:
  Mat LeftImgEpi;  //左核线影像
  Mat RightImgEpi; //右核线影像
  int windowsize;  //模板窗口的大小
  double Threshold;//相关系数的阈值
  int num;         //匹配同名点个数
  MatchPt2i *Mpt2i;//同名点结构体数组
private:
  double NCCScore(int lr,int lc,int rr,int rc);//计算相关系数
  void showresult(const Mat LeftImgColor,const Mat RightImgColor,Mat &ResultImg);//给结果影像分配内存
public:
  void FeatureMatchMain(Mat LeftImg,Mat RightImg,Mat LeftImgColor,Mat RightImgColor);//影像匹配主函数
};

FeatureMatch.cpp

//FeatureMatch.cpp:实现文件
#include
#include
#include "FeatureMatch.h"
#include "math.h"

CFeatureMatch::CFeatureMatch(void)
{
    windowsize=11;
    Threshold=0.7;
    Mpt2i=NULL;
    num=0;
}

CFeatureMatch::~CFeatureMatch(void)
{
}
void CFeatureMatch::showresult(const Mat LeftImgColor,const Mat RightImgColor,Mat &ResultImg)
{
    ResultImg.create(2*LeftImgColor.rows,LeftImgColor.cols,LeftImgColor.type());
    for (int i=0;i(i,j)=LeftImgColor.at(i,j);
        }
    }
    for (int i=0;i(i+LeftImgColor.rows,j)=RightImgColor.at(i,j);
        }
    }
}
double CFeatureMatch::NCCScore(int lr,int lc,int rr,int rc)
{
    double gLeftAverage=0;//左影像窗口灰度平均值
    double gRightAverage=0;//右影像窗口灰度平均值
    int halfsize=windowsize/2;
    for (int i=-halfsize;i(lr+i,lc+j);
            gRightAverage+=RightImgEpi.at(rr+i,rc+j);
        }
    }
    gLeftAverage/=windowsize*windowsize;
    gRightAverage/=windowsize*windowsize;
    double a=0;
    double b=0;
    double c=0;
    for (int i=-halfsize;i(lr+i,lc+j)-gLeftAverage;
            double right_av=RightImgEpi.at(rr+i,rc+j)-gRightAverage;
            a+=left_av*right_av;
            b+=left_av*left_av;
            c+=right_av*right_av;
        }
    }
    return a/sqrt(b*c);//返回相关系数的大小
}
void CFeatureMatch::FeatureMatchMain(Mat LeftImg,Mat RightImg,Mat LeftImgColor,Mat RightImgColor)
{
    LeftImgEpi=LeftImg;
    RightImgEpi=RightImg;
    Mat Result;
    showresult(LeftImgColor,RightImgColor,Result);//将两张彩色影像和合并1个
    CMoravec CM;
    CM.Moravec(LeftImgEpi,LeftImgColor,CM.Interest);//Moravec特征提取
    Mpt2i=new struct MatchPt2i[CM.FeatureNum];//给同名点结构体数组分配内存空间
    int halfsize=windowsize/2;
    //搜索匹配点
    for (int i=halfsize;i(i,j)!=0)
                //特征点作为模板中心
            {
                 double maxscore=0;
                for (int c=j-530;cmaxscore)
                    {
                        maxscore=score;//计算相关系数的最大值
                    }
                }

                for (int c=j-530;cThreshold))
                    {
                        //用直线连接同名点
                        line(Result,Point(j,i),Point(c,i+RightImgEpi.rows),Scalar(0,0,255));
                        //将匹配结果存入数组
                        Mpt2i[num].lpt=Point(j,i);
                        Mpt2i[num].rpt=Point(c,i);
                        num+=1;
                    }
                }
            }
        }
    }
    imwrite("result.jpg",Result);
    //将匹配结果写入文件
    FILE *fp=fopen("match_point.txt","w");
    if (fp == NULL)
    {
        return;
    }
    fprintf(fp,"%1i\n",num);
    for (int i=0;i主函数就随手写了一个#include
#include
#include "FeatureMatch.h"
using namespace std;
using namespace cv;

int main()
{
    Mat LeftImg = imread("D:\\exam_jpg\\uavl.jpg",0);
    Mat RightImg = imread("D:\\exam_jpg\\uavr.jpg",0);
    Mat LeftImgColor = imread("D:\\exam_jpg\\uavr.jpg",1);
    Mat RightImgColor = imread("D:\\exam_jpg\\uavr.jpg",1);
    CFeatureMatch CFM;
    CFM.FeatureMatchMain(LeftImg,RightImg,LeftImgColor,RightImgColor);
    return 0;
}

Original: https://blog.csdn.net/rjswsq1998/article/details/121847527
Author: rjswsq1998
Title: opencv–相关系数法影像匹配

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/704084/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球