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);
	
}
예제 #2
0
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);
	
}