19 #include <opencv2/imgproc/types_c.h>
20 #include "dispBlobber.hpp"
24 dispBlobber::dispBlobber(
int imH,
int imW,
int _bufferSize,
26 int _backgroundThresh,
27 int _minBlobSize,
int _maxBlobSize,
int _gaussSize,
28 int _imageThreshRatioLow,
int _imageThreshRatioHigh)
31 aux.create(imH, imW, CV_8U);
32 fillMask.create(imH + 2, imW + 2, CV_8U);
36 backgroundThresh = _backgroundThresh;
38 minBlobSize = _minBlobSize;
39 maxBlobSize = _maxBlobSize;
41 gaussSize = _gaussSize;
43 imageThreshRatioLow = _imageThreshRatioLow;
44 imageThreshRatioHigh = _imageThreshRatioHigh;
46 blue = cv::Scalar(255,0,0);
47 green = cv::Scalar(0,255,0);
48 red = cv::Scalar(0,0,255);
49 white = cv::Scalar(255,255,255);
51 bufferSize = _bufferSize;
55 bool dispBlobber::setThresh(
int low)
57 if ( low<0 || low>255 ) {
58 fprintf(stdout,
"Please select valid luminance values (0-255). \n");
62 fprintf(stdout,
"New Threshold is : %i\n", low);
63 backgroundThresh = low;
67 bool dispBlobber::setMargin(
int mrg)
69 fprintf(stdout,
"New margin : %d\n", mrg);
74 double dispBlobber::extractBlob(std::vector<cv::Mat> &images, std::vector<int> &roi, std::vector<int> ¢roid, cv::Mat &blob)
77 cv::Mat image = images[0].clone();
79 cv::cvtColor(image, image, CV_BGR2GRAY);
86 cv::GaussianBlur(image, image, cv::Size(gaussSize,gaussSize), sigmaX1, sigmaY1);
88 cv::threshold(image, image, backgroundThresh, -1, CV_THRESH_TOZERO);
95 cv::dilate(image, image, cv::Mat(), cv::Point(-1,-1), dilate_niter, cv::BORDER_CONSTANT, cv::morphologyDefaultBorderValue());
97 cv::GaussianBlur(image, image, cv::Size(gaussSize,gaussSize), sigmaX2, sigmaY2, cv::BORDER_DEFAULT);
99 cv::erode(image, image, cv::Mat(), cv::Point(-1,-1), erode_niter, cv::BORDER_CONSTANT, cv::morphologyDefaultBorderValue());
104 double minVal, maxVal;
105 cv::Point minLoc, maxLoc;
107 int fillFlags = 8 | ( 255 << 8 ) | cv::FLOODFILL_FIXED_RANGE;
112 while (fillSize < minBlobSize){
114 cv::minMaxLoc( aux, &minVal, &maxVal, &minLoc, &maxLoc );
117 fillSize = floodFill(aux, maxLoc, 0, 0, cv::Scalar(maxVal/imageThreshRatioLow), cv::Scalar(maxVal/imageThreshRatioHigh), fillFlags);
122 cv::floodFill(image, fillMask, maxLoc, 255, 0, cv::Scalar(maxVal/imageThreshRatioLow), cv::Scalar(maxVal/imageThreshRatioHigh), cv::FLOODFILL_MASK_ONLY + fillFlags);
126 std::vector<std::vector<cv::Point > > contours;
127 std::vector<cv::Vec4i> hierarchy;
130 aux = fillMask(cv::Range(1,image.rows+1), cv::Range(1,image.cols+1)).clone();
131 cv::findContours( aux, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0) );
137 double blobSizeOld = -1, blobSize = -1;
138 for(
size_t c = 0; c < contours.size(); c++ ){
141 blobSize = cv::contourArea(contours[c]);
144 if( blobSize > minBlobSize && blobSize > blobSizeOld && blobSize < maxBlobSize)
147 blobSizeOld = blobSize;
158 cv::Rect blobBox = cv::boundingRect(contours[blobI]);
160 cv::Rect imBox(cv::Point(std::max(blobBox.tl().x-margin,0),std::max(blobBox.tl().y-margin,0)),cv::Point(std::min(blobBox.br().x+margin,image.cols-1),std::min(blobBox.br().y+margin,image.rows-1)));
165 cv::Moments mu = moments( contours[blobI],
false );
168 cv::Point2f center2Dcoords = cv::Point2f( mu.m10/mu.m00 , mu.m01/mu.m00 );
172 center2DcoordsBuffer.push_back(center2Dcoords);
174 if ((
int)center2DcoordsBuffer.size()>bufferSize) {
175 assert(!center2DcoordsBuffer.empty());
176 center2DcoordsBuffer.erase(center2DcoordsBuffer.begin());
181 cv::Point2f zero(0.0f, 0.0f);
182 cv::Point2f sum = std::accumulate(center2DcoordsBuffer.begin(), center2DcoordsBuffer.end(), zero);
183 mean_centroid.x = (int)round(sum.x / center2DcoordsBuffer.size());
184 mean_centroid.y = (int)round(sum.y / center2DcoordsBuffer.size());
188 roi.push_back(imBox.tl().x);
189 roi.push_back(imBox.tl().y);
191 roi.push_back(imBox.br().x);
192 roi.push_back(imBox.br().y);
196 centroid.push_back(mean_centroid.x);
197 centroid.push_back(mean_centroid.y);
199 fillMask(cv::Range(1,image.rows+1), cv::Range(1,image.cols+1)).copyTo(blob);
205 blob = cv::Mat::zeros(image.rows, image.cols, CV_8U);
209 centroid.push_back(mean_centroid.x);
210 centroid.push_back(mean_centroid.y);