Opencv3.4.4利⽤matchTemplate⽅法实现多⽬标匹配
matchTemplate实现单⽬标匹配的⽅法很多在此不赘述,本⽂主要提供多⽬标匹配的⽅法。
⾸先matchTemplate( InputArray image, InputArray templ, OutputArray result, int method, InputArray mask = noArray() );三个参数Result,反应的是样本与待测⽬标的相似程度的⼀个矩阵;
minMaxLoc函数是出矩阵中最⼤最⼩值的⼤⼩和位置。
1、 使⽤matchTemplate得到Result,利⽤minMaxLoc确定最佳匹配位置,接着利⽤CoverTarget函数(见下⽂代码)覆盖掉⽬标区域得到新的Result重复上述步骤;
2、设置阈值使Result中符合阈值范围的点全部画出来,缺点同个⽬标被多词框出,解决⽅法在符合阈值点的领域范围内寻最佳值。(未实现)。
核⼼代码:
⽅法1:
int main()
{
Mat src = imread("1.jpg");
Mat tem = imread("temp.jpg", 0);
Mat gray = Mat::zeros(src.size(), CV_8UC1);
cvtColor(src, gray, COLOR_BGR2GRAY);
Mat resultImage;
int resultImage_cols = ls - ls + 1;
int resultImage_rows = ws - ws + 1;
matchTemplate(gray, tem, resultImage, 1);
double minValue, maxValue;
Point minLoc, maxLoc;
minMaxLoc(resultImage, &minValue, &maxValue, &minLoc, &maxLoc,  Mat());
rectangle(src, minLoc, Point(minLoc.x + ls, minLoc.y + ws), Scalar(0, 0, 255), 1, 8, 0);
// 计算第⼆个最⼩值
CoverTarget(resultImage, minLoc, maxValue, ls, ws);
minMaxLoc(resultImage, &minValue, &maxValue, &minLoc, &maxLoc, Mat());
rectangle(src, minLoc, Point(minLoc.x + ls, minLoc.y + ws), Scalar(0, 0, 255), 1, 8, 0);
// 计算三个最⼩值
CoverTarget(resultImage, minLoc, maxValue, ls, ws);
minMaxLoc(resultImage, &minValue, &maxValue, &minLoc, &maxLoc, Mat());
rectangle(src, minLoc, Point(minLoc.x + ls, minLoc.y + ws), Scalar(0, 0, 255), 1, 8, 0);
imshow("2", src);
waitKey(0);
return 0;
}
void CoverTarget(Mat &result, Point minLoc, int maxVaule, int cols, int rows)
{
// 先将第⼀个最⼩值点附近两倍模板宽度和⾼度的都设置为最⼤值防⽌产⽣⼲扰 int startX = minLoc.x - cols;
int startY = minLoc.y - rows;
int endX = minLoc.x + cols;
int endY = minLoc.y + rows;
if (startX < 0)
{
startX = 0;
}
if (startY < 0)
{
startY = 0;
}
if (endX > ls - 1)
{
endX = ls - 1;
}
if (endY > ws - 1)
{
endY = ws - 1;
}
int y, x;
for (y = startY; y < endY; y++)
{
for (x = startX; x < endX; x++)
{
result.at<float>(y, x) = maxVaule;  //覆盖
}
}
}
结果:
⽅法2:  法1和法2效果图贴反,抱歉
int main()
{
Mat src = imread("1.jpg");
Mat tem = imread("temp.jpg",0);
Mat gray = Mat::zeros(src.size(), CV_8UC1);
cvtColor(src, gray, COLOR_BGR2GRAY);
Mat resultImage;
int resultImage_cols = ls - ls + 1;
int resultImage_rows = ws - ws + 1;
// int resultImage_cols = ls;
// int resultImage_rows = ws;
//进⾏匹配和标准化
/
*
参数四:SQDIFF和SQDIFF_NORMED越⼩数值匹配效果更好,其他⽅法则反之。
TM_SQDIFF TM_SQDIFF_NORMED TM_CCORR
TM_CCORR_NORMED TM_CCOEFF TM_CCOEFF_NORMED
*/
int matchMethod = 5;//1 3 5
matchTemplate(gray, tem, resultImage, matchMethod);
imshow("效果图⽚1", resultImage);
// cout << resultImage;
float threshold;
for (int i = 0; i < ws; i++)
{
for (int j = 0; j < ls; j++)
{
if (matchMethod == 1)
{
threshold = 0.4;
if (resultImage.at<float>(i, j) < threshold)
{
rectangle(src, Point(j, i), Point(j + ls, i + ws), Scalar(0, 0, 255), 1, 8, 0);    }
}
else if(matchMethod == 3)
{
threshold = 0.8;
if (resultImage.at<float>(i, j) > threshold && resultImage.at<float>(i, j) < 1)
{
rectangle(src, Point(j, i), Point(j + ls, i + ws), Scalar(0, 0, 255), 1, 8, 0);    }
}
else if (matchMethod == 5)
{
threshold = 0.6;
if (resultImage.at<float>(i, j) > threshold && resultImage.at<float>(i, j) < 1)
{
rectangle(src, Point(j, i), Point(j + ls, i + ws), Scalar(0, 0, 255), 1, 8, 0);    }
}
}
}
imshow("原始图⽚", src);
cvWaitKey(0);
return 0;
}
结果:
rectangle函数opencv

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。