opencv 模板匹配查找

模板匹配是一项在一幅图像中寻找与另一幅模板图像最匹配(相似)部分的技术.

模板匹配函数:
void matchTemplate(InputArray image, InputArray temp1, OutputArray result, int method);

参数说明:
image,待搜索的图像,且需为 8 位或 32 位浮点型图像。
temp1,搜索模板,需要和原图片有一样的数据类型,且尺寸不能大于源图像。
result,比较结果的映射图像,其必须为单通道、32 位浮点型图像,大小为 (image.cols - temp1.cols +1)×(image.rows - temp1.rows +1)
method,匹配方法,

enum TemplateMatchModes {
    TM_SQDIFF        = 0, //!< \f[R(x,y)= \sum _{x',y'} (T(x',y')-I(x+x',y+y'))^2\f]
    TM_SQDIFF_NORMED = 1, //!< \f[R(x,y)= \frac{\sum_{x',y'} (T(x',y')-I(x+x',y+y'))^2}{\sqrt{\sum_{x',y'}T(x',y')^2 \cdot \sum_{x',y'} I(x+x',y+y')^2}}\f]
    TM_CCORR         = 2, //!< \f[R(x,y)= \sum _{x',y'} (T(x',y')  \cdot I(x+x',y+y'))\f]
    TM_CCORR_NORMED  = 3, //!< \f[R(x,y)= \frac{\sum_{x',y'} (T(x',y') \cdot I(x+x',y+y'))}{\sqrt{\sum_{x',y'}T(x',y')^2 \cdot \sum_{x',y'} I(x+x',y+y')^2}}\f]
    TM_CCOEFF        = 4, //!< \f[R(x,y)= \sum _{x',y'} (T'(x',y')  \cdot I'(x+x',y+y'))\f]
                          //!< where
                          //!< \f[\begin{array}{l} T'(x',y')=T(x',y') - 1/(w  \cdot h)  \cdot \sum _{x'',y''} T(x'',y'') \\ I'(x+x',y+y')=I(x+x',y+y') - 1/(w  \cdot h)  \cdot \sum _{x'',y''} I(x+x'',y+y'') \end{array}\f]
    TM_CCOEFF_NORMED = 5  //!< \f[R(x,y)= \frac{ \sum_{x',y'} (T'(x',y') \cdot I'(x+x',y+y')) }{ \sqrt{\sum_{x',y'}T'(x',y')^2 \cdot \sum_{x',y'} I'(x+x',y+y')^2} }\f]
};

使用案例:

bool use_mask;
Mat img;
Mat templ;
Mat mask;
Mat result;
int match_method=0;

void MatchingMethod(int, void *, Mat rem) {
    int result_cols = img.cols - templ.cols + 1;
    int result_rows = img.rows - templ.rows + 1;
    result.create(result_rows, result_cols, CV_32FC1);
    bool method_accepts_mask = (CV_TM_SQDIFF == match_method || match_method == CV_TM_CCORR_NORMED);
    if (use_mask && method_accepts_mask) {
        matchTemplate(img, templ, result, match_method, mask);
    }
    else {
        matchTemplate(img, templ, result, match_method);
    }
    normalize(result, result, 0, 1, NORM_MINMAX, -1, Mat());
    double minVal;
    double maxVal;
    Point minLoc;
    Point maxLoc;
    Point matchLoc;
    minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc, Mat());
    if (match_method == TM_SQDIFF || match_method == TM_SQDIFF_NORMED) {
        matchLoc = minLoc;
    }else {
        matchLoc = maxLoc;
    }
//    rectangle(rem, matchLoc, Point(matchLoc.x + templ.cols, matchLoc.y + templ.rows),
//              Scalar::all(0), 8, 8, 0);
    rectangle(rem, matchLoc, Point(matchLoc.x + templ.cols, matchLoc.y + templ.rows),
              Scalar::all(0), 2, 8, 0);
}

JNIEXPORT void JNICALL
Java_org_opencv_samples_tutorial2_Tutorial2Activity_FindFeatures(JNIEnv *, jobject, jlong addrGray,
                                                                 jlong addrRgba) {
    Mat &mGr = *(Mat *) addrGray;
    Mat &mRgb = *(Mat *) addrRgba;
    vector<KeyPoint> v;

    looperAddNum++;
    if (looperAddNum > 60) {
        looperAddNum = 0;
        if (looperIndexNum < 100)
            looperIndexNum += 1;
    }

    img = mRgb.clone();
    Rect r(mRgb.cols / 8 * 2, mRgb.rows / 8 * 2, mRgb.cols / 8 * 4, mRgb.rows / 8 * 4);
    templ = img(r);
    MatchingMethod(0, 0, mRgb);

    LOGI("index %d", looperIndexNum);


}

猜你喜欢

转载自blog.csdn.net/mhhyoucom/article/details/107320924