| 45 | { |
| 46 | |
| 47 | void crossCorr( const Mat& img, const Mat& _templ, Mat& corr, |
| 48 | Size corrsize, int ctype, |
| 49 | Point anchor, double delta, int borderType ) |
| 50 | { |
| 51 | const double blockScale = 4.5; |
| 52 | const int minBlockSize = 256; |
| 53 | std::vector<uchar> buf; |
| 54 | |
| 55 | Mat templ = _templ; |
| 56 | int depth = img.depth(), cn = img.channels(); |
| 57 | int tdepth = templ.depth(), tcn = templ.channels(); |
| 58 | int cdepth = CV_MAT_DEPTH(ctype), ccn = CV_MAT_CN(ctype); |
| 59 | |
| 60 | CV_Assert( img.dims <= 2 && templ.dims <= 2 && corr.dims <= 2 ); |
| 61 | |
| 62 | if( depth != tdepth && tdepth != std::max(CV_32F, depth) ) |
| 63 | { |
| 64 | _templ.convertTo(templ, std::max(CV_32F, depth)); |
| 65 | tdepth = templ.depth(); |
| 66 | } |
| 67 | |
| 68 | CV_Assert( depth == tdepth || tdepth == CV_32F); |
| 69 | CV_Assert( corrsize.height <= img.rows + templ.rows - 1 && |
| 70 | corrsize.width <= img.cols + templ.cols - 1 ); |
| 71 | |
| 72 | CV_Assert( ccn == 1 || delta == 0 ); |
| 73 | |
| 74 | corr.create(corrsize, ctype); |
| 75 | |
| 76 | int maxDepth = depth > CV_8S ? CV_64F : std::max(std::max(CV_32F, tdepth), cdepth); |
| 77 | Size blocksize, dftsize; |
| 78 | |
| 79 | blocksize.width = cvRound(templ.cols*blockScale); |
| 80 | blocksize.width = std::max( blocksize.width, minBlockSize - templ.cols + 1 ); |
| 81 | blocksize.width = std::min( blocksize.width, corr.cols ); |
| 82 | blocksize.height = cvRound(templ.rows*blockScale); |
| 83 | blocksize.height = std::max( blocksize.height, minBlockSize - templ.rows + 1 ); |
| 84 | blocksize.height = std::min( blocksize.height, corr.rows ); |
| 85 | |
| 86 | dftsize.width = std::max(getOptimalDFTSize(blocksize.width + templ.cols - 1), 2); |
| 87 | dftsize.height = getOptimalDFTSize(blocksize.height + templ.rows - 1); |
| 88 | if( dftsize.width <= 0 || dftsize.height <= 0 ) |
| 89 | CV_Error( CV_StsOutOfRange, "the input arrays are too big" ); |
| 90 | |
| 91 | // recompute block size |
| 92 | blocksize.width = dftsize.width - templ.cols + 1; |
| 93 | blocksize.width = MIN( blocksize.width, corr.cols ); |
| 94 | blocksize.height = dftsize.height - templ.rows + 1; |
| 95 | blocksize.height = MIN( blocksize.height, corr.rows ); |
| 96 | |
| 97 | Mat dftTempl( dftsize.height*tcn, dftsize.width, maxDepth ); |
| 98 | Mat dftImg( dftsize, maxDepth ); |
| 99 | |
| 100 | int i, k, bufSize = 0; |
| 101 | if( tcn > 1 && tdepth != maxDepth ) |
| 102 | bufSize = templ.cols*templ.rows*CV_ELEM_SIZE(tdepth); |
| 103 | |
| 104 | if( cn > 1 && depth != maxDepth ) |