巨坑的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
分析 blobdetector.cpp 的關鍵源碼
void SimpleBlobDetectorImpl::detect(InputArray image, std::vector<cv::KeyPoint>& 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<Center> > centers;
for (double thresh = params.minThreshold; thresh < params.maxThreshold; thresh += params.thresholdStep)
{
Mat binarizedImage;
//threshold 使得
//1. grayscaleImage中<thresh的像素,其在binarizedImage的對應位置像素爲0
//2. grayscaleImage中>=thresh的像素,其在binarizedImagek的對應位置像素爲255
threshold(grayscaleImage, binarizedImage, thresh, 255, THRESH_BINARY);
std::vector < Center > curCenters;
findBlobs(grayscaleImage, binarizedImage, curCenters);
std::vector < std::vector<Center> > 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<Center> (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);
}
}