opencv检测点在轮廓的相对位置 pointPolygonTest

如何用opencv判断点在轮廓的你面、边上或者外面?

函数说明:

检测点在轮廓的位置:

double pointPolygonTest(InputArray contour, Point2f pt, bool measureDist)

用于测试一个点是否在多边形中
当measureDist设置为true时,返回实际距离值。若返回值为正,表示点在多边形内部,返回值为负,表示在多边形外部,返回值为0,表示在多边形上。
当measureDist设置为false时,返回 -1、0、1三个固定值。若返回值为+1,表示点在多边形内部,返回值为-1,表示在多边形外部,返回值为0,表示在多边形上。

检测最大值最小值和对应位置:

void minMaxLoc( const Mat& src, double* minVal, double* maxVal=0, Point* minLoc=0, Point* maxLoc=0, const Mat& mask=Mat() );
void minMaxLoc(const MatND& src, double* minVal, double* maxVal, int* minIdx=0, int* maxIdx=0, const MatND& mask=MatND() );
void minMaxLoc(const SparseMat& src, double* minVal, double* maxVal, int* minIdx=0, int* maxIdx=0);

参数解释
参数1:InputArray类型的src,输入单通道数组(图像)。
参数2:double类型的minVal,返回最小值的指针。若无须返回,此值置为NULL。
参数3:double
类型的maxVal,返回最大值的指针。若无须返回,此值置为NULL。
参数4:Point类型的minLoc,返回最小位置的指针(二维情况下)。若无须返回,此值置为NULL。
参数5:Point
类型的maxLoc,返回最大位置的指针(二维情况下)。若无须返回,此值置为NULL。
参数6:InputArray类型的mask,用于选择子阵列的可选掩膜。

说明:
1 minMaxLoc寻找矩阵(一维数组当作向量,用Mat定义) 中最小值和最大值的位置.
2 参数若不需要,则置为NULL或者0,即可.
3 minMaxLoc针对Mat和MatND的重载中 ,第5个参数是可选的(optional),不使用不传递即可.

代码:

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;
    }


	//逻辑开始
    const int r = mRgb.rows/4;
    Mat src = Mat::zeros(Size(mRgb.cols, mRgb.rows), CV_8UC1);
    vector<Point2f> vert(6);
    vert[0] = Point(3 * r / 2, static_cast<int>(1.34 * r));
    vert[1] = Point(1 * r, 2 * r);
    vert[2] = Point(3 * r / 2, static_cast<int>(2.866 * r));
    vert[3] = Point(5 * r / 2, static_cast<int>(2.866 * r));
    vert[4] = Point(3 * r, 2 * r);
    vert[5] = Point(5 * r / 2, static_cast<int>(1.34 * r));
    for (int j = 0; j < 6; j++) {
        line(src, vert[j], vert[(j + 1) % 6], Scalar(255), 3, 8);
    }
    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;
    Mat src_copy = src.clone();
    findContours(src_copy, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);
    Mat raw_dist(src.size(), CV_32FC1);
    for (int j = 0; j < src.rows; j++) {
        for (int i = 0; i < src.cols; i++) {
            raw_dist.at<float>(j, i) = (float) pointPolygonTest(contours[0],
                                                                Point2f((float) i, (float) j),
                                                                true);
        }
    }
    double minVal;
    double maxVal;
    minMaxLoc(raw_dist, &minVal, &maxVal, 0, 0, Mat());
    minVal = abs(minVal);
    maxVal = abs(maxVal);
    Mat drawing = Mat::zeros(src.size(),CV_8UC3);
    for (int j = 0; j < src.rows; j++) {
        for (int i = 0; i < src.cols; i++) {
            if (raw_dist.at<float>(j, i) < 0) {
                drawing.at<Vec3b>(j, i)[0] = (uchar) (255 -
                                                      abs(raw_dist.at<float>(j, i)) * 255 / minVal);
            } else if (raw_dist.at<float>(j, i) > 0) {
                drawing.at<Vec3b>(j, i)[2] = (uchar) (255 -
                                                      raw_dist.at<float>(j, i) * 255 / maxVal);
            } else {
                drawing.at<Vec3b>(j, i)[0] = 255;
                drawing.at<Vec3b>(j, i)[1] = 255;
                drawing.at<Vec3b>(j, i)[2] = 255;
            }
        }
    }
    mRgb  = drawing;


    LOGI("index %d", looperIndexNum);


}

opencv检测点在轮廓的相对位置 pointPolygonTest_第1张图片

你可能感兴趣的:(Android,C语言)