(四)OpenCV | 斑点检测


Blob,这里译为斑点,可以理解为一幅图像中的显著区域。由于其代表的是一个连通区域,在图像匹配中相比于单纯的点具有更高的稳定性。本文将介绍OpenCV中集成的一个简单检测器,SimpleBlobDetector。在此之前,先理解几个算法中会用到的重要概念。

Circularity,圆度 圆度是一个反映图形接近于完美圆的程度,其范围为(0,1)。如果该值越接近于0,则该图形越接近一个无限拉长的矩形;如果该值越接近于1,则该图形越接近于一个完美的圆。圆度的计算公式如下: R o u n d n e s s = 4 π S C 2 (1) {\rm Roundness} =\frac{4\pi S}{C^2}\tag{1} Roundness=C24πS(1)

其中,S表示该图形的面积,C表示该图形的周长。

InertiaRatio,惯性率 首先,偏心率是指某一个椭圆轨道于理想圆形的偏离程度,长椭圆轨道的偏心率高,而近于圆形的轨道的偏心率低,偏心率的大小范围为[0,+∞)。对于本文来说,椭圆的偏心率范围为(0,1),当该值越接近于0,则椭圆越;当该值越接近于1,则该椭圆越。偏心率的计算公式如下: e = c a (2) e=\frac{c}{a}\tag{2} e=ac(2)

其中,c表示椭圆的半焦距,a表示椭圆的半长轴。其次,惯性率i与偏心率e具有如下关系: e 2 + i 2 = 1 (3) e^2+i^2=1\tag{3} e2+i2=1(3)

通过偏心率与惯性率的关系可以得到:惯性率越接近于0,则该图形越扁;惯性率越接近于1,则该图形越圆。

Convexity,凸度 首先,对于一个图形F以及任意两个位于图形F内的点A和B,若线段AB上的所有点恒位于图形F内,则称该图形F为凸图形;反之则称图像F为凹图形。如以下图形均为凸图形:
(四)OpenCV | 斑点检测_第1张图片
如以下图形为凹图形:
(四)OpenCV | 斑点检测_第2张图片

凸度定义为多边形接近凸图形的程度,凸图形的凸度为1,凹图形的凸度计算如下:
C o n v e x i t y = S H (4) {\rm Convexity}=\frac{S}{H}\tag{4} Convexity=HS(4)

其中,S表示该图形的面积,H表示该图形对应的凸壳的面积。凸壳定义:令K是平面上的一个点集,封闭K中所有顶点的最小凸图形称为K的凸壳。即,将凹图形变成凸图形时所形成的最小凸图形。如上凹图形的凸壳为:
(四)OpenCV | 斑点检测_第3张图片

本文所使用的检测器是OpenCV中集成的检测器。

#include 

using namespace cv;
using namespace std;

int main(int argc, char** argv) {
	// 读入图像,并将其转换为灰度形式
	Mat img = imread("blob.jpg", IMREAD_GRAYSCALE);
	// 定义SimpleBlobDetector检测器参数
	SimpleBlobDetector::Params params;
	// 检测区域大小的控制并滤除面积小于1500的区域
	params.filterByArea = true;
	params.minArea = 1500;
	// 设置最小及最大阈值
	params.minThreshold = 10;
	params.maxThreshold = 200;
	// 检测区域形状的控制并滤除圆度小于0.1的区域
	params.filterByCircularity = true;
	params.minCircularity = 0.1;
	// 检测区域惯性率的控制并滤除惯性率小于0.01的区域
	params.filterByInertia = true;
	params.minInertiaRatio = 0.01;
	// 检测区域凸性的控制并滤除凸度小于0.87的区域
	params.filterByConvexity = true;
	params.minConvexity = 0.87;
	// 定义关键点集合
	vector<KeyPoint> keypoints;

#if CV_MAJOR_VERSION < 3	// 使用OpenCV2.x
	// 初始化检测器
	SimpleBlobDetector detector(params);
	// 调用检测函数
	detector.detect(img, keypoints);
#else 
	// 初始化检测器
	Ptr<SimpleBlobDetector> detector = SimpleBlobDetector::create(params);
	// 调用检测函数
	detector->detect(img, keypoints);
#endif

	// DrawMatchesFlags::DRAW_RICH_KEYPOINTS表示在绘制特征点时会绘制特征点位置、大小和方向
	Mat img_with_keypoints;
	drawKeypoints(img, keypoints, img_with_keypoints, Scalar(0, 0, 255), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
	// 绘制检测结果
	imshow("keypoints", img_with_keypoints);
	waitKey(0);

	return 0;
}

首先来看测试图像:
(四)OpenCV | 斑点检测_第4张图片

第一行检测对象为图形面积,第二行检测对象为像素阈值,第三行检测对象为图形圆度,第四行检测对象为惯性率,第五行检测对象为图形凸度。检测结果如下:
(四)OpenCV | 斑点检测_第5张图片


参考

  1. https://github.com/spmallick/learnopencv/tree/master/BlobDetector.


你可能感兴趣的:(OpenCV,opencv,计算机视觉)