bool closeSurface( fwVertexPosition &_vertex, fwVertexIndex &_vertexIndex ) { typedef std::pair< int, int > Edge; typedef std::vector< Edge > Contour; // at Border typedef std::vector< Contour> Contours; Contours contours; findBorderEdges( _vertexIndex , contours); bool closurePerformed = !contours.empty() ; // close each hole for ( Contours::iterator contour=contours.begin(); contour != contours.end(); ++contour ) { int newVertexIndex = _vertex.size() ; // create gravity point & insert new triangle std::vector< float > massCenter(3,0); for ( Contour::iterator edge =contour->begin(); edge != contour->end(); ++edge ) { for (int i=0; i<3; ++i ) { massCenter[i] += _vertex[edge->first][i]; massCenter[i] += _vertex[edge->second][i]; } // create new Triangle std::vector< int > triangleIndex(3); triangleIndex[0] = edge->first; triangleIndex[1] = edge->second; triangleIndex[2] = newVertexIndex; _vertexIndex.push_back( triangleIndex ); // TEST } for (int i=0; i<3; ++i ) { massCenter[i] /= contour->size()*2; } _vertex.push_back( massCenter ); // normalize barycenter } return closurePerformed; }
Mat ScreenDetector::getTransformationMatrix(Error& error) { bool approxFound = false; // convert image to HSV cvtColor(img, hsv, CV_BGR2HSV); // threshold the image inRange(hsv, hsvMin, hsvMax, thresholded); // Optimize threshold by reducing noise erode(thresholded, thresholded, getStructuringElement(MORPH_ELLIPSE, Size(erodeDilateSize, erodeDilateSize)) ); dilate( thresholded, thresholded, getStructuringElement(MORPH_ELLIPSE, Size(erodeDilateSize, erodeDilateSize)) ); dilate( thresholded, thresholded, getStructuringElement(MORPH_ELLIPSE, Size(erodeDilateSize, erodeDilateSize)) ); erode(thresholded, thresholded, getStructuringElement(MORPH_ELLIPSE, Size(erodeDilateSize, erodeDilateSize)) ); GaussianBlur(thresholded, thresholded, Size(3,3), 0); Mat forContours; thresholded.copyTo(forContours); // find all contours Contours contours; Contour approximatedScreen; findContours(forContours, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE); int nbContours = contours.size(); cout << nbContours << " contours found, debug: " << DEBUG << endl; if(nbContours == 0) { error.setError("Unable to find the screen", "The camera doesn't detect any screen or green element." "Please check if your screen is turned on and directed toward the screen"); return img; } sort(contours.begin(), contours.end(), contour_compare_area); // find the contour with the biggest area that have 4 points when approximated for(int i=0; i < nbContours; ++i) { approxPolyDP(contours.at(i), approximatedScreen, approximateEpsilon * arcLength(contours.at(i), true), true); // our screen has 4 point when approximated if(approximatedScreen.size() == 4) { approxFound = true; break; } } if(!approxFound) { error.setError("Unable to find the screen properly", "It seems that the screen is not fully detectable by the camera. Try to reduce light in your room"); return img; } if(DEBUG) { namedWindow("debug", WINDOW_KEEPRATIO); namedWindow("thresholded_calibration", WINDOW_KEEPRATIO); Mat debug = Mat::zeros(img.rows, img.cols, CV_8UC3); polylines(debug, approximatedScreen, true, Scalar(0,0,255), 3); imshow("debug", debug); imshow("thresholded_calibration", thresholded); } return transformImage(approximatedScreen); }