1 以灰度的形式读入两副核线影像
2 读入左影像提取的特征点
3 沿核线在右影像上计算每个候选匹配点的相关系数值
4 取极值点以及NCC大于阈值的点作为同名点
5 输出同名点到文件中,将同名点画到影像上,并用直线连接同名点。
按钮ID | CADPTION | 对应函数 |
---|---|---|
IDOK | 打开并显示灰度图像 | OnBnClickedOk() |
IDC_read2 | 二值化图像 | OnBnClickedread2() |
IDC_read3 | Guass滤波/opencv的Guass滤波图像 | OnBnClickedread3() |
IDC_read5 | Moravec算子 | OnBnClickedread5() |
IDC_read6 | 相关系数法匹配 | OnBnClickedread6() |
IDC_read4 | 帮助 | OnBnClickedread4() |
IDCANCEL | 取消 |
编辑框ID | 变量名 | 变量类型 |
---|---|---|
IDC_Moravecsize1 | Moravecsize1 | int |
IDC_Moravecsize2 | Moravecsize2 | int |
IDC_Moraveclowestdoor | Moraveclowstdoor | int |
IDC_dist_width | dist_width | int |
IDC_lowst_door | lowst_door | float |
IDC_halflengthsize | halflengthsize | int |
按钮ID | CADPTION | 对应函数 |
---|---|---|
ID_readleft | 打开左影像 | OnBnClickedreadleft() |
ID_readright | 打开右影像 | OnBnClickedreadright() |
ID_view2 | 左侧Moravec算子输出至txt中 | OnBnClickedview() |
ID_view | 读取txt显示 | OnBnClickedview2() |
IDC_BUTTON1 | ? | OnBnClickedButton1() |
IDCANCEL | 取消 |
这里仅展示涉及到相关系数法相关功能的代码。
/***************************************************************************
类:CMatchingImg
作用:核线影像相关系数计算类
Welcome to my Github and my CSDN blog , more information will be available about the project!
Github:https://github.com/Yiqingde
CSDN Blog:https://me.csdn.net/weixin_42348202
历史:**日期** **理由** **签名**
2019年10月11日 创建 ***
/**************************************************************************/
#pragma once
#include "zrxCFeatureVector.h"
class CMatchingImg
{
public:
CMatchingImg();
~CMatchingImg();
int Div(const CString strLine, char split, CStringArray &strArray);//字符串分割函数
void lastview(Mat match_LImg, Mat match_RImg, vector<Point3f> f, vector<Point3f> r);//最后显示
void Get_coefficient(Mat Lmatchwindow, Mat match_RImg, int x, int y, float &cofficent);//求相关系数
bool read(vector < Point3f> &f);//读取txt到vector
void vectorsort(vector < Point3f> &Temp_sort);//排序
void MatchingImg(Mat &match_LImg, Mat &match_RImg, Mat match_RGBLImg, Mat match_RGBRImg, float lowst_door, int dist_width, int halflengthsize);//主函数
};
#include "stdafx.h"
#include "CMatchingImg.h"
CMatchingImg::CMatchingImg()
{
}
CMatchingImg::~CMatchingImg()
{
}
//***********************************
//字符分割函数
//***********************************
int CMatchingImg::Div(const CString strLine, char split, CStringArray &strArray)
{
strArray.RemoveAll();//自带清空属性
CString temp = strLine;
int tag = 0;
while (1)
{
tag = temp.Find(split);
if (tag >= 0)
{
strArray.Add(temp.Left(tag));
temp = temp.Right(temp.GetLength() - tag - 1);
}
else { break; }
}
strArray.Add(temp);
return strArray.GetSize();
}
/***************************************************************************
函数:read(vector < Point3i> &f)
作用:读取txt文件,储存至vector中
参数:无
返回值:无
历史:**日期** **理由** **签名**
2019年10月11日 创建 ***
/**************************************************************************/
bool CMatchingImg::read(vector < Point3f> &f)
{
CFileDialog dlgFile(TRUE, _T("txt"), NULL,
OFN_ALLOWMULTISELECT | OFN_EXPLORER,
//_T("(文本文件)|*.txt"));
_T(""));
if (dlgFile.DoModal() == IDCANCEL) return 0;
CString strName = dlgFile.GetPathName();//获取打开文件文件名(路径)
setlocale(LC_ALL, "");
CStdioFile sf;
if (!sf.Open(strName, CFile::modeRead)) return 0;//打开strName文件路径中的内容
CString strLine;
CString strContent;//接受内容字符串
CStringArray array;//供下文分割使用
strContent.Empty();//strContent中内容清空
//开始读数据
BOOL bEOF = sf.ReadString(strLine);//第一行
if (bEOF == 0) { AfxMessageBox(_T("空数据")); return 0; }
//读取控制点
bEOF = sf.ReadString(strLine);//第二行
if (bEOF == 0) { AfxMessageBox(_T("数据不规范")); return 0; }
bEOF = sf.ReadString(strLine);//第三行
if (bEOF == 0) { AfxMessageBox(_T("数据不规范")); return 0; }
int n = Div(strLine, ':', array);
if (n < 2) { AfxMessageBox(_T("数据缺失")); return 0; }
int i = _ttoi(array[1]);
bEOF = sf.ReadString(strLine);//第四行
if (bEOF == 0) { AfxMessageBox(_T("数据不规范")); return 0; }
while (i>0)
{
bEOF = sf.ReadString(strLine);
if (bEOF == 0) { AfxMessageBox(_T("数据不规范")); return 0; }
int n = Div(strLine, ',', array);
if (n < 3) { AfxMessageBox(_T("数据缺失")); return 0; }
Point3f temp;
temp.x = _ttoi(array[0]);
temp.y = _ttoi(array[1]);
temp.z = _ttoi(array[2]);
f.push_back(temp);
i--;
}
return 1;
}
/***************************************************************************
函数:Get_coefficient(Mat Lmatchwindow, Mat match_RImg,int x,int y,float &cofficent)
作用:计算相关系数
参数:Mat Lmatchwindow已经计算过的左片窗口
Mat match_RImg 右核线影像
int x 坐标值x
int y 坐标值y
float &cofficent用来返回计算过的单个值
返回值:无
历史:**日期** **理由** **签名**
2019年10月11日 创建 ***
/**************************************************************************/
void CMatchingImg::Get_coefficient(Mat Lmatchwindow, Mat match_RImg,int x,int y,float &cofficent)
{
//根据左搜索窗口确定右搜索窗口的大小
Mat Rmatchwindow;
Rmatchwindow.create(Lmatchwindow.rows, Lmatchwindow.cols, CV_32FC1);
float aveRImg = 0;
for (int m = 0; m < Lmatchwindow.rows; m++)
{
for (int n = 0; n < Lmatchwindow.cols; n++)
{
aveRImg += match_RImg.at<uchar>(x + m, y + n);
Rmatchwindow.at<float>(m, n) = match_RImg.at<uchar>(x + m, y + n);
}
}
aveRImg = aveRImg / (Lmatchwindow.rows*Lmatchwindow.cols);
for (int m = 0; m < Lmatchwindow.rows; m++)
{
for (int n = 0; n < Lmatchwindow.cols; n++)
{
Rmatchwindow.at<float>(m, n) -= aveRImg;
}
}
//开始计算相关系数
float cofficent1=0;
float cofficent2=0;
float cofficent3=0;
for (int m = 0; m < Lmatchwindow.rows; m++)
{
for (int n = 0; n < Lmatchwindow.cols; n++)
{
cofficent1 += Lmatchwindow.at<float>(m, n)*Rmatchwindow.at<float>(m, n);
cofficent2 += Rmatchwindow.at<float>(m, n)*Rmatchwindow.at<float>(m, n);
cofficent3 += Lmatchwindow.at<float>(m, n)*Lmatchwindow.at<float>(m, n);
}
}
cofficent = cofficent1 / sqrt(cofficent2 * cofficent3);
}
/***************************************************************************
函数:vectorsort(vector < Point3f> &Temp_sort)
作用:仅适用于对vector < Point3f> &Temp_sort的z元素冒泡排序,xyz作为一个整体进行改变,首元素值最大
参数:vector < Point3f> &Temp_sort 需要排序的vector
返回值:无
历史:**日期** **理由** **签名**
2019年10月11日 创建 ***
/**************************************************************************/
void CMatchingImg::vectorsort(vector < Point3f> &Temp_sort)
{
for (int i = 0; i < Temp_sort.size() - 1; i++) {
float tem = 0;
float temx = 0;
float temy = 0;
// 内层for循环控制相邻的两个元素进行比较
for (int j = i + 1; j < Temp_sort.size(); j++) {
if (Temp_sort.at(i).z < Temp_sort.at(j).z) {
tem = Temp_sort.at(j).z;
Temp_sort.at(j).z = Temp_sort.at(i).z;
Temp_sort.at(i).z = tem;
temx = Temp_sort.at(j).x;
Temp_sort.at(j).x = Temp_sort.at(i).x;
Temp_sort.at(i).x = temx;
temy = Temp_sort.at(j).y;
Temp_sort.at(j).y = Temp_sort.at(i).y;
Temp_sort.at(i).y = temy;
}
}
}
}
/***************************************************************************
函数:lastview(Mat match_LImg, Mat match_RImg,vector f,vector r)
作用:最后用来显示图像并进行写入工作路径的txt中
参数:Mat match_LImg 左核线影像
Mat match_RImg 右核线影像
vector f 存储经过筛选过后的moravec元素
vector r 存储在右片所寻找到的相应元素,与vector f相对应
返回值:无
历史:**日期** **理由** **签名**
2019年10月11日 创建 ***
/**************************************************************************/
void CMatchingImg::lastview(Mat match_LImg, Mat match_RImg,vector<Point3f> f,vector<Point3f> r)
{
Mat bothview;//输出图像
bothview.create(2 * match_LImg.rows, match_LImg.cols, match_LImg.type());
for (int i = 0; i < match_LImg.rows; i++)
{
for (int j = 0; j < match_LImg.cols; j++)
{
bothview.at<Vec3b>(i, j) = match_LImg.at<Vec3b>(i, j);
}
}
for (int i = match_LImg.rows; i < 2 * match_LImg.rows; i++)
{
for (int j = 0; j < match_LImg.cols; j++)
{
bothview.at<Vec3b>(i, j) = match_RImg.at<Vec3b>(i - match_LImg.rows, j);
}
}//左右影像合二为一
for (int i = 0; i < r.size(); i++)
{
int a = (rand() % 200);
int b = (rand() % 200 + 99);
int c = (rand() % 200) - 5
0;
if (a > 100 || a < 0)
{
a = 255;
}
if (b > 255 || b < 0)
{
b = 88;
}
if (c > 255 || c < 0)
{
c = 188;
}
line(bothview, Point(f.at(i).y,f.at(i).x), Point(r.at(i).y, r.at(i).x + match_LImg.rows ), Scalar(a, b, c),2);
}
//输出至txt中
CStdioFile SF;
CString strLine;
CString strOut;
setlocale(LC_ALL, "");
if (!SF.Open(_T("相关系数法5元素.txt"), CFile::modeCreate | CFile::modeWrite)) return;
strLine.Format(_T("%d\n"),r.size());
strOut += strLine;
for (int i = 0; i < r.size(); i++)
{
strLine.Format(_T("%.f %.f %.f %.f\n"), f.at(i).y, f.at(i).x, r.at(i).y, r.at(i).x );
strOut += strLine;
}
SF.WriteString(strOut);
SF.Close();
AfxMessageBox(_T("成功!已输入至“相关系数法5元素.txt”中(在MFC工作路径)"));
imshow("左右片影像相关系数法点位展示", bothview);
//waitKey();
imwrite("左右片影像相关系数法点位展示.jpg", bothview);
}
/***************************************************************************
函数:MatchingImg(Mat &match_LImg, Mat &match_RImg , Mat match_RGBLImg, Mat match_RGBRImg, float lowst_door, int dist_width,int halflengthsize)
作用:相关系数法主函数,调用其上函数
参数:Mat match_LImg 左核线影像
Mat match_RImg 右核线影像
Mat match_RGBLImg 左片彩色影像
Mat match_RGBRImg 右片彩色影像
float lowst_door 相关系数法阈值
int dist_width 规定一个左片与右片的相对距离
int halflengthsize 规定以该像素为中心的x轴的搜索半径
返回值:无
历史:**日期** **理由** **签名**
2019年10月11日 创建 ***
/**************************************************************************/
void CMatchingImg::MatchingImg(Mat &match_LImg, Mat &match_RImg , Mat match_RGBLImg, Mat match_RGBRImg, float lowst_door, int dist_width,int halflengthsize)
{
if (match_LImg.empty()) { AfxMessageBox(_T("请检查是否读入左核线影像")); return; }
if (match_RImg.empty()) { AfxMessageBox(_T("请检查是否读入右核线影像")); return; }
int matchsize=9;//相关系数的正方形窗口的边长
int half_matchsize = matchsize / 2;//边长的一半
//调用之前函数,将点位信息存储值f中
vector<Point3f> f;//用来读取左片moravec算子的数据
vector<Point3f> r;//用来写右片匹配到的数据
int r_i = 0;
bool tag=read(f);//运行读取函数
//创建左窗口的小窗口
Mat Lmatchwindow;
Lmatchwindow.create(matchsize, matchsize, CV_32FC1);
//进行f数据的预处理 删除不符合规范的数据
for (size_t i = 0; i < f.size(); i++)
{
//*************************进行两次擦除
//***********擦除y值不在影像范围内的点f 我·2
if (f.at(i).y < dist_width + halflengthsize + half_matchsize + 1)
{
f.erase(f.begin() + i);
i--;
continue;
}
//***********擦除x值不在影像范围内的点
if (f.at(i).x <half_matchsize +5|| f.at(i).x>match_LImg.rows-half_matchsize-10)
{
f.erase(f.begin() + i);
i--;
continue;
}
}
for (size_t i = 0; i < f.size(); i++)
{
//***************************对左窗口进行计算,计算完毕后值存入Lmatchwindow中
float aveLImg = 0;
for (int m =0; m <matchsize; m++)
{
for (int n = 0; n < matchsize; n++)
{
aveLImg += match_LImg.at<uchar>(f.at(i).x - half_matchsize + m, f.at(i).y - half_matchsize + n);
Lmatchwindow.at<float>(m, n) = match_LImg.at<uchar>(f.at(i).x - half_matchsize + m, f.at(i).y - half_matchsize + n);
}
}
aveLImg = aveLImg / (matchsize* matchsize);//求取左窗口平均值
//均除某个值
for (int m = 0; m < matchsize; m++)
{
for (int n = 0; n < matchsize; n++)
{
Lmatchwindow.at<float>(m, n) = Lmatchwindow.at<float>(m, n) - aveLImg;
}
}
//***************************对右窗口进行计算
//首先预估右窗口的位置
vector < Point3f> halflengthsize2;
//去除跑到窗口外的点
for (int ii = -halflengthsize; ii<=halflengthsize; ii++)
{
Point3f temphalflengthsize;
float coffee;
Get_coefficient(Lmatchwindow, match_RImg, f.at(i).x- half_matchsize, f.at(i).y - dist_width- half_matchsize + ii, coffee);
temphalflengthsize.x = f.at(i).x;
temphalflengthsize.y = f.at(i).y - dist_width + ii;
temphalflengthsize.z = coffee;
halflengthsize2.push_back(temphalflengthsize);
}
vectorsort(halflengthsize2);
//*************************进行第二次擦除
//***********擦除不符合相关系数不符合阈值的值
if (halflengthsize2.at(0).z > lowst_door&&halflengthsize2.at(0).z < 1)
{
Point3f tempr;
tempr.x = halflengthsize2.at(0).x;
tempr.y = halflengthsize2.at(0).y;
tempr.z = halflengthsize2.at(0).z;
r.push_back(tempr);
}
else
{
f.erase(f.begin() + i);
i--;
continue;
}
}
lastview(match_RGBLImg, match_RGBRImg,f,r);
}
#pragma once
/***************************************************************************
类:CBasic
作用:封装图像操作函数,仅储存按钮操作功能 调用相应其他图片处理类来完成图片操作
Welcome to my Github and my CSDN blog , more information will be available about the project!
Github:https://github.com/Yiqingde
CSDN Blog:https://me.csdn.net/weixin_42348202
历史:**日期** **理由** **签名**
2019年9月26日 创建 ***
/**************************************************************************/
#include "time.h"
#include "zrxCImgPro.h"
#include "CMatchingImg.h"
class CBasic
{
public:
CBasic();
~CBasic();
Mat m_srcimg;//原始灰度图像
Mat m_srcimgrgb;//RGB颜色的图像
bool tag;//鲁棒性
zrxCImgPro function1;//创建zrxCImgPro图像处理操作对象
zrxCFeatureVector function2;//创建zrxCFeatureVector图像处理操作对象
//Mat match_LImg_txt;//供制作左核线影像txt使用,是灰色的
//Mat match_RGBLImg_txt;//供制作左核线影像txt使用,是彩色的
Mat match_LImg;//存储左影像核线图像
Mat match_RImg;//存储右影像核线图像
Mat match_RGBLImg;//
Mat match_RGBRImg;//
public://********************************存储按钮功能函数
void OpenImg();//实现按钮功能,打开图像
void Button_binaryImg();//实现按钮功能,显示二值图像
void Button_GaussImg();//实现按钮功能,包括显示自写与opencv的gauss图像,并显示运行时间
void Button_Help(); //实现按钮功能,help
void Button_Moravec();//Moravec按钮
void Button_Imagematching_readleft();//读取左影像数据
void Button_Imagematching_readright();//读取右影像数据
void Button_Imagematching_makingNumber(int Moricsize, int Moravecsize2, int Moraveclowstdoor);//制作左片Moravec数据
void Button_Imagematching_view(float lowst_door, int dist_width, int halflengthsize);
};
#include "stdafx.h"
#include "CBasic.h"
CBasic::CBasic()
{
this->tag = 0;//鲁棒
}
CBasic::~CBasic()
{
}
/***************************************************************************
函数:OpenImg()
作用:实现按钮功能,打开图像并显示灰度图像,存储到 m_srcimg中; tag是标签、增加程序鲁棒性
参数:无
返回值:无
历史:**日期** **理由** **签名**
2019年9月20日 创建 ***
/**************************************************************************/
void CBasic::OpenImg()
{
CFileDialog FileDlg(TRUE, "*.jpg;*.bmp", "*.jpg;*.bmp", OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "影像文件()");
if (FileDlg.DoModal() != IDOK)
{
return;
}
CString strImgName = FileDlg.GetPathName();
//打开影像
m_srcimg = imread(strImgName.GetBuffer(), IMREAD_GRAYSCALE);//IMREAD_GRAYSCALE 以灰度形式打开
m_srcimgrgb = imread(strImgName.GetBuffer(), IMREAD_COLOR);//IMREAD_COLOR 以彩色形式打开
//resize(m_srcimg, m_srcimg, Size(m_srcimg.cols * 800 / m_srcimg.rows, 800), 0, 0, INTER_CUBIC);//自适应调整图像大小
//resize(m_srcimgrgb, m_srcimgrgb, Size(m_srcimgrgb.cols * 800 / m_srcimgrgb.rows, 800), 0, 0, INTER_CUBIC);//自适应调整图像大小
imshow("原始图像", m_srcimgrgb); //显示
tag = 1;
}
/***************************************************************************
函数:Button_binaryImg()
作用:实现按钮功能,显示二值图像
参数:无
返回值:无
历史:**日期** **理由** **签名**
2019年9月20日 创建 ***
/**************************************************************************/
void CBasic::Button_binaryImg()
{
if (tag == 0)
{
AfxMessageBox(_T("需首先打开影像才能进行操作!"));
return;
}
//二值化操作
Mat m_binary;
function1.BinaryImage(m_srcimg, 100, m_binary);
imshow("图像二值化结果", m_binary); //显示
waitKey();
}
/***************************************************************************
函数:Button_GaussImg()
作用:实现按钮功能,包括显示自写与opencv的gauss图像,并显示运行时间
参数:无
返回值:无
历史:**日期** **理由** **签名**
2019年9月20日 创建 ***
/**************************************************************************/
void CBasic::Button_GaussImg()
{
if (tag == 0)
{
AfxMessageBox(_T("需首先打开影像才能进行操作!"));
return;
}
Mat distImg;
clock_t start, finish;
double totaltime;
clock_t start1, finish1;
double totaltime1;
start = clock();
function1.Gaussianfilter(m_srcimg, 5, 1.0, distImg);
//namedWindow("ss", 1);
imshow("高斯滤波结果", distImg); //显示
finish = clock();
totaltime = (double)(finish - start) / CLOCKS_PER_SEC;
waitKey(100); //等待操作,将窗口关闭\回车\ESC等操作会运行以下的程序
//opencv自带高斯滤波
Mat dstImage;
start1 = clock();
GaussianBlur(m_srcimg, dstImage, Size(5, 5), 0, 0);
//显示效果图
imshow("opencv自带高斯滤波效果图", dstImage);
finish1 = clock();
totaltime1 = (double)(finish1 - start1) / CLOCKS_PER_SEC;
waitKey(3000);
CString runtime;
runtime.Format("%s%f%s\r\n%s%f%s",
_T("自写Gauss滤波运行时间:"),
totaltime,
_T("s"),
_T("opencvGauss滤波运行时间:"),
totaltime1,
_T("s")
);
AfxMessageBox(runtime);
}
/***************************************************************************
函数:Button_Help()
作用:实现按钮功能,help
参数:无
返回值:无
历史:**日期** **理由** **签名**
2019年9月20日 创建 ***
/**************************************************************************/
void CBasic::Button_Help()
{
CString help;
help.Format("%s\r\n%s\r\n%s\r\n%s\r\n\r\n%s\r\n%s\r\n%s\r\n", _T("感谢您使用本程序!提示:"), _T("需首先打开影像才能进行操作!"), _T("自写代码,Gauss滤波、Moravec、核线影像相关系数法匹配运行较慢,请耐心等待!"), _T("示例数据、示例结果在该MFC工作路径下!"),
_T("Welcome to my Github and my CSDN blog , more information will be available about the project!"),
_T("Github : https://github.com/Yiqingde"),
_T("CSDN Blog : https://me.csdn.net/weixin_42348202"));
AfxMessageBox(help);
}
/***************************************************************************
函数:Button_Moravec()
作用:实现按钮功能,Moravec
参数:无
返回值:无
历史:**日期** **理由** **签名**
2019年9月26日 创建 ***
/**************************************************************************/
void CBasic::Button_Moravec()
{
if (tag == 0)
{
AfxMessageBox(_T("需首先打开影像才能进行操作!"));
return;
}
Mat MoravecImg;
clock_t start, finish;
start = clock();
vector<Point3f> f;
function2.Moravec(m_srcimg, m_srcimgrgb,5,20,250,MoravecImg,f);//调用函数
finish = clock();
double totaltime = (double)(finish - start) / CLOCKS_PER_SEC;
CString runtime;
runtime.Format(_T("%s%4f%s\n"),_T("************************* Morevec算子运行时间:"), totaltime,_T("s *************************"));
imshow("Moravec单独显示", MoravecImg); //显示
waitKey();
imshow("Moravec彩色显示", m_srcimgrgb); //显示
function2.Reporttxt(runtime);//输出txt
imwrite("Moravec彩色显示.jpg", m_srcimgrgb);
}
/***************************************************************************
函数:Button_Imagematching_readleft()
作用:读取左影像数据,给match_LImg赋值
参数:无
返回值:无
历史:**日期** **理由** **签名**
2019年10月6日 创建 ***
/**************************************************************************/
void CBasic::Button_Imagematching_readleft()//读取左影像数据
{
CFileDialog FileDlg(TRUE, "*.jpg;*.bmp", "*.jpg;*.bmp", OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "影像文件()");
if (FileDlg.DoModal() != IDOK)
{
return;
}
CString strImgName = FileDlg.GetPathName();
//打开影像
match_LImg = imread(strImgName.GetBuffer(), IMREAD_GRAYSCALE);//IMREAD_GRAYSCALE 以灰度形式打开
//match_LImg_txt = imread(strImgName.GetBuffer(), IMREAD_GRAYSCALE);//IMREAD_GRAYSCALE 以灰度形式打开
match_RGBLImg = imread(strImgName.GetBuffer(), IMREAD_COLOR);//IMREAD_COLOR 以彩色形式打开
//match_RGBLImg_txt = imread(strImgName.GetBuffer(), IMREAD_COLOR);//IMREAD_COLOR 以彩色形式打开
}
/***************************************************************************
函数:Button_Imagematching_readright()
作用:读取右影像数据,给match_RImg赋值
参数:无
返回值:无
历史:**日期** **理由** **签名**
2019年10月6日 创建 ***
/**************************************************************************/
void CBasic::Button_Imagematching_readright()//读取左影像数据
{
CFileDialog FileDlg(TRUE, "*.jpg;*.bmp", "*.jpg;*.bmp", OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "影像文件()");
if (FileDlg.DoModal() != IDOK)
{
return;
}
CString strImgName = FileDlg.GetPathName();
//打开影像
match_RImg = imread(strImgName.GetBuffer(), IMREAD_GRAYSCALE);//IMREAD_GRAYSCALE 以灰度形式打开
match_RGBRImg = imread(strImgName.GetBuffer(), IMREAD_COLOR);//IMREAD_COLOR 以彩色形式打开
}
/***************************************************************************
函数:Button_Imagematching_makingNumber(int Moricsize, int Moravecsize2,int Moraveclowstdoor)
作用:制作训练数据
参数:int Moricsize moricsize参数
int Moravecsize2 moricsize参数
int Moraveclowstdoor moricsize参数
返回值:无
历史:**日期** **理由** **签名**
2019年10月6日 创建 ***
/**************************************************************************/
void CBasic::Button_Imagematching_makingNumber(int Moricsize, int Moravecsize2,int Moraveclowstdoor)
{
zrxCFeatureVector making_moravec_txt;
Mat tempImg;
vector<Point3f> txtf;
clock_t start, finish;
start = clock();
if (match_LImg.empty()) { AfxMessageBox(_T("请检查是否读入左核线影像")); return; }
if (match_RImg.empty()) { AfxMessageBox(_T("请检查是否读入右核线影像")); return; }
Mat match_LImg_txt= match_LImg.clone();//进行mat的复制
Mat match_RGBLImg_txt= match_RGBLImg.clone();//进行mat的复制
making_moravec_txt.Moravec(match_LImg_txt, match_RGBLImg_txt, Moricsize, Moravecsize2, Moraveclowstdoor,tempImg,txtf);
finish = clock();
double totaltime = (double)(finish - start) / CLOCKS_PER_SEC;
CString runtime;
runtime.Format(_T("%s%4f%s\n%s\n"), _T("************************* Morevec算子运行时间:"), totaltime, _T("s *************************"),_T("*************************影像存储至工作路径 左核线影像Moravec彩色显示.jpg 中 *************************"));
making_moravec_txt.Reporttxt(runtime);//输出txt
imwrite("左核线影像Moravec彩色显示.jpg", match_RGBLImg_txt);
}
void CBasic::Button_Imagematching_view(float lowst_door, int dist_width, int halflengthsize)
{
CMatchingImg No1;
No1.MatchingImg(match_LImg,match_RImg,match_RGBLImg, match_RGBRImg,lowst_door,dist_width,halflengthsize);
}
/*************************************************
按钮:相关系数法按钮窗口打开
*************************************************/
void CZRX0107170110Dlg::OnBnClickedread6()
{
// TODO: 在此添加控件通知处理程序代码
Imagematching a;
a.DoModal();
}
/***************************************************************************
类:Imagematching
作用:核线影像相关系数MFC界面按钮操作相关类
Welcome to my Github and my CSDN blog , more information will be available about the project!
Github:https://github.com/Yiqingde
CSDN Blog:https://me.csdn.net/weixin_42348202
历史:**日期** **理由** **签名**
2019年10月11日 创建 ***
/**************************************************************************/
CBasic temp;
//读取左影像按钮
void Imagematching::OnBnClickedreadleft()
{
// TODO: 在此添加控件通知处理程序代码
temp.Button_Imagematching_readleft();
}
//读取右影像按钮
void Imagematching::OnBnClickedreadright()
{
// TODO: 在此添加控件通知处理程序代码
temp.Button_Imagematching_readright();
}
//读取txt
void Imagematching::OnBnClickedview()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(true);
temp.Button_Imagematching_view(lowst_door, dist_width, halflengthsize);
UpdateData(false);
}
//制作txt
void Imagematching::OnBnClickedview2()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(true);
temp.Button_Imagematching_makingNumber(Moravecsize1, Moravecsize2, Moraveclowstdoor);
UpdateData(false);
}
//help
void Imagematching::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
CString help;
CString help;
help.Format(_T("%s\r\n%s\r\n%s\r\n\r\n%s"), _T("Moravec算子执行速度略慢请耐心等待"),
_T("如果您有txt标准格式数据的话,您可直接跳过该步骤,进行直接读取txt"), _T("工作路径下有: 标准数据1.txt 标准数据2.txt 标准数据3.txt可供直接读取"),_T("执行步骤:打开左影像-->打开右影像-->设置Moravec参数-->左侧Moravec算子输出到txt中-->设置核线影像参数-->读取输出的txt"));
AfxMessageBox(help);
}
1)获取的Moravec值存入txt和图像中:
Moravec窗口 | 局部抑制窗口大小 | Moravec阈值 |
---|---|---|
5 | 5 | 200 |
左片相对于右片右偏像素值 | 阈值(0.7~1) | 搜索半个窗口宽度 |
---|---|---|
500 | 0.9 | 30 |