cv::Scalar refineSegments(const cv::Mat &img, const cv::Mat &mask, cv::Mat &dst, std::vector<cv::Point> &contour, std::vector<cv::Point> &second_contour, cv::Point2i &previous) { //int niters = 3; std::vector<std::vector<cv::Point> > contours; std::vector<cv::Vec4i> hierarchy; cv::Mat temp; //cv::dilate(mask, temp, cv::Mat(), cv::Point(-1, -1), cv::niters); //cv::erode(temp, temp, cv::Mat(), cv::Point(-1, -1), cv::niters * 2); //cv::dilate(temp, temp, cv::Mat(), cv::Point(-1, -1), cv::niters); cv::blur(mask, temp, Size(11, 11)); //cv::imshow("temp", temp); temp = temp > 95.0; cv::findContours(temp, contours, /*hierarchy,*/ CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE); if (dst.data == NULL) dst = cv::Mat::zeros(img.size(), CV_8UC1); else dst.setTo(cv::Scalar(0)); if (contours.size() == 0) return cv::Scalar(-1, -1); // iterate through all the top-level contours, // draw each connected component with its own random color int idx = 0, largestComp = -1, secondlargest = -1; double maxWArea = 0, maxJArea = 0; std::vector<double> justarea(contours.size()); std::vector<double> weightedarea(contours.size()); //for (; idx >= 0; idx = hierarchy[idx][0]) for (; idx < contours.size(); ++idx) { const std::vector<cv::Point> &c = contours[idx]; cv::Scalar _mean = cv::mean(cv::Mat(contours[idx])); justarea[idx] = std::fabs(cv::contourArea(cv::Mat(c))); weightedarea[idx] = std::fabs(cv::contourArea(cv::Mat(c))) / ((previous.x >- 1) ? (1.0 + cv::norm(cv::Point(_mean[0], _mean[1]) - previous)) : 1.0); // consider distance from last blob } for (idx = 0; idx < contours.size(); ++idx) { if (weightedarea[idx] > maxWArea) { maxWArea = weightedarea[idx]; largestComp = idx; } } for (idx = 0; idx < contours.size(); ++idx) { if (justarea[idx] > maxJArea && idx != largestComp) { maxJArea = justarea[idx]; secondlargest = idx; } } cv::Scalar color(255); //std::cout << "largest cc " << largestComp << std::endl; //cv::drawContours(dst, contours, largestComp, color, CV_FILLED); //, 8, hierarchy); //for (idx = 0; idx < contours[largestComp].size() - 1; ++idx) // cv::line(dst, contours[largestComp][idx], contours[largestComp][idx + 1], color, 2); if (largestComp >= 0) { int num = contours[largestComp].size(); cv::Point *pts = &(contours[largestComp][0]); cv::fillPoly(dst, (const Point **)(&pts), &num, 1, color); cv::Scalar b = cv::mean(cv::Mat(contours[largestComp])); b[2] = justarea[largestComp]; contour.clear(); contour = contours[largestComp]; second_contour.clear(); if (secondlargest >= 0) { second_contour = contours[secondlargest]; b[3] = maxJArea; } previous.x = b[0]; previous.y = b[1]; return b; } else return cv::Scalar(-1, -1); }
Scalar refineSegments(const Mat& img, Mat& mask, Mat& dst, vector<Point>& contour, vector<Point>& second_contour, Point2i& previous) { // int niters = 3; vector<vector<Point> > contours; vector<Vec4i> hierarchy; Mat temp; blur(mask, temp, Size(11,11)); temp = temp > 85.0; findContours( temp, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE ); if(dst.data==NULL) dst = Mat::zeros(img.size(), CV_8UC1); else dst.setTo(Scalar(0)); if( contours.size() == 0 ) return Scalar(-1,-1); // iterate through all the top-level contours, // draw each connected component with its own random color int idx = 0, largestComp = -1, secondlargest = -1; double maxWArea = 0, maxJArea = 0; vector<double> justarea(contours.size()); vector<double> weightedarea(contours.size()); // for( ; idx >= 0; idx = hierarchy[idx][0] ) for (; idx<contours.size(); idx++) { const vector<Point>& c = contours[idx]; Scalar _mean = mean(Mat(contours[idx])); justarea[idx] = fabs(contourArea(Mat(c))); weightedarea[idx] = fabs(contourArea(Mat(c))) / ((previous.x >- 1) ? (1.0 + norm(Point(_mean[0],_mean[1])-previous)) : 1.0); //consider distance from last blob } for (idx = 0; idx<contours.size(); idx++) { if( weightedarea[idx] > maxWArea ) { maxWArea = weightedarea[idx]; largestComp = idx; } } for (idx = 0; idx < contours.size(); idx++) { if ( justarea[idx] > maxJArea && idx != largestComp ) { maxJArea = justarea[idx]; secondlargest = idx; } } Scalar color( 255 ); // cout << "largest cc " << largestComp << endl; // drawContours( dst, contours, largestComp, color, CV_FILLED); //, 8, hierarchy ); // for (idx=0; idx<contours[largestComp].size()-1; idx++) { // line(dst, contours[largestComp][idx], contours[largestComp][idx+1], color, 2); // if(largestComp >= 0) { //find top-left values int maxx = -INT_MAX,miny = INT_MAX; int num = contours[largestComp].size(); for (int i=0; i<num; i++) { if(contours[largestComp][i].x > maxx) maxx = contours[largestComp][i].x; if(contours[largestComp][i].y < miny) miny = contours[largestComp][i].y; } //crop contour to 150x150 "window" vector<Point> newblob = contours[largestComp]; // int maxxp150 = MAX(maxx-200,0),minyp150 = MIN(miny+170,480); // // for (int i=0; i<num; i++) { // Point _p = contours[largestComp][i]; // if(_p.x > maxxp150 && _p.y < minyp150) newblob.push_back(_p); // else newblob.push_back(Point(MAX(_p.x,maxxp150),MIN(_p.y,minyp150))); // } Point* pts = &(newblob[0]); num = newblob.size(); fillPoly(dst, (const Point**)(&pts), &num, 1, color); Scalar b = mean(Mat(newblob)); //center of the blob b[0] += 40; b[1] -= 40; b[2] = justarea[largestComp]; contour.clear(); contour = newblob; second_contour.clear(); if(secondlargest >= 0) { second_contour = contours[secondlargest]; b[3] = maxJArea; } previous.x = b[0]; previous.y = b[1]; return b; } else return Scalar(-1,-1); }