zl程序教程

您现在的位置是:首页 >  后端

当前栏目

利用OpenCV的SimpleBlobDetector检测图像的奇异区域(斑点)

Opencv 利用 检测 图像 区域 奇异
2023-09-11 14:15:39 时间

图像处理开发需求、图像处理接私活挣零花钱,请加微信/QQ 2487872782
图像处理开发资料、图像处理技术交流请加QQ群,群号 271891601

奇异区域通常是指与周围领域有着某些特征(颜色或灰度)差别的区域。常见的奇异区域如医学领域X光照片或CT某些特定组织、天空中降落的特体等。

奇异区域检测一般采用两种方法来实现。PS:下面对原理的描述只是个大概描述,估计大家都看得模模糊糊的,如果想真得搞清楚,请自行搜索相关论文。之所以要给个大概描述,是方便大家查询资料时有个参考。

⑴基于微分检测器检测。拉普拉斯算子是检测图像奇异区域常用的方法。图像与高斯拉普拉斯函数进行卷积操作实际上求取的是图像与这一函数的相似性,奇异区域表现出来的特征就是图像中呈现比它周围像素灰度值大或小的区域,二维高斯拉普拉斯变换恰好呈现出来的就是这种特征。拉普拉斯检测图像中的局部极值点,通常需要先对图像进行滤波,去除伪点噪声。

⑵基于局部极值的分水岭检测。局部极值的分水岭检测奇异区域是对原图像进行多间隔区域二值化操作,对一个二值化图像提取相应的连通域并计算相应区域的连通中心点;根据中心点拟合归类成同一块group,得到对应的blob特征;最后根据得到的中心点集group估计出blob特征和对应的半径。

OpenCV提供了操作类SimpleBlobDetector用于奇异区域检测,原理就采用的是上面介绍的第二种原理,即基于局部极值的分水岭检测。下面对这个类进行相关介绍和说明。

首先要明白为什么叫称这个类叫操作类,因为实际上它实际上并没有实质性的功能,为啥没有?我们先来看下它的定义吧!

class CV_EXPORTS_W SimpleBlobDetector : public Feature2D
{
public:
  struct CV_EXPORTS_W_SIMPLE Params
  {
      CV_WRAP Params();
      CV_PROP_RW float thresholdStep;
      CV_PROP_RW float minThreshold;
      CV_PROP_RW float maxThreshold;
      CV_PROP_RW size_t minRepeatability;
      CV_PROP_RW float minDistBetweenBlobs;

      CV_PROP_RW bool filterByColor;
      CV_PROP_RW uchar blobColor;

      CV_PROP_RW bool filterByArea;
      CV_PROP_RW float minArea, maxArea;

      CV_PROP_RW bool filterByCircularity;
      CV_PROP_RW float minCircularity, maxCircularity;

      CV_PROP_RW bool filterByInertia;
      CV_PROP_RW float minInertiaRatio, maxInertiaRatio;

      CV_PROP_RW bool filterByConvexity;
      CV_PROP_RW float minConvexity, maxConvexity;

      void read( const FileNode& fn );
      void write( FileStorage& fs ) const;
  };

  CV_WRAP static Ptr<SimpleBlobDetector>
    create(const SimpleBlobDetector::Params ¶meters = SimpleBlobDetector::Params());
};

我们看到,这个类实际上就定义了一个名称为Params的结构体,它的实际性操作实际上都是来自于基类Feature2D,所以这个类仅是一个对Feature2D的操作类而已,这样说大家能明白了吧!结构体Params中各成员的含义只有真正懂这个算法才能搞清楚,所以这里就不做介绍了。如果你懂这个算法的原理了,那么根据名称就知道各成员是干嘛的了。
值得注意的,成员函数create的返回类型是Ptr<SimpleBlobDetector>,所以在使用create创建对象时,对象的类型一定要注意,关于这一点,看下面我给出的代码就行了,

下面是代码(代码中用到的图像的下载链接:boudingRect.jpg_免费高速下载|百度网盘-分享无限制

//OpenCV版本3.0.0 
//图像处理开发需求、图像处理接私活挣零花钱,请加微信/QQ 2487872782
//图像处理开发资料、图像处理技术交流请加QQ群,群号 271891601


#include "opencv2/opencv.hpp"  
#include <iostream>
using namespace cv;
int main()
{
	cv::Mat srcImage=
		cv::imread("boudingRect.jpg");
	if (!srcImage.data)
		return -1;
	cv::imshow("srcImage", srcImage);
	// 向量关键点
	std::vector<KeyPoint> keypoints;
	//  blob类定义
	SimpleBlobDetector::Params params;
    // 参数定义
	params.filterByArea = true;
	params.minArea = 15;
	params.maxArea = 10000;

  
   Ptr<SimpleBlobDetector> blobDetect=SimpleBlobDetector::create(params);

   	// 奇异区域检测
   blobDetect->detect(srcImage, keypoints);




	// 绘制关键点
	drawKeypoints(srcImage, keypoints,
	 srcImage, Scalar(255, 0, 0));
	cv::imshow("result", srcImage);
	cv::waitKey();
	return 0;
}

代码运行结果如下图所示

从运行结果中我们可以看出,通过程序,检测出了图像中的奇异区域,即热气球,并且标出了这些区域的中心~

图像处理开发需求、图像处理接私活挣零花钱,请加微信/QQ 2487872782
图像处理开发资料、图像处理技术交流请加QQ群,群号 271891601