예제 #1
0
파일: color.cpp 프로젝트: tracedev/legit
        void fillconvex_ring(Mat& mask, Point2f* points, int count, int inner, int outer) {

            Point2f* hull;
            int size = convex_hull(points, count, &hull);

            // apparently we have to convert Point2f array to integers ...
            Point* hulli = new Point[size];

            for (int i = 0; i < size; i++) {
                hulli[i].x = (int) hull[i].x;
                hulli[i].y = (int) hull[i].y;
            }

            free(hull);

            fillConvexPoly(mask, hulli, size, Scalar(1), 1);

            delete [] hulli;

            Mat mask2;

            dilate(mask, mask2, Mat::ones(outer + inner, outer + inner, CV_8U));

            fillConvexPoly(mask, hulli, size, Scalar(0), 1);

            erode(mask2, mask, Mat::ones(inner, inner, CV_8U));

        }
예제 #2
0
	static void paint_voronoi( Mat& img, Subdiv2D& subdiv )
	{
	    vector<vector<Point2f> > facets;
	    vector<Point2f> centers;
	    subdiv.getVoronoiFacetList(vector<int>(), facets, centers);
	
	    vector<Point> ifacet;
	    vector<vector<Point> > ifacets(1);
	
	    for( size_t i = 0; i < facets.size(); i++ )
	    {
	        ifacet.resize(facets[i].size());
	        for( size_t j = 0; j < facets[i].size(); j++ )
	            ifacet[j] = facets[i][j];
	
	        Scalar color;
	        color[0] = rand() & 255;
	        color[1] = rand() & 255;
	        color[2] = rand() & 255;
	        fillConvexPoly(img, ifacet, color, 8, 0);
	
	        ifacets[0] = ifacet;
	        polylines(img, ifacets, true, Scalar(), 1, LINE_AA, 0);
	        circle(img, centers[i], 3, Scalar(), FILLED, LINE_AA, 0);
	    }
	}
void drawCroppedImage(Mat& sourceImg, vector<Point> ROI){
	int max_x = 0;
	int max_y = 0;
	int min_x = 99999;
	int min_y = 99999;
	
	Mat mask = cvCreateMat(sourceImg.rows, sourceImg.cols, CV_8UC1);
	for(int i=0; i<mask.cols; i++)
	   for(int j=0; j<mask.rows; j++)
		   mask.at<uchar>(Point(i,j)) = 0;

	vector<Point> ROI_Poly;
	approxPolyDP(ROI, ROI_Poly, 1.0, true);

	for (int i = 0; i < ROI.size(); i++){
		if (ROI[i].x > max_x){
			max_x = ROI[i].x;}
		if (ROI[i].x < min_x){
			min_x = ROI[i].x;}
		if (ROI[i].y > max_y){
			max_y = ROI[i].y;}
		if (ROI[i].y < min_y){
			min_y = ROI[i].y;}
	}
	
	fillConvexPoly(mask, &ROI_Poly[0], ROI_Poly.size(), 255, 8, 0); 
	// Sanity check for outside the edges of the source image
	/*max_x = (max_x > sourceImg.cols) ? sourceImg.cols : max_x;
	max_y = (max_y > sourceImg.rows) ? sourceImg.rows : max_y;
	min_x = (min_x < 0 ) ? 0 : min_x;
	min_y = (min_y < 0 ) ? 0 : min_y;
	
	int width = max_x - min_x;
	int height = max_y - min_y;*/
	
//	int topLeftX = centerX - width  * scaleX / 2;
//	int topLeftY = centerY - height * scaleY / 2;
	
//	cout << topLeftX << " " << topLeftY << endl;
	
//	topLeftX = max(topLeftX, 0);
//	topLeftY = max(topLeftY, 0);
	
	
	// Move mask to the origin
//	translateImg(mask, (-1 * min_x) , (-1 * min_y)  );//, 50);
	
//	cout << mask.size() << endl;
			
//	Mat tmp = sourceImg(Rect(min_x, min_y, width, height) );
	
//	resize(tmp, tmp, Size(width * scaleX, height * scaleY), 0, 0, INTER_CUBIC);
//	resize(mask, mask, Size(mask.cols * scaleX, mask.rows * scaleY), 0, 0, INTER_CUBIC);
	
	// By playing around, it seems that the thing to do is move the mask to the origin, where it is 
	// applied to the dstImg(rectangle). Then that masked image is applied to the rectangle in the 
	// destination image. We don't need to move the mask to line up with the destination image. 
//	tmp.copyTo(dstImg(Rect(topLeftX, topLeftY, width * scaleX, height * scaleY) )  , mask);
}
예제 #4
0
void cameraSettings2d::on_calBack_released()
{
    BackCalibration=true;
    cConfig->BM->start();
    ui->processLabel->setText("Background calibration...");
    ui->Instructions->setText("Wait for background calibration process.");
    cConfig->maskZona.setTo(cv::Scalar::all(0));
    fillConvexPoly(cConfig->maskZona,cConfig->zone,4,cvScalar(255));
}
예제 #5
0
Mat AAM::warpImage(Mat image, vector<int> points)
{
    imshow("before warp", image);
    //cout<<"imege to warp type: "<<image.type()<<endl;
    Mat warp_final = Mat::zeros( image.rows, image.cols, image.type() );
    vector<Vec6f> trianglesList;
    this->meanShapeTriangulation.getTriangleList(trianglesList);
    for(int i=0; i<trianglesList.size(); i++)
    {
        Point p1(cvRound(trianglesList[i][0]), cvRound(trianglesList[i][1]));
        Point p2(cvRound(trianglesList[i][2]), cvRound(trianglesList[i][3]));
        Point p3(cvRound(trianglesList[i][4]), cvRound(trianglesList[i][5]));
        //cout<<"trinagle: "<<i<<"  "<<p1<<" "<<p2<<" "<<p3<<endl;
        if(isPointOnImage(p1, image.cols, image.rows) && isPointOnImage(p2, image.cols, image.rows) && isPointOnImage(p3, image.cols, image.rows))
        {
            Mat warp_mask = Mat::zeros( image.rows, image.cols, image.type() );
            Mat warp_dst = Mat::zeros( image.rows, image.cols, image.type() );
            //cout<<"p1: "<<p1<<endl;
           // cout<<"p2: "<<p2<<endl;
           // cout<<"p3: "<<p3<<endl;
            Point2f verticesDst[3];
            verticesDst[0]=p1;
            verticesDst[1]=p2;
            verticesDst[2]=p3;
            Point2f verticesSrc[3];
            int p1num=this->meanShapePointsOrder[p1];
            int p2num=this->meanShapePointsOrder[p2];
            int p3num=this->meanShapePointsOrder[p3];
            //cout<<"p1num: "<<p1num<<endl;
            //cout<<"p2num: "<<p2num<<endl;
            //cout<<"p3num: "<<p3num<<endl;
            verticesSrc[0]=Point(points[2*p1num], points[2*p1num+1]);
            verticesSrc[1]=Point(points[2*p2num], points[2*p2num+1]);
            verticesSrc[2]=Point(points[2*p3num], points[2*p3num+1]);
            //cout<<"dst: "<<verticesDst[0]<<" "<<verticesDst[1]<<" "<<verticesDst[2]<<endl;
            //cout<<"src: "<<verticesSrc[0]<<" "<<verticesSrc[1]<<" "<<verticesSrc[2]<<endl;
            Mat transformationMatrix=findTransformationMatrix(verticesSrc, verticesDst);
            //cout<<"transformation matrix: "<<transformationMatrix<<endl;
            warpAffine(image, warp_dst, transformationMatrix, warp_dst.size());
            imshow("warped", warp_dst);
            Point trianglePoints[3];
            trianglePoints[0]=verticesDst[0];
            trianglePoints[1]=verticesDst[1];
            trianglePoints[2]=verticesDst[2];
            fillConvexPoly(warp_mask, trianglePoints, 3, CV_RGB(255,255,255), CV_AA, 0 );
            //imshow("warp mask", warp_mask);
            warp_dst.copyTo(warp_final,warp_mask);
        }
    }
    imshow("warp final", warp_final);
    return warp_final;
}
예제 #6
0
void cameraSettings2d::on_calcPlane_released()
{
    if(cConfig->zoneSelected){
        doPlaneCalculation=true;
        ui->processLabel->setText("RANSAC Plane Fitting...");
        ui->Instructions->setText("Wait for the process to finish.");
        cConfig->maskZona.setTo(cv::Scalar::all(0));
        fillConvexPoly(cConfig->maskZona,cConfig->zone,4,cvScalar(255));
    }
    else{
        ui->Instructions->setText("In order to do plane fit calculation \nyou must first select the valid zone.");
    }
}
예제 #7
0
  cv::Mat TextLine::drawDebugImage(cv::Mat baseImage) {
    cv::Mat debugImage(baseImage.size(), baseImage.type());

    baseImage.copyTo(debugImage);

    cv::cvtColor(debugImage, debugImage, CV_GRAY2BGR);


    fillConvexPoly(debugImage, linePolygon.data(), linePolygon.size(), Scalar(0,0,165));

    fillConvexPoly(debugImage, textArea.data(), textArea.size(), Scalar(125,255,0));

    line(debugImage, topLine.p1, topLine.p2, Scalar(255,0,0), 1);
    line(debugImage, bottomLine.p1, bottomLine.p2, Scalar(255,0,0), 1);

    line(debugImage, charBoxTop.p1, charBoxTop.p2, Scalar(0,125,125), 1);
    line(debugImage, charBoxLeft.p1, charBoxLeft.p2, Scalar(0,125,125), 1);
    line(debugImage, charBoxRight.p1, charBoxRight.p2, Scalar(0,125,125), 1);
    line(debugImage, charBoxBottom.p1, charBoxBottom.p2, Scalar(0,125,125), 1);


    return debugImage;
  }
	void findGoodCorners2(const Mat &grayFrame, const SoccerPitchData &data, Mat &currToKeyTrans, Mat &keyToTopTrans) {
		Mat topToCurrTrans;
		invert(keyToTopTrans * currToKeyTrans, topToCurrTrans);
		vector<Point2f> imagePitchOuterContour;
		perspectiveTransform(data.pitchOuterPoints, imagePitchOuterContour, topToCurrTrans);

		vector<Point2f> hull;
		convexHull(imagePitchOuterContour, hull);

		Mat mask = Mat::zeros(frameSize, CV_8UC1);
		fillConvexPoly(mask, vector<Point>(hull.begin(), hull.end()), Scalar(1, 0, 0));

		dilate(mask, mask, getStructuringElement(MORPH_ELLIPSE, Size(3, 3)));

		Mat bin;
		adaptiveThreshold(grayFrame, bin, 255, ADAPTIVE_THRESH_MEAN_C , THRESH_BINARY, 5, -10);
		
		vector<Point2f> candidateCorners;
		goodFeaturesToTrack(bin, candidateCorners, 100, 0.01, 24, mask);

		cornerSubPix(bin, candidateCorners, Size(5, 5), Size(-1, -1), TermCriteria(CV_TERMCRIT_EPS & CV_TERMCRIT_ITER, 40, 0.001));

		vector<Point2f> goodPoints;
		for (Point2f corner : candidateCorners) {
			if (goodCornerCheck(corner, bin) && !closeToBoundary(corner))
				goodPoints.push_back(corner);
		}

		if (goodPoints.size() > 0) {
			vector<Point2f> reprojGoodPoints;
			perspectiveTransform(goodPoints, reprojGoodPoints, keyToTopTrans * currToKeyTrans);
			// try to add these new corners into the relocatedCorners
			for (int i = 0; i < reprojGoodPoints.size(); i++) {
				// if does not exists already and coincide with reproj of 28 points
				bool exists = hasSimilarPoint(relocatedPitchPoints, reprojGoodPoints[i], 10) ;
				int minId = findClosestPoint(data.pitchPoints, reprojGoodPoints[i]);
				double minDist = norm(reprojGoodPoints[i] - data.pitchPoints[minId]);
				if ((!exists ) && (minDist < 16) && (minDist < reprojErr[minId])) {
					relocatedCorners.push_back(goodPoints[i]);
					relocatedPitchPoints.push_back(data.pitchPoints[minId]);
					reprojErr[minId] = minDist;
				}
			}
		}

		cout<<relocatedCorners.size()<<" points relocated"<<endl;
	}
예제 #9
0
파일: delaunay.cpp 프로젝트: tracedev/legit
void fillconvex(Mat& image, Point2f* points, int count, Scalar color) {

    Point2f* hull;
    int size = convex_hull(points, count, &hull);

    // apparently we have to convert Point2f array to integers ...
    Point* hulli = new Point[size];

    for (int i = 0; i < size; i++) {
        hulli[i].x = (int) hull[i].x;
        hulli[i].y = (int) hull[i].y;
    }

    free(hull);

    fillConvexPoly(image, hulli, size, color, 1);

    delete [] hulli;

}
예제 #10
0
Mat vehicle_det::get_mask(Mat & src)
{
    //cout<<__PRETTY_FUNCTION__<<endl;
    /* ROI by creating mask for the parallelogram */
    Mat mask = Mat(src.rows, src.cols, CV_8UC1);

    // Create black image with the same size as the original
    for(int i = 0; i < mask.cols; i++)
        for(int j = 0; j < mask.rows; j++)
        {
            mask.at<uchar>(Point(i, j)) = 0;
        }

    // Create Polygon from vertices
    vector<Point> ROI_Poly;
    approxPolyDP(ROI_Vertices, ROI_Poly, 1.0, true);
    // Fill polygon white
    fillConvexPoly(mask, &ROI_Poly[0], ROI_Poly.size(), 255, 8, 0);
    // Cut out ROI and store it in imageDest
    return mask;
}
예제 #11
0
CharacterSegmenter::CharacterSegmenter(Mat img, bool invertedColors, Config* config)
{

  this->config = config;
  
  this->confidence = 0;
 
  if (this->config->debugCharSegmenter)
    cout << "Starting CharacterSegmenter" << endl;
  
  //CharacterRegion charRegion(img, debug);
  
  timespec startTime;
  getTime(&startTime);

  
  Mat img_gray(img.size(), CV_8U);
  cvtColor( img, img_gray, CV_BGR2GRAY );
  //normalize(img_gray, img_gray, 0, 255, CV_MINMAX );
  medianBlur(img_gray, img_gray, 3);
  
  if (invertedColors)
    bitwise_not(img_gray, img_gray);
  
  
  charAnalysis = new CharacterAnalysis(img_gray, config);
  charAnalysis->analyze();
  
  
  
  if (this->config->debugCharSegmenter)
  {
      displayImage(config, "CharacterSegmenter  Thresholds", drawImageDashboard(charAnalysis->thresholds, CV_8U, 3));
  }
  

  
  
  

  if (this->config->debugCharSegmenter)
  {
      
    Mat img_contours(charAnalysis->bestThreshold.size(), CV_8U);
    charAnalysis->bestThreshold.copyTo(img_contours);
    cvtColor(img_contours, img_contours, CV_GRAY2RGB);
    
    vector<vector<Point> > allowedContours;
    for (int i = 0; i < charAnalysis->bestContours.size(); i++)
    {
	if (charAnalysis->bestCharSegments[i])
	  allowedContours.push_back(charAnalysis->bestContours[i]);
    }
    
    drawContours(img_contours, charAnalysis->bestContours,
	    -1, // draw all contours
	    cv::Scalar(255,0,0), // in blue
	    1); // with a thickness of 1
    
    drawContours(img_contours, allowedContours,
	    -1, // draw all contours
	    cv::Scalar(0,255,0), // in green
	    1); // with a thickness of 1
    
    if (charAnalysis->linePolygon.size() > 0)
    {
      line(img_contours, charAnalysis->linePolygon[0], charAnalysis->linePolygon[1], Scalar(255, 0, 255), 1);
      line(img_contours, charAnalysis->linePolygon[3], charAnalysis->linePolygon[2], Scalar(255, 0, 255), 1);
    }
    
    Mat bordered = addLabel(img_contours, "Best Contours");
    imgDbgGeneral.push_back(bordered);
  }
  
  // Figure out the average character width
  float totalCharWidth = 0;
  float totalCharHeight = 0;
  
  if (charAnalysis->linePolygon.size() > 0)
  {
    this->top = LineSegment(charAnalysis->linePolygon[0].x, charAnalysis->linePolygon[0].y, charAnalysis->linePolygon[1].x, charAnalysis->linePolygon[1].y);
    this->bottom = LineSegment(charAnalysis->linePolygon[3].x, charAnalysis->linePolygon[3].y, charAnalysis->linePolygon[2].x, charAnalysis->linePolygon[2].y);
    
    for (int i = 0; i < charAnalysis->bestContours.size(); i++)
    {
	if (charAnalysis->bestCharSegments[i] == false)
	  continue;
	
	Rect mr = boundingRect(charAnalysis->bestContours[i]);
	totalCharWidth += mr.width;
	totalCharHeight += mr.height;
    }
    
    int numSamples = charAnalysis->bestCharSegmentsCount;
    float avgCharWidth = totalCharWidth / numSamples;
    float avgCharHeight = totalCharHeight / numSamples;
  
    removeSmallContours(charAnalysis->thresholds, charAnalysis->allContours, avgCharWidth, avgCharHeight);
  
    // Do the histogram analysis to figure out char regions
    
    
    timespec startTime;
    getTime(&startTime);

    
    vector<Mat> allHistograms;
    
    vector<Rect> allBoxes;
    for (int i = 0; i < charAnalysis->allContours.size(); i++)
    {


      Mat histogramMask = Mat::zeros(charAnalysis->thresholds[i].size(), CV_8U);

      fillConvexPoly(histogramMask, charAnalysis->linePolygon.data(), charAnalysis->linePolygon.size(), Scalar(255,255,255));
      
      
      VerticalHistogram vertHistogram(charAnalysis->thresholds[i], histogramMask);
      

      if (this->config->debugCharSegmenter)
      {
	Mat histoCopy(vertHistogram.debugImg.size(), vertHistogram.debugImg.type());
	//vertHistogram.copyTo(histoCopy);
	cvtColor(vertHistogram.debugImg, histoCopy, CV_GRAY2RGB);
	allHistograms.push_back(histoCopy);
      }

//       
      float score = 0;
      vector<Rect> charBoxes = getHistogramBoxes(vertHistogram.debugImg, avgCharWidth, avgCharHeight, &score); 
      
      
      if (this->config->debugCharSegmenter)
      {
	for (int cboxIdx = 0; cboxIdx < charBoxes.size(); cboxIdx++)
	{
	    rectangle(allHistograms[i], charBoxes[cboxIdx], Scalar(0, 255, 0));
	}
	
	Mat histDashboard = drawImageDashboard(allHistograms, allHistograms[0].type(), 3);
	displayImage(config, "Char seg histograms", histDashboard);
      }
      
      for (int z = 0; z < charBoxes.size(); z++)
	allBoxes.push_back(charBoxes[z]);
      //drawAndWait(&histogramMask);
    }
    

    float biggestCharWidth = avgCharWidth;
    // Compute largest char width
    for (int i = 0; i < allBoxes.size(); i++)
    {
      if (allBoxes[i].width > biggestCharWidth)
	biggestCharWidth = allBoxes[i].width;
    }
      

    if (config->debugTiming)
    {
      timespec endTime;
      getTime(&endTime);
      cout << "  -- Character Segmentation Create and Score Histograms Time: " << diffclock(startTime, endTime) << "ms." << endl;
    }
    
    //ColorFilter colorFilter(img, charAnalysis->getCharacterMask());    
    vector<Rect> candidateBoxes = getBestCharBoxes(charAnalysis->thresholds[0], allBoxes, biggestCharWidth);
    
    
    if (this->config->debugCharSegmenter)
    {
	// Setup the dashboard images to show the cleaning filters
      for (int i = 0; i < charAnalysis->thresholds.size(); i++)
      {
	Mat cleanImg = Mat::zeros(charAnalysis->thresholds[i].size(), charAnalysis->thresholds[i].type());
	Mat boxMask = getCharBoxMask(charAnalysis->thresholds[i], candidateBoxes);
	charAnalysis->thresholds[i].copyTo(cleanImg);
	bitwise_and(cleanImg, boxMask, cleanImg);
	cvtColor(cleanImg, cleanImg, CV_GRAY2BGR);
	
	for (int c = 0; c < candidateBoxes.size(); c++)
	  rectangle(cleanImg, candidateBoxes[c], Scalar(0, 255, 0), 1);
	imgDbgCleanStages.push_back(cleanImg);
      }
    }
    
    
    getTime(&startTime);
    
    filterEdgeBoxes(charAnalysis->thresholds, candidateBoxes, biggestCharWidth, avgCharHeight);
    
    candidateBoxes = filterMostlyEmptyBoxes(charAnalysis->thresholds, candidateBoxes);
 
    candidateBoxes = combineCloseBoxes(candidateBoxes, biggestCharWidth);

    cleanCharRegions(charAnalysis->thresholds, candidateBoxes);
    cleanMostlyFullBoxes(charAnalysis->thresholds, candidateBoxes);
    
    //cleanBasedOnColor(thresholds, colorFilter.colorMask, candidateBoxes);
    
    candidateBoxes = filterMostlyEmptyBoxes(charAnalysis->thresholds, candidateBoxes);
    this->characters = candidateBoxes;
    
    if (config->debugTiming)
    {
      timespec endTime;
      getTime(&endTime);
      cout << "  -- Character Segmentation Box cleaning/filtering Time: " << diffclock(startTime, endTime) << "ms." << endl;
    }
    
    if (this->config->debugCharSegmenter)
    {
      
      
      Mat imgDash = drawImageDashboard(charAnalysis->thresholds, CV_8U, 3);
      displayImage(config, "Segmentation after cleaning", imgDash);
      
      Mat generalDash = drawImageDashboard(this->imgDbgGeneral, this->imgDbgGeneral[0].type(), 2);
      displayImage(config, "Segmentation General", generalDash);
      
      Mat cleanImgDash = drawImageDashboard(this->imgDbgCleanStages, this->imgDbgCleanStages[0].type(), 3);
      displayImage(config, "Segmentation Clean Filters", cleanImgDash);
    }
  }
  
  
  
  
  
  
  if (config->debugTiming)
  {
    timespec endTime;
    getTime(&endTime);
    cout << "Character Segmenter Time: " << diffclock(startTime, endTime) << "ms." << endl;
  }
}
예제 #12
0
void cameraSettings2d::hacerUpdate(){
    ///ACA UPDATE DE TODO LO QUE SE NECESITA
    camUpdate();
    if(isUpdated){
        if(zoneSelection){
            if(numSelectedPoints<4){
                if(ui->glImage->isNewClick){
                cConfig->zone[numSelectedPoints].x=ui->glImage->lastPos.x()*640/ui->glImage->width();
                cConfig->zone[numSelectedPoints].y=ui->glImage->lastPos.y()*480/ui->glImage->height();
                //cout << cConfig->zone[numSelectedPoints].x << "," << cConfig->zone[numSelectedPoints].y << endl;
                numSelectedPoints++;
                ui->glImage->isNewClick=false;
                ui->progressBar->setValue(numSelectedPoints*25);
                }
            }
            else{
                numSelectedPoints=0;
                zoneSelection=false;
                cConfig->zoneSelected=true;
                ui->processLabel->setText("Idle process");
                ui->progressBar->setValue(0);
                ui->Instructions->setText("Nothing to do...");
                cConfig->maskZona.setTo(cv::Scalar::all(0));
                fillConvexPoly(cConfig->maskZona,cConfig->zone,4,cvScalar(255));
                Mat temp=cConfig->maskBack & cConfig->maskZona;
                ui->imgMaskBack->updateImage(false,temp);
                ui->imgMaskPlane->updateImage(false,cConfig->maskZona);
            }
        }
        if(mixImagesToColor()){
            if(BackCalibration){
                if(!cConfig->BM->proc(cConfig->variance,depthsS[nC],masks[nC],cConfig->Background,cConfig->maskBack)){
                    ui->progressBar->setValue(((float)cConfig->BM->nback/(cConfig->BM->total+1))*100);
                }
                else{
                    BackCalibration=false;
                    ui->processLabel->setText("Idle process");
                    ui->progressBar->setValue(0);
                    ui->Instructions->setText("Nothing to do...");
                    Mat temp0,temp1;
                    cConfig->Background.convertTo(temp0,CV_8UC1,255);
                    if(cConfig->zoneSelected)
                        temp1=cConfig->maskBack & cConfig->maskZona;
                    else
                        temp1=cConfig->maskBack;
                    ui->imgBack->updateImage(false,temp0);
                    ui->imgMaskBack->updateImage(false,temp1);
                }
            }
            if(zoneSelection){
                for(int cir=0;cir<numSelectedPoints;cir++)
                    circle(mixs[nC],cConfig->zone[cir],10,Scalar(0,0,255),-1);
            }
            else if(cConfig->zoneSelected){
                int *num=new int[1];
                num[0]=4;
                const Point* ptt[1] = { cConfig->zone };
                polylines(mixs[nC],ptt,num,1,1,cvScalar(255),2);
                delete num;
            }
            if(doPlaneCalculation){
                cam->retrivePointCloud(nC,depths[nC],pCs[nC]);
                cConfig->VP->calcPlanoPC(pCs[nC],cConfig->maskZona,masks[nC],ui->progressBar);
                doPlaneCalculation=false;
                ui->processLabel->setText("Idle process");
                ui->progressBar->setValue(0);
                ui->Instructions->setText("Nothing to do...");
            }
            ui->glImage->updateImage(true,mixs[nC]);
            if(cConfig->method=="Background"){
                sktP->processImage(depthsS[nC],toBlobs,masks[nC]);
            }
            else{
                cam->retrivePointCloud(nC,depths[nC],pCs[nC]);
                sktP->processImage(pCs[nC],toBlobs,masks[nC]);
            }
            ui->glBlobs->updateImage(false,toBlobs);
        }
        if(refiningMask){
            if(cConfig->method=="Background"){
                cConfig->maskBack=(cConfig->maskBack==255) & (toBlobs==0);
                cConfig->maskZona=(cConfig->maskZona==255) & (toBlobs==0);
                ui->imgMaskBack->updateImage(false,cConfig->maskBack);
            }
            else{
                cConfig->maskZona=(cConfig->maskZona==255) & (toBlobs==0);
                ui->imgMaskPlane->updateImage(false,cConfig->maskZona);
            }
        }
    }
    ////////////////////Procesamiento
    isUpdated=false;
}
예제 #13
0
void Target::findLaser(Mat imgInput, Mat *imgOutput)
{
	Mat hsv_img, binary, cont, imgCopy;
	imgCopy = imgInput;
	
	cvtColor(imgCopy, hsv_img, CV_BGR2HSV);

	Mat imgThresholded;
	int iLowH = colorRatio[0];
	int iHighH = colorRatio[1];

	int iLowS = colorRatio[2];
	int iHighS = colorRatio[3];

	int iLowV = colorRatio[4];
	int iHighV = colorRatio[5];
	inRange(hsv_img, Scalar(iLowH, iLowS, iLowV), Scalar(iHighH, iHighS, iHighV), imgThresholded); //Threshold the image

	//morphological opening (remove small objects from the foreground)
	erode(imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
	dilate(imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));

	//morphological closing (fill small holes in the foreground)
	dilate(imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
	erode(imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));

	binary = imgThresholded;
	vector<vector<Point>> contours;
	vector<Point> contours_poly;
	Rect boundRect;
	binary.copyTo(cont);
	findContours(cont, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
	int max = 0, i_cont = -1;
	Mat drawing = Mat::zeros(cont.size(), CV_8UC3);
	for (int i = 0; i< contours.size(); i++)
	{
		if (abs(contourArea(Mat(contours[i]))) > max)
		{
			max = abs(contourArea(Mat(contours[i])));
			i_cont = i;
		}
	}
	if (i_cont >= 0)
	{
		approxPolyDP(Mat(contours[i_cont]), contours_poly, 3, true);
		boundRect = boundingRect(Mat(contours_poly));
		fillConvexPoly(imgCopy, contours_poly, contours_poly.size());
		rectangle(imgCopy, boundRect.tl(), boundRect.br(), Scalar(125, 250, 125), 2, 8, 0);
		line(imgCopy, boundRect.tl(), boundRect.br(), Scalar(250, 125, 125), 2, 8, 0);
		line(imgCopy, Point(boundRect.x + boundRect.width, boundRect.y), Point(boundRect.x, boundRect.y + boundRect.height), Scalar(250, 125, 125), 2, 8, 0);
		string s;
		stringstream out;
		out << boundRect.x + boundRect.width / 2 << "x" << boundRect.y + boundRect.height / 2;
		Point contour_center;
		contour_center.x = boundRect.x + boundRect.width / 2;
		contour_center.y = boundRect.y + boundRect.height / 2;
		*laser = contour_center;
		s = out.str();
		putText(imgCopy, s, Point(50, 50), CV_FONT_HERSHEY_COMPLEX, 1, Scalar(20, 40, 80), 3, 8);
		drawContours(drawing, contours, i_cont, Scalar(125, 125, 250), 2);
	}
	*imgOutput = imgCopy;
	//imshow("kolory", binary);
	
}
예제 #14
0
void FindContour::singleCellDetection(const Mat &img, vector<Point> &cir_org,
                                      Mat &dispImg1, Mat &dispImg2,
                                      int &area, int &perimeter,
                                      Point2f &ctroid, float &shape,
                                      Mat &cell_alpha, // only the area inside cell (without background)
                                      vector<Point> &smooth_contour_curve, // relative position (without counting rect.x and rect.y)
                                      vector<Point> &smooth_contour_curve_abs, // absolut position
                                      Mat &blebsImg,
                                      Rect &rectangle,
                                      //vector<int> &blebs,
                                      int &frameNum)
{
    frame = &img;

    vector<Point> cir; //***global coordinates of circle***
    //cout << "[";
    for(unsigned int i = 0; i < cir_org.size(); i++){
        cir.push_back(Point(cir_org[i].x / scale, cir_org[i].y / scale));
        //cout << int(cir_org[i].x / scale) << ", " << int(cir_org[i].y / scale) << "; ";
    }
    //cout << "]" << endl;

    //enlarge the bounding rect by adding a margin (e) to it
    rect = enlargeRect(boundingRect(Mat(cir)), 5, img.cols, img.rows);
    //cout << "rect_roi " << boundingRect(Mat(cir)) << "\n";
    //cout << "enlarged rect " << rect << endl;

    dispImg1 = (*frame)(rect).clone();

    Mat sub; //*** the rectangle region of ROI (Gray) ***
    cv::cvtColor(dispImg1, sub, CV_RGB2GRAY);
    int width = sub.cols;
    int height = sub.rows;

    rectangle = rect;

//    Mat canny;
//    CannyWithBlur(sub, canny);
//    imshow("canny", canny);

    vector<Point> circle_ROI; //***local coordinates of circle***
    for (unsigned int i = 0; i < cir.size(); i++){
        Point p = Point(cir[i].x - rect.x, cir[i].y - rect.y);
        circle_ROI.push_back(p);
    }

    Mat adapThreshImg1 = Mat::zeros(height, width, sub.type());
    //image edge detection for the sub region (roi rect)
    adaptiveThreshold(sub, adapThreshImg1, 255.0, ADAPTIVE_THRESH_GAUSSIAN_C,
                          CV_THRESH_BINARY_INV, blockSize, constValue);
    //imshow("adapThreshImg1", adapThreshImg1);

    // dilation and erosion
    Mat dilerod;
    dilErod(adapThreshImg1, dilerod, dilSize);

    //display image 2 -- dilerod of adaptive threshold image
    GaussianBlur(dilerod, dilerod, Size(3, 3), 2, 2 );

    //mask for filtering out the cell of interest
    Mat mask_conv = Mat::zeros(height, width, CV_8UC1);
    fillConvexPoly(mask_conv, circle_ROI, Scalar(255));
    //imshow("mask_before", mask_conv);

    //dilate the mask -> region grows
    Mat mask_conv_dil;
    Mat element = getStructuringElement( MORPH_ELLIPSE,
                                         Size( 2*dilSize+1, 2*dilSize+1 ),
                                         Point(dilSize,dilSize) );
    dilate(mask_conv, mask_conv_dil, element);
    //imshow("mask_dil", mask_conv_dil);

    //bitwise AND on mask and dilerod
    bitwise_and(mask_conv_dil, dilerod, dispImg2);

    // findcontours
    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;
    unsigned int largest_contour_index;
    dilErodContours(dispImg2, contours, hierarchy, largest_contour_index, perimeter, dispImg1);

    // find the area of the cell by counting the white area inside the largest contour
    Mat cellArea = Mat::zeros(height, width, CV_8UC1);
    drawContours(cellArea, contours, largest_contour_index, Scalar(255), -1, 8, hierarchy, 0, Point() );
    //imshow("cellArea", cellArea);
    area = countNonZero(cellArea);

    //cout << "frame " << frameNum << "\n";
    //cout << contours[largest_contour_index] << endl;

    //renew circle points as the convex hull
    vector<Point> convHull;
    convexHull(contours[largest_contour_index], convHull);

    // find the centroid of the contour
    Moments mu = moments(contours[largest_contour_index]);
    ctroid = Point2f(mu.m10/mu.m00 + rect.x, mu.m01/mu.m00 + rect.y);

    // find the shape of the cell by the largest contour and centroid
    shape = findShape(ctroid, contours[largest_contour_index]);

    ////---- draw largest contour start ----
    //draw the largest contour
    Mat borderImg = Mat::zeros(height, width, CV_8UC1);
    drawContours(borderImg, contours, largest_contour_index, Scalar(255), 1, 8, hierarchy, 0, Point());
    //QString cellFileName0 = "border" + QString::number(frameNum) + ".png";
    //imwrite(cellFileName0.toStdString(), borderImg);


    Mat cell;
    bitwise_and(cellArea, sub, cell);
    //cell_alpha = createAlphaMat(cell);  // cell image with exactly the contour detected
    //vector<int> compression_params;
    //compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);
    //compression_params.push_back(9);
//    QString cellFileName1 = "cell" + QString::number(frameNum) + ".png";
//    imwrite(cellFileName1.toStdString(), cell_alpha, compression_params);
    ////---- draw largest contour end ----

    // find the number and the sizes of blebs of the cell
    Mat smooth;
    vector<Point> smoothCurve;
    int WIN = 25;
    smooth = curveSmooth(borderImg, WIN, contours[largest_contour_index], smoothCurve, convHull);
    //smooth = curveSmooth(borderImg, WIN, contours[largest_contour_index], smoothCurve, ctroid/*Point(ctroid.x, ctroid.y)*/);
    //drawPointVectors(dispImg1, smoothCurve, 1, Scalar(159, 120, 28));


    Mat smooth_contour;
    int w = 10;
    smooth_contour = curveSmooth(borderImg, w, contours[largest_contour_index], smooth_contour_curve, convHull);
    //smooth_contour = curveSmooth(borderImg, w, contours[largest_contour_index], smooth_contour_curve, ctroid/*Point(ctroid.x, ctroid.y)*/);
    //imshow("smooth_contour", smooth_contour);

    for(unsigned int i = 0; i < smooth_contour_curve.size(); i++){
         Point p(smooth_contour_curve[i].x + rect.x, smooth_contour_curve[i].y + rect.y);
         smooth_contour_curve_abs.push_back(p);
    }

//    cout << "ctroid X " << ctroid.x << " Y " << ctroid.y << endl;
////    for(unsigned int i = 0; i < contours[largest_contour_index].size(); i++)
////        cout << "(" << contours[largest_contour_index][i].x + rect.x << ", " << contours[largest_contour_index][i].y + rect.y << ") ";
////    cout << endl;
//    for(unsigned int i = 0; i < smooth_contour_curve_abs.size(); i++)
//        cout << "(" << smooth_contour_curve_abs[i].x << ", " << smooth_contour_curve_abs[i].y << ") ";
//    cout << endl;

    //cout << mask_conv_dil.type() << " " << sub.type() << endl;
    Mat cell_convex;
    bitwise_and(smooth_contour, sub, cell_convex);
    cell_alpha = createAlphaMat(cell_convex);
//    imshow("cell_convex_contour", cell_alpha);
    dispImg2 = cell_convex.clone();

    //change dispImg2 from gray to rgb for displaying
    cvtColor(dispImg2, dispImg2, CV_GRAY2RGB);

    bitwise_not(smooth, smooth);
    //Mat blebsImg;
    bitwise_and(smooth, cellArea, blebsImg);
//    imshow("blebs", blebsImg);
//    QString cellFileName2 = "blebs" + QString::number(frameNum) + ".png";
//    imwrite(cellFileName2.toStdString(), blebs);

    //QString cellFileName2 = "dispImg1" + QString::number(frameNum) + ".png";
    //imwrite(cellFileName2.toStdString(), dispImg1);

    cir_org.clear();
    for(unsigned int i = 0; i < convHull.size(); i++)
        cir_org.push_back(Point((convHull[i].x + rect.x)*scale, (convHull[i].y + rect.y)*scale));
}
예제 #15
0
// get ROI + edgeDectection
void FindContour::cellDetection(const Mat &img, vector<Point> &cir_org,
                                Mat &dispImg1, Mat &dispImg2,
                                vector<Point2f> &points1, vector<Point2f> &points2,
                                int &area,
                                int &perimeter,
                                Point2f &ctroid,
                                float &shape,
//                                vector<int> &blebs,
                                int &frameNum){
    frame = &img;
    //rect = boundingRect(Mat(cir));


    Mat frameGray;
    cv::cvtColor(*frame, frameGray, CV_RGB2GRAY);
/*
    QString cellFileName0 = "frame" + QString::number(frameNum) + ".png";
    imwrite(cellFileName0.toStdString(), frameGray);*/

    vector<Point> cir; //***global coordinates of circle***
    for(unsigned int i = 0; i < cir_org.size(); i++){
        cir.push_back(Point(cir_org[i].x / scale, cir_org[i].y / scale));
    }
    //cout << "original circle: " << cir_org << "\n" << " scaled circle: " << cir << endl;

    //enlarge the bounding rect by adding a margin (e) to it
    rect = enlargeRect(boundingRect(Mat(cir)), 5, img.cols, img.rows);

    //global circle mask
    Mat mask_cir_org = Mat::zeros(frame->size(), CV_8UC1);
    fillConvexPoly(mask_cir_org, cir, Scalar(255));

    // flow points
    vector<unsigned int> cell_pts_global;
    vector<Point2f> longOptflow_pt1, longOptflow_pt2;
    Point2f avrg_vec = Point2f(0,0);
    for(unsigned int i = 0; i < points1.size(); i++){
        Point p1 = Point(points1[i].x, points1[i].y);
        Point p2 = Point(points2[i].x, points2[i].y);
        if(mask_cir_org.at<uchar>(p1.y,p1.x) == 255 ){
            cell_pts_global.push_back(i);
            if(dist_square(p1, p2) > 2.0){
                longOptflow_pt1.push_back(Point2f(p1.x, p1.y));
                longOptflow_pt2.push_back(Point2f(p2.x, p2.y));
                avrg_vec.x += (p2.x-p1.x);
                avrg_vec.y += (p2.y-p1.y);
            }
        }
    }

//    if(longOptflow_pt1.size()!= 0){
//        avrg_vec.x = avrg_vec.x / longOptflow_pt1.size();
//        avrg_vec.y = avrg_vec.y / longOptflow_pt1.size();
//    }
    Rect trans_rect = translateRect(rect, avrg_vec);


    // ***
    // if (the homography is a good one) use the homography to update the rectangle
    // otherwise use the same rectangle
    // ***
    if (longOptflow_pt1.size() >= 4){
        Mat H = findHomography(Mat(longOptflow_pt1), Mat(longOptflow_pt2), CV_RANSAC, 2);
        //cout << "H: " << H << endl;

        if(determinant(H) >= 0){
            vector<Point> rect_corners;
            rect_corners.push_back(Point(rect.x, rect.y));
            rect_corners.push_back(Point(rect.x+rect.width, rect.y));
            rect_corners.push_back(Point(rect.x, rect.y+rect.height));
            rect_corners.push_back(Point(rect.x+rect.width, rect.y+rect.height));

            vector<Point> rect_update_corners = pointTransform(rect_corners, H);
            trans_rect = boundingRect(rect_update_corners);
        }
    }


    rectangle(frameGray, trans_rect, Scalar(255), 2);
    imshow("frameGray", frameGray);









    dispImg1 = (*frame)(rect).clone();
    //dispImg2 = Mat(dispImg1.rows, dispImg1.cols, CV_8UC3);

    Mat sub; //*** the rectangle region of ROI (Gray) ***
    cv::cvtColor(dispImg1, sub, CV_RGB2GRAY);
    int width = sub.cols;
    int height = sub.rows;

    vector<Point> circle_ROI; //***local coordinates of circle***
    for (unsigned int i = 0; i < cir.size(); i++){
        Point p = Point(cir[i].x - rect.x, cir[i].y - rect.y);
        circle_ROI.push_back(p);
    }

    Mat adapThreshImg1 = Mat::zeros(height, width, sub.type());
    //image edge detection for the sub region (roi rect)
    adaptiveThreshold(sub, adapThreshImg1, 255.0, ADAPTIVE_THRESH_GAUSSIAN_C,
                          CV_THRESH_BINARY_INV, blockSize, constValue);
    //imshow("adapThreshImg1", adapThreshImg1);

    // dilation and erosion
    Mat dilerod;
    dilErod(adapThreshImg1, dilerod, dilSize);

    //display image 2 -- dilerod of adaptive threshold image
    GaussianBlur(dilerod, dilerod, Size(3, 3), 2, 2 );

    //mask for filtering out the cell of interest
    Mat mask_conv = Mat::zeros(height, width, CV_8UC1);
    fillConvexPoly(mask_conv, circle_ROI, Scalar(255));
    //imshow("mask_before", mask_conv);

    //dilate the mask -> region grows
    Mat mask_conv_dil;
    Mat element = getStructuringElement( MORPH_ELLIPSE, Size( 2*2+2, 2*2+1 ), Point(2,2) );
    dilate(mask_conv, mask_conv_dil, element);
    //imshow("mask_dil", mask_conv_dil);



    /*
    Mat mask_conv_ero;
    erode(mask_conv, mask_conv_ero, element);
    Mat ring_dil, ring_ero;
    bitwise_xor(mask_conv, mask_conv_dil, ring_dil);
    bitwise_xor(mask_conv, mask_conv_ero, ring_ero);
    Mat ring;
    bitwise_or(ring_dil, ring_ero, ring);
    imshow("ring", ring);

    vector<unsigned int> opt_onRing_index;
    // use optflow info set rectangle
    for(unsigned int i = 0; i < points2.size(); i++){
        Point p2 = Point(points2[i].x, points2[i].y);
        Point p1 = Point(points1[i].x, points1[i].y);
        if(ring.at<uchar>(p1.y,p1.x) != 255 &&
                ring.at<uchar>(p2.y,p2.x) != 255)
            continue;
        else{
            opt_onRing_index.push_back(i);
        }
    }*/

    /*
    // draw the optflow on dispImg1
    unsigned int size = opt_inside_cl_index.size();
    for(unsigned int i = 0; i < size; i++ ){
        Point p0( ceil( points1[i].x - rect.x ), ceil( points1[i].y - rect.y ) );
        Point p1( ceil( points2[i].x - rect.x ), ceil( points2[i].y - rect.y) );
        //std::cout << "(" << p0.x << "," << p0.y << ")" << "\n";
        //std::cout << "(" << p1.x << "," << p1.y << ")" << std::endl;

        //draw lines to visualize the flow
        double angle = atan2((double) p0.y - p1.y, (double) p0.x - p1.x);
        double arrowLen = 0.01 * (double) (width);
        line(dispImg1, p0, p1, CV_RGB(255,255,255), 1 );
        Point p;
        p.x = (int) (p1.x + arrowLen * cos(angle + 3.14/4));
        p.y = (int) (p1.y + arrowLen * sin(angle + 3.14/4));
        line(dispImg1, p, p1, CV_RGB(255,255,255), 1 );
        p.x = (int) (p1.x + arrowLen * cos(angle - 3.14/4));
        p.y = (int) (p1.y + arrowLen * sin(angle - 3.14/4));

        line(dispImg1, p, Point(2*p1.x - p0.x, 2*p1.y - p0.y), CV_RGB(255,255,255), 1 );
        //line(dispImg1, p, p1, CV_RGB(255,255,255), 1 );
    }*/

/*
    //stop growing when meeting with canny edges that outside the circle

    Mat canny;
    CannyWithBlur(sub, canny);
    Mat cannyColor;
    cvtColor(canny, cannyColor, CV_GRAY2RGB);
    imwrite("canny.png", canny);
    vector<Point> outsideCircle;
    vector<Point> onRing;
    for(int j = 0; j < height; j++){
        for(int i = 0; i < width; i++){
            if(canny.at<uchar>(j,i) != 0 && mask_conv.at<uchar>(j,i) == 0){
                cannyColor.data[cannyColor.channels()*(cannyColor.cols*j + i)+0] = 81;
                cannyColor.data[cannyColor.channels()*(cannyColor.cols*j + i)+1] = 172;
                cannyColor.data[cannyColor.channels()*(cannyColor.cols*j + i)+2] = 251;
                outsideCircle.push_back(Point(i, j));
                if(ring.at<uchar>(j,i) != 0){
                    cannyColor.data[cannyColor.channels()*(cannyColor.cols*j + i)+0] = 255;
                    cannyColor.data[cannyColor.channels()*(cannyColor.cols*j + i)+1] = 255;
                    cannyColor.data[cannyColor.channels()*(cannyColor.cols*j + i)+2] = 0;
                    onRing.push_back(Point(i,j));
                }
            }
        }
    } */

//    QString cannyFileName = "canny" + QString::number(frameNum) + ".png";
//    imwrite(cannyFileName.toStdString(), cannyColor);



    //bitwise AND on mask and dilerod
    bitwise_and(mask_conv/*_dil*/, dilerod, dispImg2);

    // findcontours
    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;
    unsigned int largest_contour_index;
    dilErodContours(dispImg2, contours, hierarchy, largest_contour_index, perimeter, dispImg1);

    // find the area of the cell by counting the white area inside the largest contour
    Mat cellArea = Mat::zeros(height, width, CV_8UC1);
    drawContours(cellArea, contours, largest_contour_index, Scalar(255), -1, 8, hierarchy, 0, Point() );
    //imshow("cell", cell);
    area = countNonZero(cellArea);

    //cout << "frame " << frameNum << "\n";
    //cout << contours[largest_contour_index] << endl;


    //change dispImg2 from gray to rgb for displaying
    cvtColor(dispImg2, dispImg2, CV_GRAY2RGB);

    //renew circle points as the convex hull
    vector<Point> convHull;
    convexHull(contours[largest_contour_index], convHull);


    // find the centroid of the contour
    Moments mu = moments(contours[largest_contour_index]);
    ctroid = Point2f(mu.m10/mu.m00 + rect.x, mu.m01/mu.m00 + rect.y);

    // find the shape of the cell by the largest contour and centroid
    shape = findShape(ctroid, contours[largest_contour_index]);

    ////---- draw largest contour start ----
    //draw the largest contour
    Mat borderImg = Mat::zeros(height, width, CV_8UC1);
    drawContours(borderImg, contours, largest_contour_index, Scalar(255), 1, 8, hierarchy, 0, Point());
    //QString cellFileName0 = "border" + QString::number(frameNum) + ".png";
    //imwrite(cellFileName0.toStdString(), borderImg);
    ////---- draw largest contour end ----

    // find the number and the sizes of blebs of the cell
    Mat smooth;
    vector<Point> smoothCurve;
    int WIN = 25;
    vector< vector<Point> > tmp;
    smooth = curveSmooth(borderImg, WIN, contours[largest_contour_index], smoothCurve, convHull/*ctroid*/);
    tmp.push_back(smoothCurve);
    drawContours(dispImg1, tmp, 0, Scalar(255, 0, 0));

    bitwise_not(smooth, smooth);
    Mat blebsImg;
    bitwise_and(smooth, cellArea, blebsImg);
    //imshow("blebs", blebs);
    //QString cellFileName2 = "blebs" + QString::number(frameNum) + ".png";
    //imwrite(cellFileName2.toStdString(), blebs);

//    vector<Point> blebCtrs;
//    recursive_connected_components(blebsImg, blebs, blebCtrs);
//    for(unsigned int i = 0; i < blebCtrs.size(); i++){
//        circle(dispImg1, blebCtrs[i], 2, Scalar(255, 255, 0));
//    }


    cir_org.clear();
    for(unsigned int i = 0; i < convHull.size(); i++)
        cir_org.push_back(Point((convHull[i].x + rect.x)*scale, (convHull[i].y + rect.y)*scale));

}
예제 #16
0
Mat FindContour::curveSmooth(Mat &contourImg,
                int WIN, // half window size for laplacian smoothing
                vector<Point> &border,
                vector<Point> &smooth,
                /*Point cntoid*/vector<Point> &convHull )
{
//    if(contourImg.type() != CV_8UC1){
//        cvtColor( contourImg, contourImg, CV_BGR2GRAY );
//    }
    double width = contourImg.cols;
    double height = contourImg.rows;

    Moments mu = moments(convHull);
//    Moments mu = moments(border);
    Point cntoid = Point2f(mu.m10/mu.m00/* + rect.x*/, mu.m01/mu.m00/* +rect.y*/);

    double d_min = max(width, height)*max(width, height);
    vector<polarPoint> border_polar;
    for (unsigned int n = 0; n < border.size(); n++)
    {
        //find the polar coordinates of the border;
        border_polar.push_back(cartesianToPolar(cntoid, border[n]));

        //find the nearest point to the center on the border
        double d = dist(cntoid, border[n]);
        if(d < d_min){
            d_min = d;
        }
    }
    d_min = sqrt(d_min);

    // sort border_polar by theta
    sort(border_polar.begin(), border_polar.end(), sortByTheta);

    // Laplacian smoothing
    unsigned int border_size = border_polar.size();
    for(unsigned int n = 0; n < border_size; n++){
        //cout << border_polar[n].r << " " << border_polar[n].theta << "  ";

        double avg = 0;
        for(int w = -WIN; w < WIN; w++){
            unsigned int pos = std::fabs((w+n+border_size)%border_size);
            //cout << " pos " << pos << "  ";
            avg += border_polar[pos].r;
        }
        avg = avg/WIN/2;
        polarPoint polar;
        polar.r = avg;
        polar.theta = border_polar[n].theta;
        //cout << polar.r << " " << polar.theta << " ";
        Point p = polarToCartesian(cntoid, polar);
        //circle(color, p, 1, Scalar(255, 255, 0));
        smooth.push_back(p);
        //cout << p.x << " " << p.y << "\n";
    }

    Mat smoothCircle = Mat::zeros(height, width, CV_8UC1);
    fillConvexPoly(smoothCircle, smooth, Scalar(255));
//    fillPoly(smoothCircle, smooth, Scalar(255));
    //imshow("smoothCircle", smoothCircle);

    return smoothCircle;
}
예제 #17
0
파일: shape.cpp 프로젝트: tracedev/legit
        void ModalityConvex::update(Image& image, PatchSet* patchSet, Rect bounds) {

            Ptr<PatchSet> patches = Ptr<PatchSet>(reliablePatchesFilter.empty() ? patchSet : patchSet->filter(*reliablePatchesFilter));

            if (patches->size() < 3) {
                //flush();
                return;
            }

            Mat temp = image.get_float_mask();

            temp.setTo(0);

            if (history.empty()) {
                history.create(image.height(), image.width(), CV_32F);
                history.setTo(0);
            }

            Point2f* points = new Point2f[patches->size()];
            Point2f* hull = NULL;

            Point2f offset = Point2f(image.width() / 2, image.height() / 2) - patchSet->mean_position();

            Point2f mean(0, 0);

            for (int i = 0; i < patches->size(); i++) {
                points[i] = patches->get_position(i) + offset;
            }

            int size = convex_hull(points, patches->size(), &hull);

            for (int i = 0; i < size; i++) {
                mean.x += hull[i].x;
                mean.y += hull[i].y;
            }

            mean.x /= size;
            mean.y /= size;

            Point* hulli = new Point[size];
            Point* hullei = new Point[size];

            for (int i = 0; i < size; i++) {
                hulli[i].x = (int) hull[i].x;
                hulli[i].y = (int) hull[i].y;
            }

            expand(hull, size, mean, margin);

            for (int i = 0; i < size; i++) {
                hullei[i].x = (int) hull[i].x;
                hullei[i].y = (int) hull[i].y;
            }

            fillConvexPoly(temp, hullei, size, Scalar(1 - margin_diminish));
            fillConvexPoly(temp, hulli, size, Scalar(1));

            delete [] points;
            free(hull);
            delete [] hulli;
            delete [] hullei;

            history = history * persistence + temp * (1.0f - persistence);


        }
void pxsnsr(vector<vector<Point>> &contours, Mat &Seg_img_red, Mat &Seg_img_blue)
{
	Rect *r = new Rect[contours.size()];   // 定义外接矩形数组
	Mat obj_rec_thr = Mat::zeros(Seg_img_red.size(), CV_8UC3);
	for (unsigned int i = 0; i < contours.size(); i++)
	{
		r[i] = boundingRect(Mat(contours[i]));// boundingRect获取这个外接矩形
	}

	/// 绘出轮廓及其凸包
	Mat Seg_img_blue_hull(Seg_img_blue.size(), CV_8U, Scalar(0));
	vector<vector<Point> >hull(contours.size());
	for (unsigned int i = 0; i< contours.size(); i++)
	{
		convexHull(Mat(contours[i]), hull[i], false);
		fillConvexPoly(Seg_img_blue_hull, &hull[i][0], hull[i].size(), Scalar(1));
	}
	erode(Seg_img_blue_hull, Seg_img_blue_hull, Mat(), Point(-1, -1), dilate_size);   // 对图像进行之前的膨胀恢复
	Seg_img_blue_hull.convertTo(Seg_img_blue_hull, CV_32F);
	imshow("Seg_img_blue _hull", Seg_img_blue_hull);

	double Evaluation = 0;      // 对潜在目标的打分值初始化
	double Evaluation_max = 0;   // 对潜在目标的打分最大值初始化
	int index_best = -1;         // 最优轮廓标记 <注意此处初始值应为-1>
	int index = 0;               // 轮廓标记
	cout << contours.size() << endl;
	vector<vector<Point>>::const_iterator itContours = contours.begin();
	//for (; itContours != contours.end(); ++itContours)
	while (itContours != contours.end())
	{
		Mat imageROI_red = Seg_img_red(cv::Rect(r[index].x, r[index].y, r[index].width, r[index].height));
		Mat imageROI_blue = Seg_img_blue_hull(cv::Rect(r[index].x, r[index].y, r[index].width, r[index].height));

		Mat imageROI_red_blue = imageROI_red + imageROI_blue;
		threshold(imageROI_red_blue, imageROI_red_blue, 1, 1, THRESH_BINARY);   // 进行阈值分割(大于阈值1等于2时候取 1)


		Scalar s1 = sum(imageROI_red_blue);
		Scalar s2 = sum(imageROI_blue);
		double sum_red = s1.val[0];    // 获取图像块包含在蓝色中的红色像素数量
		double sum_blue = s2.val[0];    // 获取图像块中蓝色像素数量
		double pixel_sum_rate = rate(sum_red, sum_blue);  // 计算图像块中红蓝像素的比例
		cout << "sum_red:" << sum_red << "\t" << "," << "sum_blue:" << sum_blue << "\t";
		cout << "pixel_sum_rate:" << pixel_sum_rate << endl;
	    // 将红蓝像素比太低的连通域轮廓删除
		if ((pixel_sum_rate < threshold_value_pixel_rate) || (sum_red < 12))  // 如当前轮廓不含一定的红色像素
		{
			itContours = contours.erase(itContours);  // 删除当前轮廓 <特别注意:删除当前轮廓后迭代器自动指向后一个>
			index++;
			continue;
		}
		else     // 如当前轮廓含一定的红色像素
		{
			int aaa = contours.size();  // 用于设置条件断点

			Evaluation = sum_red;       // 目标轮廓简单评价值定义
			if (Evaluation > Evaluation_max)
			{
				Evaluation_max = Evaluation;
				index_best++;
				cout << "index_best - " << index_best  << endl;
			}
			index++;
			itContours++;  // 继续检索下一个轮廓 <此处必须要代码指定迭代器转向后一个轮廓>
		}	
	}

	int ttt = contours.size();    // 用于设置条件断点
   // 如果仍然有大于一个潜在目标则选取最优的一个
	if (ttt > 1) 
	{
		int index = 0;
		vector<vector<Point>>::const_iterator itContours_2 = contours.begin();
		while(itContours_2 != contours.end())
		{
			if (index != index_best)
				itContours_2 = contours.erase(itContours_2);
			else
				++itContours_2; 
			index++;
		}
	}
	delete[] r;
}
예제 #19
0
  void CharacterAnalysis::filterBetweenLines(Mat img, TextContours& textContours, vector<TextLine> textLines )
  {
    static float MIN_AREA_PERCENT_WITHIN_LINES = 0.88;
    static float MAX_DISTANCE_PERCENT_FROM_LINES = 0.15;

    if (textLines.size() == 0)
      return;

    vector<Point> validPoints;


    // Create a white mask for the area inside the polygon
    Mat outerMask = Mat::zeros(img.size(), CV_8U);

    for (unsigned int i = 0; i < textLines.size(); i++)
      fillConvexPoly(outerMask, textLines[i].linePolygon.data(), textLines[i].linePolygon.size(), Scalar(255,255,255));

    // For each contour, determine if enough of it is between the lines to qualify
    for (unsigned int i = 0; i < textContours.size(); i++)
    {
      if (textContours.goodIndices[i] == false)
        continue;

      float percentInsideMask = getContourAreaPercentInsideMask(outerMask, 
              textContours.contours,
              textContours.hierarchy, 
              (int) i);



      if (percentInsideMask < MIN_AREA_PERCENT_WITHIN_LINES)
      {
        // Not enough area is inside the lines.
        if (config->debugCharAnalysis)
          cout << "Rejecting due to insufficient area" << endl;
        textContours.goodIndices[i] = false; 

        continue;
      }


      // now check to make sure that the top and bottom of the contour are near enough to the lines

      // First get the high and low point for the contour
      // Remember that origin is top-left, so the top Y values are actually closer to 0.
      Rect brect = boundingRect(textContours.contours[i]);
      int xmiddle = brect.x + (brect.width / 2);
      Point topMiddle = Point(xmiddle, brect.y);
      Point botMiddle = Point(xmiddle, brect.y+brect.height);

      // Get the absolute distance from the top and bottom lines

      for (unsigned int i = 0; i < textLines.size(); i++)
      {
        Point closestTopPoint = textLines[i].topLine.closestPointOnSegmentTo(topMiddle);
        Point closestBottomPoint = textLines[i].bottomLine.closestPointOnSegmentTo(botMiddle);

        float absTopDistance = distanceBetweenPoints(closestTopPoint, topMiddle);
        float absBottomDistance = distanceBetweenPoints(closestBottomPoint, botMiddle);

        float maxDistance = textLines[i].lineHeight * MAX_DISTANCE_PERCENT_FROM_LINES;

        if (absTopDistance < maxDistance && absBottomDistance < maxDistance)
        {
          // It's ok, leave it as-is.
        }
        else
        {

          textContours.goodIndices[i] = false; 
          if (config->debugCharAnalysis)
            cout << "Rejecting due to top/bottom points that are out of range" << endl;
        }
      }

    }

  }
예제 #20
0
vector<bool> CharacterAnalysis::filterBetweenLines(Mat img, vector<vector<Point> > contours, vector<Vec4i> hierarchy, vector<Point> outerPolygon, vector<bool> goodIndices)
{
    static float MIN_AREA_PERCENT_WITHIN_LINES = 0.88;

    vector<bool> includedIndices(contours.size());
    for (int j = 0; j < contours.size(); j++)
        includedIndices[j] = false;


    if (outerPolygon.size() == 0)
        return includedIndices;

    vector<Point> validPoints;

    // Figure out the line height
    LineSegment topLine(outerPolygon[0].x, outerPolygon[0].y, outerPolygon[1].x, outerPolygon[1].y);
    LineSegment bottomLine(outerPolygon[3].x, outerPolygon[3].y, outerPolygon[2].x, outerPolygon[2].y);

    float x = ((float) img.cols) / 2;
    Point midpoint = Point(x, bottomLine.getPointAt(x));
    Point acrossFromMidpoint = topLine.closestPointOnSegmentTo(midpoint);
    float lineHeight = distanceBetweenPoints(midpoint, acrossFromMidpoint);

    // Create a white mask for the area inside the polygon
    Mat outerMask = Mat::zeros(img.size(), CV_8U);
    Mat innerArea = Mat::zeros(img.size(), CV_8U);
    fillConvexPoly(outerMask, outerPolygon.data(), outerPolygon.size(), Scalar(255,255,255));


    for (int i = 0; i < contours.size(); i++)
    {
        if (goodIndices[i] == false)
            continue;

        // get rid of the outline by drawing a 1 pixel width black line
        drawContours(innerArea, contours,
                     i, // draw this contour
                     cv::Scalar(255,255,255), // in
                     CV_FILLED,
                     8,
                     hierarchy,
                     0
                    );


        bitwise_and(innerArea, outerMask, innerArea);


        vector<vector<Point> > tempContours;
        findContours(innerArea, tempContours,
                     CV_RETR_EXTERNAL, // retrieve the external contours
                     CV_CHAIN_APPROX_SIMPLE ); // all pixels of each contours );

        double totalArea = contourArea(contours[i]);
        double areaBetweenLines = 0;

        for (int tempContourIdx = 0; tempContourIdx < tempContours.size(); tempContourIdx++)
        {
            areaBetweenLines += contourArea(tempContours[tempContourIdx]);

        }


        if (areaBetweenLines / totalArea >= MIN_AREA_PERCENT_WITHIN_LINES)
        {
            includedIndices[i] = true;
        }

        innerArea.setTo(Scalar(0,0,0));
    }

    return includedIndices;
}