巨坑的simpleBlobDetector
- 入门 强大的simpleBlobDetector
- 进阶 minrepeatability stackOverFlow
- 准备看源码 threshold documence, 看下面的源码要用
- 看源码 blobdetector.cpp 源码
- param.blobColor=255, 将fg设置为255
- param.minRepeatability=0, 取消这个过滤功能
- 由于mask中bg=0,因此随意设置minThreshold=100,maxThreshold=200
void SimpleBlobDetectorImpl::detect(InputArray image, std::vector& keypoints, InputArray)
{
//TODO: support mask
keypoints.clear();
Mat grayscaleImage;
if (image.channels() == 3)
cvtColor(image, grayscaleImage, COLOR_BGR2GRAY);
else
grayscaleImage = image.getMat();
if (grayscaleImage.type() != CV_8UC1) {
CV_Error(Error::StsUnsupportedFormat, "Blob detector only supports 8-bit images!");
}std::vector < std::vector > centers;
for (double thresh = params.minThreshold;
thresh < params.maxThreshold;
thresh += params.thresholdStep)
{
Mat binarizedImage;
//threshold 使得
//1. grayscaleImage中=thresh的像素,其在binarizedImagek的对应位置像素为255
threshold(grayscaleImage, binarizedImage, thresh, 255, THRESH_BINARY);
std::vector < Center > curCenters;
findBlobs(grayscaleImage, binarizedImage, curCenters);
std::vector < std::vector > newCenters;
for (size_t i = 0;
i < curCenters.size();
i++)
{
bool isNew = true;
for (size_t j = 0;
j < centers.size();
j++)
{
double dist = norm(centers[j][ centers[j].size() / 2 ].location - curCenters[i].location);
isNew = dist >= params.minDistBetweenBlobs && dist >= centers[j][ centers[j].size() / 2 ].radius && dist >= curCenters[i].radius;
if (!isNew)
{
centers[j].push_back(curCenters[i]);
size_t k = centers[j].size() - 1;
while( k > 0 && centers[j][k].radius < centers[j][k-1].radius )
{
centers[j][k] = centers[j][k-1];
k--;
}
centers[j][k] = curCenters[i];
break;
}
}
if (isNew)
newCenters.push_back(std::vector (1, curCenters[i]));
}
std::copy(newCenters.begin(), newCenters.end(), std::back_inserter(centers));
}for (size_t i = 0;
i < centers.size();
i++)
{
//remove 不够稳定的blob,即重复次数少于params.minRepeatability
if (centers[i].size() < params.minRepeatability)
continue;
Point2d sumPoint(0, 0);
double normalizer = 0;
for (size_t j = 0;
j < centers[i].size();
j++)
{
sumPoint += centers[i][j].confidence * centers[i][j].location;
normalizer += centers[i][j].confidence;
}
sumPoint *= (1. / normalizer);
KeyPoint kpt(sumPoint, (float)(centers[i][centers[i].size() / 2].radius) * 2.0f);
keypoints.push_back(kpt);
}
}
推荐阅读
- 人脸识别|【人脸识别系列】| 实现自动化妆
- OpenCV|OpenCV-Python实战(18)——深度学习简介与入门示例
- opencv|图像处理之椒盐噪声的添加与去除
- 人脸识别|【人脸识别系列】| 实现人脸截图保存并编写128维特征向量
- opencv|网络爬虫入门练习
- OpenCV|【OpenCV 完整例程】89. 带阻滤波器的传递函数
- OpenCV|【OpenCV 完整例程】90. 频率域陷波滤波器
- OpenCV|【OpenCV 完整例程】22. 图像添加非中文文字
- OpenCV|【OpenCV 完整例程】91. 高斯噪声、瑞利噪声、爱尔兰噪声
- opencv|python+opencv车道线,实线虚线的检测