1.什么叫奇异区域
奇异区域通常是指与周围领域有着某些特征(颜色和灰度)差别的区域,常见的奇异区域如医学领域X光照片或CT某些特定组织,天空中降落等,奇异区域相对于点区域检查更稳定,在目标分割及检测、图像配准、特征分析等领域得到了广泛应用。
计算机视觉中我们常常关注目标的特征是颜色和灰度,刻画图像中两个区域的视觉相似性有许多方法,如形状描述子、颜色特征、矩特征等。对于某种场景下的应用,具有独特纹理的对象可以使用一个很好的纹理描述符。对颜色不同的区域中的单个对象做相同的扩展,我们可以使用颜色特征来测量对象的不同部分的相似性。利用色彩空间表达RGB颜色空间直方图不能很好地表示颜色扩散现象,因此利用HSV色调饱和度纯度来计算其相应的直方图信息。
在计算机视觉中,奇异区域检测主要是通过微分检测或局部极值的分水岭算法实现的。基于图像中的奇异区域的邻域像素值或大或小的特征,我们可以通过计算图像中的局部极值点来实现相应兴趣区域的检测。奇异区域检测一般采用下面两种方法来实现:
(1)基于检测检测器检测
拉普拉斯算子是检测图像奇异区域常用的方法,二维高斯经过拉普拉斯变换后得到:
图像与高斯拉普拉斯函数进行卷积操作实际上求取的是图像与这一函数的相似性,奇异区域表示出现的特征就是图像中呈现比它周围像素灰度值大或小的区域,二维高斯拉普拉斯变换恰好呈现出来的就是这种特征。拉普拉斯检测到图像中的局部极值点,通常需要先对图像进行低通滤波,去除伪点噪声。拉普拉斯响应在尺度时取得极值,也就是说,满足特征空间和尺度上的极值点就是需要检测的奇异区域。
(2)基于局部极值的分水岭检测
局部极值的分水岭检测奇异区域是对原图像进行多间隔区域二值化操作。对一个二值化图像提取相应的连通域并计算相应区域的连通中心点,根据中心点拟合归类成同一块group,得到对应的blob特征;最后根据得到的中心点集group估计出blob特征和对应的半径。
blob分析一般用于图像分割或连通性分析
2.SimpleBlobDetector类
Opencv中提供了操作类SimpleBlobDetector用于奇异区域检测,下面将详细介绍该类的成员及相关参数使用说明。
class SimpleBlobDetector:public FeatureDetector
{
public:
struct Params
{
Params();
float thresholdStep;//二值化间隔
float minThreshold;//二值化起始区间
float maxThreshold;//二值化终止区间
size_t minRepeatability;
float minDistBetweenBlobs;
bool filterByColor;//颜色特征选择
uchar blobColor;//亮度区域标志
bool filterByArea;//限定区域标志
float minArea,maxArea;
bool filterByCircularity;
float minCircularity,maxCircularity;//目标半径
bool filterByInertia;
float minInertiaRatio,maxInertiaRatio;凸包限定
float filterByConvexity;
float minConvexity,maxConvexity;
}
SimpleBlobDetector(const SimpleBlobDetector::Params ¶meters = SimpleBlobDetector::Params ())
protected:
};
该类实现对blob区域的检测,提取blobs目标是先将输入图像源转化为二值图像,以thresholdStep为参数间隔利用二值区间阈值区间[minThreshold,maxThreshold]进行多次二值操作,然后提取每个二值化图像的区域连通并计算它们的中心;接着根据minDistBetweenBlobs将上一步骤得到的区域中心归类得到group,最后根据group估计得到每个blob的中心及其半径,并返回相应的关键点位置及尺寸。
3.参考代码
我们来用blob在RGB和HSV两种通道下,看一下漂亮的羲和小姐姐(图像选的不好,建议找划痕检测或者天空飞行物检测):
这里是参考代码:
#include<opencv2\core\core.hpp>
#include<opencv2\imgproc\imgproc.hpp>
#include<opencv2\highgui\highgui.hpp>
#include <opencv2\features2d\features2d.hpp>
void main()
{
cv::Mat srcImage = cv::imread("1.jpg");
const cv::Mat dstImage1 = srcImage;
cv::Mat dstImage2 = srcImage;
cv::imshow("Input", srcImage);
std::vector<cv::KeyPoint> keypoints1, keypoints2;
cv::SimpleBlobDetector::Params params;//定义blob类
params.filterByArea = true;
params.minArea = 15;
params.maxArea = 10000;
cv::Ptr<cv::SimpleBlobDetector> blobDetector = cv::SimpleBlobDetector::create(params);
blobDetector->detect(dstImage1, keypoints1);//RGB通道下奇异区域检测
cv::drawKeypoints(dstImage1, keypoints1, dstImage1);
cv::imshow("Output1", dstImage1);
cv::imwrite("11.png", dstImage1);
cv::cvtColor(dstImage2, dstImage2, CV_BGR2HSV);
blobDetector->detect(dstImage2, keypoints2);//HSV通道下奇异区域检测
cv::drawKeypoints(dstImage2, keypoints2, dstImage2);
cv::imshow("Output2", dstImage2);
cv::imwrite("12.png", dstImage2);
cv::waitKey(0);
}
得到两个通道的检测图像分别如下