如何用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);
}