模板匹配 -提高计算速度
误差平方和算法(SSD)
误差平方和算法(Sum of Squared Differences,简称SSD算法),也叫差方和算法。实际上,SSD算法与SAD算法如出一辙,只是其相似度测量公式有一点改动(计算的是子图与模板图的L2距离)。这里不再赘述。
模板匹配的速率如何提高?
先说说模板匹配的优势,精度高。但是计算量是特别大 以此项目为例 单次匹配 12ms
那么总共计算时间就是 10ms* 200(rows)*600(cols),20分钟往上。12ms的单次循环很难继续优化。
1.常用的方法 将图像 没9个色块再分为一个像素 这样 你的计算速度就能优化9倍。
2.其他方法,GPU加速,CPU加速(多核电脑下的多线程);
我采取了一个特别实用的办法,看着,秀操作的时候到了
学会了吗? 20min/10/10 = 12S ,不得不说,相当实用啊。
那么想继续提高精度,知道怎么办了吗?你可以以此基础下进行扩容,就是一目前锁定的这个点寻找周围的 20个像素,寻找最匹配的那个像素点。6不6。随便写点感悟
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <math.h>
#include <opencv.hpp>
using namespace std;
using namespace cv;
int main(int argc, const char* argv[]) {
//模板原图
cv::Mat ScrImg = cv::imread("B.jpg", cv::IMREAD_GRAYSCALE);
int Srows = ScrImg.rows;
int Scols = ScrImg.cols;
int Sdepth = ScrImg.channels();
//匹配图
cv::Mat TargitImg = cv::imread("B_.jpg", cv::IMREAD_GRAYSCALE);
int Trows = TargitImg.rows;
int Tcols = TargitImg.cols;
int Tchanel = TargitImg.channels();
int endR = Srows - Trows;
int endC = Scols - Tcols;
int ChanelNum = Sdepth;
int Squarediff = 255* Trows* Trows*Tcols* Tcols*3;
int outr=0, outc=0;
for (int starR = 0; starR < endR; starR = starR +10)
{
for (int starC = 0; starC < endC; starC =starC+10)
{
//cv::Mat pMat = ScrImg(Rect(starR, starC, Trows, Tcols));
int temp = 0;
for (int diffr =0; diffr < Trows; diffr++)
{
for (int diffc =0 ; diffc < Tcols; diffc++)
{
if (Tchanel == 1) {
temp += abs(ScrImg.at<uchar>(starR + diffr, starC + diffc)- TargitImg.at<uchar>(diffr, diffc))
;
}
else
{
for (int chanels = 0; chanels < Tchanel; chanels++) {
temp += (ScrImg.at<Vec3b>(starR + diffr, starC + diffc)[chanels] - TargitImg.at<Vec3b>(diffr, diffc)[chanels])*
(ScrImg.at<Vec3b>(starR + diffr, starC + diffc)[chanels] - TargitImg.at<Vec3b>(diffr, diffc)[chanels]);
}
}
}
}
if (temp < Squarediff)
{
Squarediff = temp;
outr = starR;
outc = starC;
}
}
}
Rect rect(outc, outr, Tcols, Trows);//左上坐标(x,y)和矩形的长(x)宽(y)
cv::rectangle(ScrImg, rect, Scalar(255, 0, 0), 1, LINE_8, 0);
cv::imshow("原图", ScrImg);
cv::imshow("匹配图", TargitImg);
cv::waitKey(0);
cv::destroyAllWindows();
return 0;
}