| 232 | /*****************************************************************************************/ |
| 233 | |
| 234 | void cv::matchTemplate( InputArray _img, InputArray _templ, OutputArray _result, int method ) |
| 235 | { |
| 236 | CV_Assert( CV_TM_SQDIFF <= method && method <= CV_TM_CCOEFF_NORMED ); |
| 237 | |
| 238 | int numType = method == CV_TM_CCORR || method == CV_TM_CCORR_NORMED ? 0 : |
| 239 | method == CV_TM_CCOEFF || method == CV_TM_CCOEFF_NORMED ? 1 : 2; |
| 240 | bool isNormed = method == CV_TM_CCORR_NORMED || |
| 241 | method == CV_TM_SQDIFF_NORMED || |
| 242 | method == CV_TM_CCOEFF_NORMED; |
| 243 | |
| 244 | Mat img = _img.getMat(), templ = _templ.getMat(); |
| 245 | if( img.rows < templ.rows || img.cols < templ.cols ) |
| 246 | std::swap(img, templ); |
| 247 | |
| 248 | CV_Assert( (img.depth() == CV_8U || img.depth() == CV_32F) && |
| 249 | img.type() == templ.type() ); |
| 250 | |
| 251 | CV_Assert( img.rows >= templ.rows && img.cols >= templ.cols); |
| 252 | |
| 253 | Size corrSize(img.cols - templ.cols + 1, img.rows - templ.rows + 1); |
| 254 | _result.create(corrSize, CV_32F); |
| 255 | Mat result = _result.getMat(); |
| 256 | |
| 257 | #ifdef HAVE_TEGRA_OPTIMIZATION |
| 258 | if (tegra::matchTemplate(img, templ, result, method)) |
| 259 | return; |
| 260 | #endif |
| 261 | |
| 262 | int cn = img.channels(); |
| 263 | crossCorr( img, templ, result, result.size(), result.type(), Point(0,0), 0, 0); |
| 264 | |
| 265 | if( method == CV_TM_CCORR ) |
| 266 | return; |
| 267 | |
| 268 | double invArea = 1./((double)templ.rows * templ.cols); |
| 269 | |
| 270 | Mat sum, sqsum; |
| 271 | Scalar templMean, templSdv; |
| 272 | double *q0 = 0, *q1 = 0, *q2 = 0, *q3 = 0; |
| 273 | double templNorm = 0, templSum2 = 0; |
| 274 | |
| 275 | if( method == CV_TM_CCOEFF ) |
| 276 | { |
| 277 | integral(img, sum, CV_64F); |
| 278 | templMean = mean(templ); |
| 279 | } |
| 280 | else |
| 281 | { |
| 282 | integral(img, sum, sqsum, CV_64F); |
| 283 | meanStdDev( templ, templMean, templSdv ); |
| 284 | |
| 285 | templNorm = CV_SQR(templSdv[0]) + CV_SQR(templSdv[1]) + |
| 286 | CV_SQR(templSdv[2]) + CV_SQR(templSdv[3]); |
| 287 | |
| 288 | if( templNorm < DBL_EPSILON && method == CV_TM_CCOEFF_NORMED ) |
| 289 | { |
| 290 | result = Scalar::all(1); |
| 291 | return; |