void CtestDoc::OnTemplatematching()
{
// TODO: 在此添加命令处理程序代码
CFileDialog Dlg(TRUE, NULL, NULL, OFN_OVERWRITEPROMPT, NULL, NULL);//第一步读取模板图像A,为了简便表示算法,
//该程序只以灰度图像打开,彩色三个通道原理类似
Dlg.DoModal();
CString FN = Dlg.GetPathName();
std::string s((LPCTSTR)FN);
Mat A = imread(s, CV_LOAD_IMAGE_GRAYSCALE);
//如果图片打开失败就报错
if (A.empty())
{
std::cout << "read image failure" << std::endl;
}
imshow("A", A);
CFileDialog Dlg2(TRUE, NULL, NULL, OFN_OVERWRITEPROMPT, NULL, NULL);//第二步读取需要匹配的图片B
Dlg2.DoModal();
CString FN2 = Dlg2.GetPathName();
std::string s2((LPCTSTR)FN2);
Mat B = imread(s2, CV_LOAD_IMAGE_GRAYSCALE);
//如果图片打开失败就报错
if (B.empty())
{
std::cout << "read image failure" << std::endl;
}
imshow("B", B);
waitKey(0);
Mat result(B.rows - A.rows +1, B.cols - A.cols +1, CV_16UC3);//建立一个空矩阵用来存储计算的数据
for (int x = 0; x < result.rows; x++){ //计算过程
for (int y = 0; y < result.cols; y++){
double s = 0;
for (int m = 0; m < A.rows; m++){
for (int n = 0; n < A.cols+1; n++){
s += abs(A.at<Vec3b>(m, n)[0] - B.at<Vec3b>(x + m, y + n)[0]);
}
}
result.at<Vec3b>(x, y)[0] = s;
}
}
对了忘说了是在循环体里崩溃的
那个啥。这是图像处理软件吗
在A.at(m, n)[0]和B.at(x + m, y + n)[0]出错的,Mat构造时先输入行数再输入列数,但是访问像素时使用的是纵坐标正方向朝下的xy坐标系,即你程序(m,n)中m代表第m列,n代表第n行,你的循环边界行列设反了。
还有你的矩阵用的数据格式是CV_16UC3,是3通道unsigned short类型,Vec3b访问的是3通道uchar类型,会出错的。