opencv simpleBlobDetector入坑

巨坑的simpleBlobDetector

  • 入门 强大的simpleBlobDetector
  • 进阶 minrepeatability stackOverFlow
  • 准备看源码 threshold documence, 看下面的源码要用
  • 看源码 blobdetector.cpp 源码
对于 mask, fg=255 而不是fg=0
  • param.blobColor=255, 将fg设置为255
  • param.minRepeatability=0, 取消这个过滤功能
  • 由于mask中bg=0,因此随意设置minThreshold=100,maxThreshold=200
minThreshold, maxThreshold 【opencv simpleBlobDetector入坑】分析 blobdetector.cpp 的关键源码
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); } }

    推荐阅读