opencv学习笔记二十四:Hu矩

在连续情况下,图像函数为 ,那么图像的p+q阶几何矩(标准矩)定义为:

p+q阶中心距定义为:

其中 和 代表图像的重心,

对于离散的数字图像,采用求和号代替积分:

 和 分别是图像的高度和宽度;

归一化的中心距定义为:

 ;其中

利用二阶和三阶归一化中心矩构造了7个不变矩 :

这7个不变矩构成一组特征量,Hu.M.K在1962年证明了他们具有旋转,缩放和平移不变性。

实际上,在对图片中物体的识别过程中,只有 和 不变性保持的比较好,其他的几个不变矩带来的误差比较大,有学者认为只有基于二阶矩的不变矩对二维物体的描述才是真正的具有旋转、缩放和平移不变性( 和 刚好都是由二阶矩组成的)。

由Hu矩组成的特征量对图片进行识别,优点就是速度很快,缺点是识别率比较低,我做过手势识别,对于已经分割好的手势轮廓图,识别率也就30%左右,对于纹理比较丰富的图片,识别率更是不堪入眼,只有10%左右。这一部分原因是由于Hu不变矩只用到低阶矩(最多也就用到三阶矩),对于图像的细节未能很好的描述出来,导致对图像的描述不够完整。

Hu不变矩一般用来识别图像中大的物体,对于物体的形状描述得比较好,图像的纹理特征不能太复杂,像识别水果的形状,或者对于车牌中的简单字符的识别效果会相对好一些。

以上定义摘自该篇博客:https://blog.csdn.net/wrj19860202/article/details/6327094

#include<opencv2/opencv.hpp>

using namespace cv;
using namespace std;
int value = 80;
RNG rng(1);
Mat src, dst,gray_img, canny_img, blur_img;
void callback(int, void*);
int main(int arc, char** argv)
{	
	src = imread("3.jpg");
	namedWindow("input",CV_WINDOW_AUTOSIZE);
	imshow("input", src);
	cvtColor(src, gray_img,CV_BGR2GRAY);
	GaussianBlur(gray_img, blur_img, Size(3, 3), 10, 10);
	namedWindow("output", CV_WINDOW_AUTOSIZE);
	createTrackbar("threshold", "output", &value, 255, callback);
	callback(0, 0);


	waitKey(0);
	return 0;
}
void callback(int, void*) {
	Canny(blur_img, canny_img, value, 2 * value, 3);
	vector<vector<Point>> contours;
	vector<Vec4i> hierarchy;
	findContours(canny_img, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
	vector<Moments> contours_moments(contours.size());
	vector<Point2f>centroid(contours.size());
	for (int i = 0; i < contours.size(); i++) {
		contours_moments[i] = moments(contours[i]);
		centroid[i] = Point(contours_moments[i].m10 / contours_moments[i].m00, contours_moments[i].m01 / contours_moments[i].m00);
	}
	src.copyTo(dst);

	for (int j = 0; j < contours.size(); j++) {
		//如果轮廓点数小于30,就不进行下面操作,继续循环
		if (contours[j].size() < 30) {
			continue;
		}
		Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
		printf("contours %d area:%.2f arcLength:%.2f\n",j,contourArea(contours[j]), arcLength(contours[j],false));
		drawContours(dst, contours, j, color, 2);
		circle(dst, centroid[j], 2, color, 2);
	}
	imshow("output", dst);
	
	
}

运行结果如下:

猜你喜欢

转载自blog.csdn.net/qq_24946843/article/details/82558593
今日推荐