如何使用opencv 的moments方法计算轮廓的矩?
矩即为用一组简单的数据(数据描述量)来描述整个图像,这组数据月简单越有代表性越好。良好的特征不受光线、噪点、几何形变的干扰,图像识别技术的发展中,不断有新的描述图像特征提出,而图像不变矩就是其中一个。
从图像中计算出来的矩通常描述了图像不同种类的几何特征如:大小、灰度、方向、形状等,图像矩广泛应用于模式识别、目标分类、目标识别与防伪估计、图像编码与重构等领域。
函数说明api:
获取矩的方法:
cv::moments ( InputArray array,
bool binaryImage = false
)
array:输入数组,可以是光栅图像(单通道,8-bit或浮点型二维数组),或者是一个二维数组(1 X N或N X 1),二维数组类型为Point或Point2f
binaryImage:默认值是false,如果为true,则所有非零的像素都会按值1对待,也就是说相当于对图像进行了二值化处理,阈值为1,此参数仅对图像有效。
计算面积:
double cv::contourArea ( InputArray contour,
bool oriented = false
)
contour:是一个向量,二维点,可以是vector或Mat类型
oriented:有默认值false,面向区域标识符,如果为true,该函数返回一个带符号的面积,其正负取决于轮廓的方向(顺时针还是逆时针)。根据这个特性可以根据面积的符号来确定轮廓的位置。如果是默认值false,则面积以绝对值的形式返回.
计算轮廓曲线的长度方法:
double cv::arcLength ( InputArray curve,
bool closed
)
curve:输入二维点集,可以是vector或Mat类型
closed:曲线是否封闭的标志位,true则封闭否则不封闭
代码:
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;
}
int thresh = 100;
blur(mGr, mGr, Size(3, 3));
Mat canny_output;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
Canny(mGr, canny_output, thresh, thresh * 2, 3);
findContours(canny_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
vector<Moments> mu(contours.size());
for (size_t i = 0; i < contours.size(); i++) {
mu[i] = moments(contours[i], false);
}
vector<Point2f> mc(contours.size());
for (size_t i = 0; i < contours.size(); i++) {
mc[i] = Point2f(static_cast<float>(mu[i].m10 / mu[i].m00),
static_cast<float>(mu[i].m01 / mu[i].m00));
}
Mat drawing = Mat::zeros(canny_output.size(), mRgb.type());
for (size_t i = 0; i < contours.size(); i++) {
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
drawContours(drawing, contours, (int) i, color, 2, 8, hierarchy, 0, Point());
circle(drawing, mc[i], 8, color, -1, 8, 0);
}
// printf("\t Info: Area and Contour Length \n");
for (size_t i = 0; i < contours.size(); i++) {
printf(" * Contour[%d] - Area (M_00) = %.2f - Area OpenCV: %.2f - Length: %.2f \n", (int) i,
mu[i].m00, contourArea(contours[i]), arcLength(contours[i], true));
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
drawContours(drawing, contours, (int) i, color, 2, 8, hierarchy, 0, Point());
circle(drawing, mc[i], 4, color, -1, 8, 0);
}
mRgb=drawing;
LOGI("index %d", looperIndexNum);
}