static Rect fitEllipse_check( vector<Point> contour ) { Mat pointsf; Mat(contour).convertTo(pointsf, CV_32F); RotatedRect box = fitEllipse(pointsf); //cout << box.size << " " << box.size <<endl; return box.boundingRect(); if( MAX(box.size.width, box.size.height) > MIN(box.size.width, box.size.height)*2 ) return Rect(-1,-1,0,0); else return box.boundingRect(); }
void get_min_box(vector<Point> r, RotatedRect box) { if ((box.size.width < 500) && (box.size.width < 500)) { if (min_rect.size() == 0) { // first rect min_rect.push_back(box); min_r.push_back(r); } else { // every other rect bool is_inside = true; for (int i = 0; i < int(min_rect.size()); ++i) { if (box.boundingRect().contains(min_rect[i].center)) { // if hierachical boxes break; else add box is_inside = true; break; } else { is_inside = false; } } if (is_inside == false) { min_rect.push_back(box); min_r.push_back(r); } } } }
void Brushstroke::draw(Mat& alphaMap, Mat& mask, double spacing, double jitter) { Point2d normal = Point2d(cos(angle), sin(angle)); Point2d point1 = normal * length1; Point2d point2 = normal * -length2; point1 += anchor; point2 += anchor; Point2d texCenter; RotatedRect maskRect; double texAngle; Size_<double> maskSize = mask.size(); double ratio = (width + 2.0) / maskSize.width; Mat scaledMask; resize(mask, scaledMask, Size(), ratio, ratio, INTER_CUBIC); maskSize = scaledMask.size(); RNG rng(0xFFFFFFFF); for(double dist = -length2; dist < length1; dist += spacing) { texCenter = anchor + normal * dist; texAngle = angle + jitter * rng.uniform(-1.0, 1.0); maskRect = RotatedRect(texCenter, maskSize, texAngle); Rect2d boundingRect = maskRect.boundingRect(); renderTexture(alphaMap, scaledMask, maskRect); } }
void camshift( Mat &frame, Mat &hue_roi, Mat &mask_roi, Mat &backproj, Mat &thresh_img, Point2i &resol, Point2i &shift, Rect &searchwin, struct intrinsics *intrins, struct pose *body, ofstream& file ) { Mat hsv, hue, mask; hue.create( resol.y, resol.x, CV_8UC1); mask.create(resol.y, resol.x, CV_8UC3); int ch[] = {0,0}; float theta; RotatedRect orient; Point2f vertices[4]; bool inframe = false; cvtColor( frame, hsv, COLOR_BGR2HSV ); //Ignore pixels in HSV space with too high/low saturation and a high value: hv_threshold( hsv, mask ); //Extract single channel Hue frames from HSV frames //Usage of ch[] means copying from channel 0 of source to channel 0 of destination mixChannels( &hsv, 1, &hue, 1, ch, 1 ); //Compute backprojected frames: backprojection( binsize, hue_roi, hue, backproj, mask_roi, thresh_img ); double res = 1; moment(thresh_img, res, searchwin, theta, inframe, shift); orient = RotatedRect(Point2f(searchwin.x, searchwin.y), Size2f(searchwin.width, searchwin.height), theta); orient.points(vertices); for (int i = 0; i < 4; i++){ line(frame, vertices[i], vertices[(i+1)%4], Scalar(0,255,0), 2); } Rect brect = orient.boundingRect(); rectangle( frame, brect, Scalar(0,0,255), 2 ); imshow( "Source Stream", frame ) ; if (inframe){ simulate(inframe, searchwin, intrins, file); } }
void CSpatialIndexFTaxi::Insert(RotatedRect n_rotatedrect,int n_index) { //get the bounding rectangle; Rect n_rect=n_rotatedrect.boundingRect(); //the the tl and br point; Point2f n_pt1=n_rect.tl(); Point2f n_pt2=n_rect.br(); //tranform the point to BTPoint BTPoint n_btpt1(n_pt1.x,n_pt1.y); BTPoint n_btpt2(n_pt2.x,n_pt2.y); //create box of the btpoint BTBox n_box(n_btpt1,n_btpt2); //create BTValue BTValue n_val=std::make_pair(n_box,n_index); //insert nRtree.insert(n_val); }
int CSpatialIndexFTaxi::CheckOverLay(RotatedRect n_rotatedrect) { //get the bounding rectangle; Rect n_rect=n_rotatedrect.boundingRect(); //the the tl and br point; Point2f n_pt1=n_rect.tl(); Point2f n_pt2=n_rect.br(); //tranform the point to BTPoint BTPoint n_btpt1(n_pt1.x,n_pt1.y); BTPoint n_btpt2(n_pt2.x,n_pt2.y); //create box of the btpoint BTBox n_box(n_btpt1,n_btpt2); //results storate std::vector<BTValue> n_resultvct; //query nRtree.query(bgi::intersects(n_box),std::back_inserter(n_resultvct)); return n_resultvct.size(); }
void Brushstroke::renderTexture(Mat& alphaMap, Mat& mask, RotatedRect& maskRect) { // transformations, etc Rect2d boundingRect = maskRect.boundingRect(); int offsetX = (boundingRect.width - mask.cols)/2; int offsetY = (boundingRect.height - mask.rows)/2; Mat paddedMask = Mat::zeros(boundingRect.height, boundingRect.width, CV_64FC3); mask.copyTo(paddedMask(Rect(offsetX, offsetY, mask.cols, mask.rows))); Mat rot_mat = getRotationMatrix2D(Point2f(boundingRect.width/2, boundingRect.height/2), maskRect.angle / PI * 180.0, 1.0); warpAffine(paddedMask, paddedMask, rot_mat, paddedMask.size()); int x1 = boundingRect.x; int y1 = boundingRect.y; int x2 = x1 + boundingRect.width; int y2 = y1 + boundingRect.height; x1 = CLAMP(x1, 0, alphaMap.cols); y1 = CLAMP(y1, 0, alphaMap.rows); x2 = CLAMP(x2, 0, alphaMap.cols); y2 = CLAMP(y2, 0, alphaMap.rows); int wid = x2-x1; int hig = y2-y1; if (wid <= 0 || hig <= 0) return; Rect src_roi(x1 - boundingRect.x, y1 - boundingRect.y, wid, hig); Rect dst_roi(x1, y1, wid, hig); Mat one_minus_src = Mat::ones(hig, wid, CV_64FC3); one_minus_src.setTo(1); one_minus_src -= paddedMask(src_roi); alphaMap(dst_roi) = paddedMask(src_roi) + alphaMap(dst_roi).mul(one_minus_src); }
geometry_msgs::Pose getFeature(Mat img, Mat dst, Scalar low, Scalar high, Scalar draw) { // Threshold image Mat bw, hsv; cv::cvtColor(img, hsv, CV_BGR2HSV); vector<vector<Point> > contours; inRange(hsv, low, high, bw); findContours(bw.clone(), contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE); for(size_t i=0; i < contours.size(); i++) { double area = contourArea(contours[i]); // Ensure minimum area and symmetry for circles if(area > 200){ RotatedRect minEllipse; minEllipse = fitEllipse(Mat(contours[i])); double eW = minEllipse.boundingRect().width; double eH = minEllipse.boundingRect().height; if(abs(eW-eH)<6){ ellipse(dst, minEllipse, draw, 2, 8); cv::imshow("Range window", dst); cv::imshow("HSV window", hsv); geometry_msgs::Point pt; geometry_msgs::Quaternion q; pt.x = minEllipse.center.y; pt.y = minEllipse.center.x; pt.z = 0.0; geometry_msgs::Pose p; p.position = pt; p.orientation = q; return p; } } } cv::imshow("Range window", dst); cv::imshow("HSV window", hsv); return geometry_msgs::Pose(); }
Mat CControl::GetSubsetImg(RotatedRect n_rotatedrect) { // cout<<n_rotatedrect<<endl; //根据旋转矩形,从nimgraw中获得新图像。 //获得边界矩形。 Rect n_boundrect=n_rotatedrect.boundingRect(); //将边界在原图像上画出。 Point2f vertices[4]; n_rotatedrect.points(vertices); // Mat n_imgraw; // nImgRaw.copyTo(n_imgraw); // for (int i = 0; i < 4; i++) // line(n_imgraw, vertices[i], vertices[(i+1)%4], Scalar(0,255,0)); // imshow("raw",n_imgraw); //获得子图像。 Mat n_boundmatemp=nImgRaw(n_boundrect); Mat n_boundmat; n_boundmatemp.copyTo(n_boundmat); // imshow("prerotated",n_boundmat); //获得旋转变换参数矩阵 //这里的中心不再是原图像的中心,而是子图的中心。(原中心-左上角) Point2f n_pt1=n_rotatedrect.center; Point2f n_pt2=n_boundrect.tl(); Point2f n_ptcenter=n_pt1-n_pt2; Mat n_rotatematparam=getRotationMatrix2D(n_ptcenter,n_rotatedrect.angle,1.0); //进行仿射变换。 Mat n_rotatedMat; warpAffine(n_boundmat, n_rotatedMat,n_rotatematparam,n_boundmat.size(),INTER_CUBIC); //截取子图像。 Mat n_croppedmat; Size n_subsize(nControlOptions.nWidth,nControlOptions.nHeight); getRectSubPix(n_rotatedMat,n_subsize,n_ptcenter,n_croppedmat); // imshow("rotated",n_croppedmat); // waitKey(0); return n_croppedmat; }
cv::Rect getBoundingRect(RotatedRect rect){ rect.angle = rect.angle+90; return rect.boundingRect(); }
int _tmain(int argc, _TCHAR* argv[]) { Mat input = imread("2715DTZ.jpg",1); if (input.empty()) { fprintf(stderr,"Cannot load a picture!"); return -1; } Mat img_gray; cvtColor(input,img_gray,CV_BGR2GRAY); blur(img_gray,img_gray,Size(5,5)); Mat img_sobel; Sobel(img_gray,img_sobel,CV_8U,1,0,3,1,0); imshow("sobel",img_sobel); Mat img_threshold; threshold(img_sobel,img_threshold,0,255,CV_THRESH_OTSU+CV_THRESH_BINARY); Mat element = getStructuringElement(MORPH_RECT,Size(17,3)); morphologyEx(img_threshold,img_threshold,CV_MOP_CLOSE,element); imshow("morphologyEx",img_threshold); vector<vector<Point> >contours; findContours(img_threshold,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE); vector<vector<Point> >::iterator itc = contours.begin(); vector<RotatedRect> rects; while (itc!=contours.end()) { RotatedRect mr = minAreaRect(Mat(*itc)); if (!verifySizes(mr)) { itc=contours.erase(itc); }else { ++itc; rects.push_back(mr); } } // Draw blue contours on a white image cv::Mat result; input.copyTo(result); cv::drawContours(result,contours, -1, // draw all contours cv::Scalar(255,0,0), // in blue 1); // with a thickness of 1 for(int i=0; i< rects.size(); i++){ //For better rect cropping for each posible box //Make floodfill algorithm because the plate has white background //And then we can retrieve more clearly the contour box circle(result, rects[i].center, 3, Scalar(0,255,0), -1); //get the min size between width and height float minSize=(rects[i].size.width < rects[i].size.height)?rects[i].size.width:rects[i].size.height; minSize=minSize-minSize*0.5; //initialize rand and get 5 points around center for floodfill algorithm srand ( time(NULL) ); //Initialize floodfill parameters and variables Mat mask; mask.create(input.rows + 2, input.cols + 2, CV_8UC1); mask= Scalar::all(0); int loDiff = 30; int upDiff = 30; int connectivity = 4; int newMaskVal = 255; int NumSeeds = 10; Rect ccomp; int flags = connectivity + (newMaskVal << 8 ) + CV_FLOODFILL_FIXED_RANGE + CV_FLOODFILL_MASK_ONLY; for(int j=0; j<NumSeeds; j++){ Point seed; seed.x=rects[i].center.x+rand()%(int)minSize-(minSize/2); seed.y=rects[i].center.y+rand()%(int)minSize-(minSize/2); circle(result, seed, 1, Scalar(0,255,255), -1); int area = floodFill(input, mask, seed, Scalar(255,0,0), &ccomp, Scalar(loDiff, loDiff, loDiff), Scalar(upDiff, upDiff, upDiff), flags); } imshow("MASK", mask); cvWaitKey(3000); vector<Point> pointsInterest; Mat_<uchar>::iterator itMask= mask.begin<uchar>(); Mat_<uchar>::iterator end= mask.end<uchar>(); for( ; itMask!=end; ++itMask) if(*itMask==255) pointsInterest.push_back(itMask.pos()); RotatedRect minRect = minAreaRect(pointsInterest); if(verifySizes(minRect)){ // rotated rectangle drawing Point2f rect_points[4]; minRect.points( rect_points ); for( int j = 0; j < 4; j++ ) line( result, rect_points[j], rect_points[(j+1)%4], Scalar(0,0,255), 1, 8 ); //Get rotation matrix float r= (float)minRect.size.width / (float)minRect.size.height; float angle=minRect.angle; if(r<1) angle=90+angle; Mat rotmat= getRotationMatrix2D(minRect.center, angle,1); //Create and rotate image Mat img_rotated; warpAffine(input, img_rotated, rotmat, input.size(), CV_INTER_CUBIC); //Crop image Size rect_size=minRect.size; if(r < 1) swap(rect_size.width, rect_size.height); Mat img_crop; getRectSubPix(img_rotated, rect_size, minRect.center, img_crop); Mat resultResized; resultResized.create(33,144, CV_8UC3); resize(img_crop, resultResized, resultResized.size(), 0, 0, INTER_CUBIC); //Equalize croped image Mat grayResult; cvtColor(resultResized, grayResult, CV_BGR2GRAY); blur(grayResult, grayResult, Size(3,3)); grayResult=histeq(grayResult); if(saveRegions){ stringstream ss(stringstream::in | stringstream::out); ss << "tmp/" << filename << "_" << i << ".jpg"; imwrite(ss.str(), grayResult); } output.push_back(Plate(grayResult,minRect.boundingRect())); } } imshow("Contours", result); cvWaitKey(0); return 0; }
void monCamShiftAmoi( Rect& selection, Mat& image) { bool backprojMode = true; bool selectObject = false; int trackObject = -1; bool showHist = true; Point origin; int vmin = 100, vmax = 256, smin = 100; help(); //VideoCapture cap; Rect trackWindow; int hsize = 16; //int hbins = 30, sbins = 32; //int histSize[] = {hbins, sbins}; float hranges[] = {0,180}; //float sranges[] = { 0, 256 }; const float* phranges = hranges; //const float* ranges[] = { hranges, sranges }; //CommandLineParser parser(argc, argv, keys); //int camNum = 1; //cap.open(camNum); /*if( !cap.isOpened() ) { help(); cout << "***Could not initialize capturing...***\n"; cout << "Current parameter's value: \n"; parser.printParams(); return -1; }*/ namedWindow( "Histogram", 0 ); namedWindow( "CamShift Demo", 0 ); //setMouseCallback( "CamShift Demo", onMouse, 0 ); createTrackbar( "Vmin", "CamShift Demo", &vmin, 256, 0 ); createTrackbar( "Vmax", "CamShift Demo", &vmax, 256, 0 ); createTrackbar( "Smin", "CamShift Demo", &smin, 256, 0 ); Mat frame, hsv, hue, mask, hist, histimg = Mat::zeros(200, 320, CV_8UC3), backproj; bool paused = false; /*for(;;) { if( !paused ) { cap >> frame; if( frame.empty() ) break; } frame.copyTo(image);*/ if( !paused ) { cvtColor(image, hsv, COLOR_BGR2HSV); if( trackObject ) { int _vmin = vmin, _vmax = vmax; inRange(hsv, Scalar(0, smin, MIN(_vmin,_vmax)), Scalar(180, 256, MAX(_vmin, _vmax)), mask); int ch[] = {0, 0}; hue.create(hsv.size(), hsv.depth()); mixChannels(&hsv, 1, &hue, 1, ch, 1); if( trackObject < 0 ) { Mat roi(hue, selection), maskroi(mask, selection); calcHist(&roi, 1, 0, maskroi, hist, 1, &hsize, &phranges); normalize(hist, hist, 0, 255, CV_MINMAX); trackWindow = selection; trackObject = 1; histimg = Scalar::all(0); int binW = histimg.cols / hsize; Mat buf(1, hsize, CV_8UC3); for( int i = 0; i < hsize; i++ ) buf.at<Vec3b>(i) = Vec3b(saturate_cast<uchar>(i*180./hsize), 255, 255); cvtColor(buf, buf, CV_HSV2BGR); for( int i = 0; i < hsize; i++ ) { int val = saturate_cast<int>(hist.at<float>(i)*histimg.rows/255); rectangle( histimg, Point(i*binW,histimg.rows), Point((i+1)*binW,histimg.rows - val), Scalar(buf.at<Vec3b>(i)), -1, 8 ); } } calcBackProject(&hue, 1, 0, hist, backproj, &phranges); backproj &= mask; //trackbox est le rect qui suivi le visage. //backproj RotatedRect trackBox = CamShift(backproj, trackWindow, TermCriteria( CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1 )); Rect recttrackBox = trackBox.boundingRect(); if(recttrackBox.x<0) recttrackBox.x=0; if(recttrackBox.y<0) recttrackBox.y=0; if(recttrackBox.x+recttrackBox.width>image.cols) recttrackBox.width=image.cols-recttrackBox.x; if(recttrackBox.y+recttrackBox.height>image.rows) recttrackBox.height=image.rows-recttrackBox.y; Mat roia(backproj, recttrackBox); roia= Scalar(0,0,0); trackWindow = Rect(0,0,image.cols,image.rows); RotatedRect trackBox2 = CamShift(backproj, trackWindow, TermCriteria( CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1 )); if( trackWindow.area() <= 1 ) { int cols = backproj.cols, rows = backproj.rows, r = (MIN(cols, rows) + 5)/6; trackWindow = Rect(trackWindow.x - r, trackWindow.y - r, trackWindow.x + r, trackWindow.y + r) & Rect(0, 0, cols, rows); } if( backprojMode ) cvtColor( backproj, image, COLOR_GRAY2BGR ); ellipse( image, trackBox2, Scalar(0,0,255), 3, CV_AA ); } } else if( trackObject < 0 ) paused = false; if( selectObject && selection.width > 0 && selection.height > 0 ) { Mat roi(image, selection); //bitwise_not(roi, roi); } imshow( "CamShift Demo", image ); imshow( "Histogram", histimg ); imwrite("img.jpg", image); char c = (char)waitKey(10); //if( c == 27 ) //break; switch(c) { case 'b': backprojMode = !backprojMode; break; case 'c': trackObject = 0; histimg = Scalar::all(0); break; case 'h': showHist = !showHist; if( !showHist ) destroyWindow( "Histogram" ); else namedWindow( "Histogram", 1 ); break; case 'p': paused = !paused; break; default: ; } //} //return 0; }
int size() { return box.boundingRect().area(); }
vector<Placa> RegionPlaca::segmento(Mat input){ vector<Placa> output;// creamos un array de clases de tipo Placa //Transformamos la imagen a escala de grises Mat img_gray; cvtColor(input, img_gray, CV_BGR2GRAY); blur(img_gray, img_gray, Size(5, 5)); //Para encontrar las lineas verticales de la placa, se debe resaltar las lineas Mat img_sobel; Sobel(img_gray, img_sobel, CV_8U, 1, 0, 3, 1, 0, BORDER_DEFAULT); if (showSteps) imshow("Sobel", img_sobel); //Se binariza la imagen Mat img_threshold; threshold(img_sobel, img_threshold, 0, 255, CV_THRESH_OTSU + CV_THRESH_BINARY); if (showSteps) imshow("Threshold", img_threshold); //Se hace un barrido de las lineas verticales y horizontales Mat element = getStructuringElement(MORPH_RECT, Size(20, 5)); morphologyEx(img_threshold, img_threshold, CV_MOP_CLOSE, element); if (showSteps) imshow("Close", img_threshold); //Encontramos todas las posibles regiones de placas de autos vector< vector< Point> > regiones; findContours(img_threshold, regiones, // Array de regiones CV_RETR_EXTERNAL, // retrieve the external contours CV_CHAIN_APPROX_NONE); // all pixels of each contours //Empezamos a analizar las regiones una por una vector<vector<Point> >::iterator itc = regiones.begin(); vector<RotatedRect> rects; // Rectangulos dentro de los limites indicados //Eliminamos las regiones que no se encuentran dentro de los limites permitidos. while (itc != regiones.end()) { //Create bounding rect of object RotatedRect angRect = minAreaRect(Mat(*itc)); if (!verificarTamaño(angRect, false)){ itc = regiones.erase(itc); } else{ ++itc; rects.push_back(angRect); } } // Pintamos de color azul las regiones que se encuentran dentro de los limites cv::Mat resultado; input.copyTo(resultado); // copiamos la imagen de entrada en la variable 'resultado' cv::drawContours(resultado, regiones, -1, // pintamos todos los contornos cv::Scalar(255, 0, 0), // asignamos que color 1, // Pintamos los contornos que encierran otros contornos 16);// Grosor de las lineas if (showSteps) imshow("ContornosAzul", resultado); for (int i = 0; i< rects.size(); i++){ std::string cadena = ""; cadena = static_cast<std::ostringstream*>(&(std::ostringstream() << i))->str(); //For better rect cropping for each posible box //Make floodfill algorithm because the plate has white background //And then we can retrieve more clearly the contour box circle(resultado, rects[i].center, 3, Scalar(0, 255, 0), -1); //get the min size between width and height float minSize = (rects[i].size.width < rects[i].size.height) ? rects[i].size.width : rects[i].size.height; minSize = minSize - minSize*0.5; //initialize rand and get 5 points around center for floodfill algorithm srand(time(NULL)); //Initialize floodfill parameters and variables Mat mask; mask.create(input.rows + 2, input.cols + 2, CV_8UC1); mask = Scalar::all(0); int loDiff = 30; int upDiff = 30; int connectivity = 4; int newMaskVal = 255; int NumSeeds = 10; Rect ccomp; int flags = connectivity + (newMaskVal << 8) + CV_FLOODFILL_FIXED_RANGE + CV_FLOODFILL_MASK_ONLY; for (int j = 0; j<NumSeeds; j++){ Point seed; seed.x = rects[i].center.x + rand() % (int)minSize - (minSize / 2); seed.y = rects[i].center.y + rand() % (int)minSize - (minSize / 2); circle(resultado, seed, 1, Scalar(0, 255, 255), -1); int area = floodFill(input, mask, seed, Scalar(255, 0, 0), &ccomp, Scalar(loDiff, loDiff, loDiff), Scalar(upDiff, upDiff, upDiff), flags); } if (showSteps) imshow("MASK" + cadena, mask); //cvWaitKey(0); //Check new floodfill mask match for a correct patch. //Get all points detected for get Minimal rotated Rect vector<Point> pointsInterest; Mat_<uchar>::iterator itMask = mask.begin<uchar>(); Mat_<uchar>::iterator end = mask.end<uchar>(); for (; itMask != end; ++itMask) if (*itMask == 255) pointsInterest.push_back(itMask.pos()); RotatedRect minRect = minAreaRect(pointsInterest); //imshow("Rotated minRECT" + cadena, result); if (verificarTamaño (minRect, true)){ // rotated rectangle drawing Point2f rect_points[4]; minRect.points(rect_points); for (int j = 0; j < 4; j++) line(resultado, rect_points[j], rect_points[(j + 1) % 4], Scalar(0, 0, 255), 1, 8); //imshow("Rotated mminRECT SEGUNDO" + cadena, result); //Get rotation matrix float r = (float)minRect.size.width / (float)minRect.size.height; float angle = minRect.angle; if (r<1) angle = 90 + angle; Mat rotmat = getRotationMatrix2D(minRect.center, angle, 1); //Create and rotate image Mat img_rotated; warpAffine(input, img_rotated, rotmat, input.size(), CV_INTER_CUBIC); //Se corta la imagen de la placa identificada Size rect_size = minRect.size; if (r < 1) swap(rect_size.width, rect_size.height); Mat img_crop; getRectSubPix(img_rotated, rect_size, minRect.center, img_crop); if (showSteps) imshow("imgCrop" + cadena, img_crop); Mat resultResized; resultResized.create(33, 144, CV_8UC3); resize(img_crop, resultResized, resultResized.size(), 0, 0, INTER_CUBIC); //Se convierte a escala de grises la imagen cortada Mat grayResult; cvtColor(resultResized, grayResult, CV_BGR2GRAY); blur(grayResult, grayResult, Size(3, 3)); grayResult = c1Bgr(grayResult); if (showSteps){ stringstream ss(stringstream::in | stringstream::out); ss << "tmp/" << nombreArchivo << "_" << i << ".jpg"; vector<int> compression_params; compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION); compression_params.push_back(9); bool success = imwrite("C:/Users/gian/Documents/Visual Studio 2013/Projects/PlacaRNA/CaractSVM/" + ss.str(), grayResult, compression_params); if (success) cout << ss.str() << endl; } output.push_back(Placa(grayResult, minRect.boundingRect())); } } if (showSteps) imshow("Contours", resultado); return output; }
vector<Plate> DetectRegions::segment(Mat input){ vector<Plate> output; //convert image to gray Mat img_gray; //= *new Mat(input.size().width,input.size().height, CV_8UC1); cvtColor(input, img_gray, CV_BGR2GRAY); blur(img_gray, img_gray, Size(5,5)); //Finde vertical lines. Car plates have high density of vertical lines Mat img_sobel; Sobel(img_gray, img_sobel, CV_8U, 1, 0, 3, 1, 0, BORDER_DEFAULT); if(showSteps) imshow("Sobel", img_sobel); //threshold image Mat img_threshold; threshold(img_sobel, img_threshold, 0, 255, CV_THRESH_OTSU+CV_THRESH_BINARY); if(showSteps) imshow("Threshold", img_threshold); //Morphplogic operation close Mat element = getStructuringElement(MORPH_RECT, Size(17, 3) ); morphologyEx(img_threshold, img_threshold, CV_MOP_CLOSE, element); if(showSteps) imshow("Close", img_threshold); //Find contours of possibles plates vector< vector< Point> > contours; findContours(img_threshold, contours, // a vector of contours CV_RETR_EXTERNAL, // retrieve the external contours CV_CHAIN_APPROX_NONE); // all pixels of each contours //Start to iterate to each contour founded vector<vector<Point> >::iterator itc= contours.begin(); vector<RotatedRect> rects; //Remove patch that are no inside limits of aspect ratio and area. while (itc!=contours.end()) { //Create bounding rect of object RotatedRect mr= minAreaRect(Mat(*itc)); if( !verifySizes(mr)){ itc= contours.erase(itc); }else{ ++itc; rects.push_back(mr); } } // Draw blue contours on a white image cv::Mat result; input.copyTo(result); cv::drawContours(result,contours, -1, // draw all contours cv::Scalar(255,0,0), // in blue 1); // with a thickness of 1 for(int i=0; i< rects.size(); i++){ //For better rect cropping for each posible box //Make floodfill algorithm because the plate has white background //And then we can retrieve more clearly the contour box circle(result, rects[i].center, 3, Scalar(0,255,0), -1); //get the min size between width and height float minSize=(rects[i].size.width < rects[i].size.height)?rects[i].size.width:rects[i].size.height; minSize=minSize-minSize*0.5; //initialize rand and get 5 points around center for floodfill algorithm srand ( time(NULL) ); //Initialize floodfill parameters and variables Mat mask; mask.create(input.rows + 2, input.cols + 2, CV_8UC1); mask= Scalar::all(0); int loDiff = 30; int upDiff = 30; int connectivity = 4; int newMaskVal = 255; int NumSeeds = 10; Rect ccomp; int flags = connectivity + (newMaskVal << 8 ) + CV_FLOODFILL_FIXED_RANGE + CV_FLOODFILL_MASK_ONLY; for(int j=0; j<NumSeeds; j++){ Point seed; seed.x=rects[i].center.x+rand()%(int)minSize-(minSize/2); seed.y=rects[i].center.y+rand()%(int)minSize-(minSize/2); circle(result, seed, 1, Scalar(0,255,255), -1); int area = floodFill(input, mask, seed, Scalar(255,0,0), &ccomp, Scalar(loDiff, loDiff, loDiff), Scalar(upDiff, upDiff, upDiff), flags); } if(showSteps) imshow("MASK", mask); //cvWaitKey(0); //Check new floodfill mask match for a correct patch. //Get all points detected for get Minimal rotated Rect vector<Point> pointsInterest; Mat_<uchar>::iterator itMask= mask.begin<uchar>(); Mat_<uchar>::iterator end= mask.end<uchar>(); for( ; itMask!=end; ++itMask) if(*itMask==255) pointsInterest.push_back(itMask.pos()); RotatedRect minRect = minAreaRect(pointsInterest); if(verifySizes(minRect)){ // rotated rectangle drawing Point2f rect_points[4]; minRect.points( rect_points ); for( int j = 0; j < 4; j++ ) line( result, rect_points[j], rect_points[(j+1)%4], Scalar(0,0,255), 1, 8 ); //Get rotation matrix float r= (float)minRect.size.width / (float)minRect.size.height; float angle=minRect.angle; if(r<1) angle=90+angle; Mat rotmat= getRotationMatrix2D(minRect.center, angle,1); //Create and rotate image Mat img_rotated; warpAffine(input, img_rotated, rotmat, input.size(), CV_INTER_CUBIC); //Crop image Size rect_size=minRect.size; if(r < 1) swap(rect_size.width, rect_size.height); Mat img_crop; getRectSubPix(img_rotated, rect_size, minRect.center, img_crop); Mat resultResized; resultResized.create(33,144, CV_8UC3); resize(img_crop, resultResized, resultResized.size(), 0, 0, INTER_CUBIC); //Equalize croped image Mat grayResult; cvtColor(resultResized, grayResult, CV_BGR2GRAY); blur(grayResult, grayResult, Size(3,3)); grayResult=histeq(grayResult); if(saveRegions){ stringstream ss(stringstream::in | stringstream::out); ss << "tmp/" << filename << "_" << i << ".jpg"; imwrite(ss.str(), grayResult); } output.push_back(Plate(grayResult,minRect.boundingRect())); } } if(showSteps) imshow("Contours", result); return output; }
bool is_bigger(RotatedRect box_1, RotatedRect box_2) { return box_1.boundingRect().size().area() < box_2.boundingRect().size().area(); }
bool CVTracker::filter(const Frame& in, Frame& out) { BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << " " << id(); toffy::Filter::setLoggingLvl(); //List of detected objects BOOST_LOG_TRIVIAL(debug) << "Getting _in_vec: " << _in_vec; boost::shared_ptr<std::vector<detection::DetectedObject*> > detObj; try { detObj = boost::any_cast<boost::shared_ptr<std::vector<detection::DetectedObject*> > >(in.getData(_in_vec)); } catch(const boost::bad_any_cast &) { BOOST_LOG_TRIVIAL(warning) << "Could not find object vector: " << _in_vec << ". " << id(); return true; } BOOST_LOG_TRIVIAL(debug) << "Got _in_vec(" << _in_vec << "): " << detObj->size(); // TODO Where come img from?, why we mask it with the objects. BOOST_LOG_TRIVIAL(debug) << "Getting got _in_img: " << _in_img; boost::shared_ptr<cv::Mat> img; try { img = in.getMatPtr(_in_img); } catch(const boost::bad_any_cast &) { BOOST_LOG_TRIVIAL(warning) << "Could not cast input " << _in_img << ", filter " << id() <<" does not show objects."; img.reset(new cv::Mat(cv::Size(160,120),CV_8UC3, Scalar(0,0,0))); out.addData(_in_img,img); } img.reset(new cv::Mat(cv::Size(160,120),CV_8UC3, Scalar(0,0,0))); for (size_t i = 0; i < detObj->size(); i++) { cv::drawContours( *img, *(detObj->at(i)->contours), detObj->at(i)->idx, detObj->at(i)->color, FILLED, LINE_AA, *(detObj->at(i)->hierarchy)); } Mat show = img->clone(); for (size_t i = 0; i < detObj->size(); i++) { RotatedRect rr = cv::minAreaRect(detObj->at(0)->contour); cv::rectangle(show, rr.boundingRect(), cv::Scalar( 0, 255, 0 ), 1 ); Point2f rect_points[4]; rr.points(rect_points); for( int j = 0; j < 4; j++ ) line( show, rect_points[j], rect_points[(j+1)%4], cv::Scalar( 255, 0, 0 ), 1, 8 ); //circle( imgCopy, o->massCenter, 2, Scalar( 0, 255, 255 ), FILLED, LINE_AA); } cv::namedWindow("Trackeds", cv::WINDOW_NORMAL); cv::imshow("Trackeds", show); if(!tracker) { bbox = cv::minAreaRect(detObj->at(0)->contour).boundingRect(); #if (OCV_VERSION_MAJOR >= 3 ) && (OCV_VERSION_MINOR > 1) tracker = cv::TrackerKCF::create( ); #else tracker = cv::Tracker::create( "KCF" ); #endif tracker->init(*img,bbox); } else { bbox = cv::minAreaRect(detObj->at(0)->contour).boundingRect(); tracker->update(*img, bbox); // Draw bounding box cv::rectangle(*img, bbox, cv::Scalar( 255, 0, 0 ), 1 ); // Display result cv::namedWindow("Tracking", cv::WINDOW_NORMAL); cv::imshow("Tracking", *img); } return true; }
int main() { if(!lcm1.good()) return 1; VideoCapture cap(1); cap >> frame; start_time = utime_now(); float x=0,y=0,z=0; int estPixel; //Temporary local variables Rect trackWindow; int hsize = 16; float hranges[] = {0,180}; const float* phranges = hranges; Mat hsv, hue, mask, hist, histimg = Mat::zeros(200, 320, CV_8UC3), backproj; bool paused = false; int _vmin,_vmax; namedWindow( "CamShift Demo", 1 ); setMouseCallback( "CamShift Demo", onMouse, 0 ); while(!frame.empty()) { RotatedRect trackBox; if( !paused ) { //resize(frame,frame,Size(FRAME_W,FRAME_H)); frame_number = cap.get(CV_CAP_PROP_POS_FRAMES); } frame.copyTo(image); if( !paused ) { cvtColor(image, hsv, COLOR_BGR2HSV); if( trackObject ) { _vmin = CAM_VMIN, _vmax = CAM_VMAX; inRange(hsv, Scalar(0, CAM_SMIN, MIN(_vmin,_vmax)), Scalar(180, 256, MAX(_vmin, _vmax)), mask); int ch[] = {0, 0}; hue.create(hsv.size(), hsv.depth()); mixChannels(&hsv, 1, &hue, 1, ch, 1); if( trackObject < 0 ) { destroyAllWindows(); Mat roi(hue, selection), maskroi(mask, selection); calcHist(&roi, 1, 0, maskroi, hist, 1, &hsize, &phranges); normalize(hist, hist, 0, 255, CV_MINMAX); trackWindow = selection; trackObject = 1; histimg = Scalar::all(0); int binW = histimg.cols / hsize; Mat buf(1, hsize, CV_8UC3); for( int i = 0; i < hsize; i++ ) buf.at<Vec3b>(i) = Vec3b(saturate_cast<uchar>(i*180./hsize), 255, 255); cvtColor(buf, buf, CV_HSV2BGR); for( int i = 0; i < hsize; i++ ) { int val = saturate_cast<int>(hist.at<float>(i)*histimg.rows/255); rectangle( histimg, Point(i*binW,histimg.rows),Point((i+1)*binW,histimg.rows - val),Scalar(buf.at<Vec3b>(i)), -1, 8 ); } } calcBackProject(&hue, 1, 0, hist, backproj, &phranges); backproj &= mask; trackBox = CamShift(backproj, trackWindow, TermCriteria( CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1 )); if( trackWindow.area() <= 1 ) { int cols = backproj.cols, rows = backproj.rows, r = (MIN(cols, rows) + 5)/6; trackWindow = Rect(trackWindow.x - r, trackWindow.y - r,trackWindow.x + r, trackWindow.y + r) &Rect(0, 0, cols, rows); if (trackWindow.area() == 0) trackWindow = Rect(360,240,100,100); } rectangle(image,trackBox.boundingRect(),Scalar(0,0,255),3); } if( backprojMode ) cvtColor( backproj, image, COLOR_GRAY2BGR ); else if( trackObject < 0 ) paused = false; if( selectObject && selection.width > 0 && selection.height > 0 ) { Mat roi(image, selection); bitwise_not(roi, roi); } imshow( "CamShift Demo", image ); waitKey(10); char c = (char)waitKey(30); if( c == 27 ) exit(0); switch(c) { case 'b': backprojMode = !backprojMode; break; case 'c': trackObject = 0; histimg = Scalar::all(0); break; case 'h': showHist = !showHist; if( !showHist ) destroyWindow( "Histogram" ); else namedWindow( "Histogram", 1 ); break; case 'p': paused = !paused; break; default: ; } if(!paused) { estPixel = trackBox.boundingRect().width; if(estPixel!=1) { z = hgtEst(estPixel,0.0025,3.31,177.8); x = persProj(trackBox.boundingRect().x+((trackBox.boundingRect().width)/2.0), z, 1325.55); y = persProj(trackBox.boundingRect().y+((trackBox.boundingRect().height)/2.0),z, 1325.55); } else { x=0;y=0;z=0; } cap >> frame; end_time = utime_now(); time_diff = end_time - start_time; // cout<<time_diff<<endl; start_time = end_time; vision_msg.timestamp = utime_now(); vision_msg.velocity[0] = (vision_msg.position[0] - x)/time_diff*1000; vision_msg.velocity[1] = (vision_msg.position[1] - y)/time_diff*1000; vision_msg.velocity[2] = (vision_msg.position[2] - z)/time_diff*1000; vision_msg.position[0] = x; vision_msg.position[1] = y; vision_msg.position[2] = z; lcm1.publish("vision state", &vision_msg); if( frame.empty() ) break; } }
JNIEXPORT void JNICALL Java_com_samou_twodimlda_DetectionBasedTracker_nativeDetect (JNIEnv * jenv, jclass, jlong thiz, jlong imageGray, jlong faces, jlong landmark, jlong predict) { LOGD("Java_com_samou_twodimlda_DetectionBasedTracker_nativeDetect enter"); try { vector<Rect> RectFaces; vector<Point> eye; vector<int> result; ((DetectionBasedTracker*)thiz)->process(*((Mat*)imageGray)); ((DetectionBasedTracker*)thiz)->getObjects(RectFaces); IplImage temp2 = IplImage(*((Mat*)imageGray)); int p1[2], p2[2]; // our recognition propotion float k = 0.262 / 0.476; float w, h, eye_ball_w; // eye area's 4 corner position int xa, xb, xc, xd, ya, yb, yc, yd; for ( int i = 0; i < RectFaces.size(); i++ ) { bbox[0] = RectFaces[i].x; bbox[1] = RectFaces[i].y; bbox[2] = RectFaces[i].x + RectFaces[i].width; bbox[3] = RectFaces[i].y + RectFaces[i].height; flandmark_detect(&temp2, bbox, model, landmarks); p1[0] = static_cast<int>((landmarks[1*2] + landmarks[5*2])/2); p1[1] = static_cast<int>((landmarks[1*2+1] + landmarks[5*2+1]) / 2); p2[0] = static_cast<int>((landmarks[2*2] + landmarks[6*2])/2); p2[1] = static_cast<int>((landmarks[2*2+1] + landmarks[6*2+1]) / 2); eye.push_back(cv::Point(p1[0], p1[1])); eye.push_back(cv::Point(p2[0], p2[1])); Mat dst_img = Mat::zeros(81, 201, CV_8UC1); w = (1/0.476)*sqrt(pow(p1[0] - p2[0], 2) + pow(p1[1] - p2[1], 2)); eye_ball_w = static_cast<int>(w /4); h = w * 0.4; xa = static_cast<int>(p1[0] - k * (p2[0] - p1[0])); xb = xa; xd = static_cast<int>(p2[0] + k * (p2[0] - p1[0])); xc = xd; ya = static_cast<int>(p1[1] - k * (p2[1] - p1[1]) - 0.5 * h); yb = static_cast<int>(ya + h); yd = static_cast<int>(p2[1] + k * (p2[1] - p1[1]) - 0.5 * h); yc = static_cast<int>(yd + h); // cvCircle(&temp, cvPoint(xa, ya), 3, CV_RGB(0, 255, 0), CV_FILLED); // cvCircle(&temp, cvPoint(xb, yb), 3, CV_RGB(0, 255, 0), CV_FILLED); // cvCircle(&temp, cvPoint(xc, yc), 3, CV_RGB(0, 255, 0), CV_FILLED); // cvCircle(&temp, cvPoint(xd, yd), 3, CV_RGB(0, 255, 0), CV_FILLED); vector<Point> eye_area; eye_area.push_back(Point(xa, ya) ); eye_area.push_back(Point(xd, yd) ); eye_area.push_back(Point(xb, yb) ); eye_area.push_back(Point(xc, yc) ); RotatedRect box = minAreaRect(Mat(eye_area)); Point2f pts[4]; box.points(pts); cv::Point2f ori[] = {eye_area[0], eye_area[1], eye_area[2], eye_area[3]}; cv::Point2f dst[] = {Point(0, 0), \ Point(box.boundingRect().width-1, 0), \ Point(0, box.boundingRect().height-1), \ Point(box.boundingRect().width-1, \ box.boundingRect().height-1)}; Mat warpAffineMatrix = getAffineTransform(ori, dst); cv::Size size(box.boundingRect().width, box.boundingRect().height); warpAffine(*((Mat*)imageGray), dst_img, warpAffineMatrix, \ size, INTER_LINEAR, BORDER_CONSTANT); Mat d = dst_img.clone(); resize(d, dst_img, Size(201, 81), 0, 0, cv::INTER_LINEAR); // recognition Mat obj = dst_img.clone(); GaussianBlur(obj, obj, Size(5, 5), 2, 0); obj.convertTo(obj, CV_32FC1); Mat data_test_vector = obj * eigen_selected; double min = 1000000; int record_N = -1; for ( int class_num = 0; class_num < 49; class_num++ ) { Mat temp_mat = data_test_vector - class_mean_vector.at(class_num); double distance = 0; for (int col_num = 0; col_num < temp_mat.cols; col_num++) { distance += norm(temp_mat.col(col_num)); } if (distance <= min) { if (distance <= 8600 ) record_N = class_num + 1; min = distance; } } LOGD("Face %d Recognition result: %d\n\n", i, record_N); result.push_back(record_N); } vector_Point_to_Mat(eye, *((Mat*)landmark)); vector_int_to_Mat(result, *((Mat*)predict)); vector_Rect_to_Mat(RectFaces, *((Mat*)faces)); } catch(cv::Exception& e) { LOGD("nativeCreateObject caught cv::Exception: %s", e.what()); jclass je = jenv->FindClass("org/opencv/core/CvException"); if(!je) je = jenv->FindClass("java/lang/Exception"); jenv->ThrowNew(je, e.what()); } catch (...) { LOGD("nativeDetect caught unknown exception"); jclass je = jenv->FindClass("java/lang/Exception"); jenv->ThrowNew(je, "Unknown exception in JNI code DetectionBasedTracker.nativeDetect()"); } LOGD("Java_com_samou_twodimlda_DetectionBasedTracker_nativeDetect exit"); }
int main() { //for serial port int fd = open_port(); fd_set readfs; if (fd == -1) { std::cout << "Could not open /dev/ttyUSB1" << std::endl; return -1; } struct timeval Timeout; Timeout.tv_usec = 0; /* milliseconds */ Timeout.tv_sec = 0; /* seconds */ //for stereo int w=640, h=480; Mat M1, M2, D1, D2, R1, R2, P1, P2, mx1, mx2, my1, my2, Q; FileStorage fs; fs.open("intrinsics.xml", FileStorage::READ); fs["M1"] >> M1; fs["D1"] >> D1; fs["M2"] >> M2; fs["D2"] >> D2; fs.release(); fs.open("extrinsics.xml", FileStorage::READ); fs["R1"] >> R1; fs["P1"] >> P1; fs["R2"] >> R2; fs["P2"] >> P2; fs["Q"] >> Q; fs.release(); Q.convertTo(Q, CV_32F); initUndistortRectifyMap(M1, D1, R1, P1, Size(w, h), CV_32FC1, mx1, my1); initUndistortRectifyMap(M2, D2, R2, P2, Size(w, h), CV_32FC1, mx2, my2); int ndisp = 192; //288 96 192 48 StereoBM bm(StereoBM::BASIC_PRESET); bm.state->preFilterCap = 31; bm.state->SADWindowSize = 41; bm.state->minDisparity = 48; bm.state->numberOfDisparities = ndisp; bm.state->textureThreshold = 10; bm.state->uniquenessRatio = 15; bm.state->speckleWindowSize = 100; bm.state->speckleRange = 32; bm.state->disp12MaxDiff = 1; //for SURF Mat object = imread("photo20.jpg", CV_LOAD_IMAGE_GRAYSCALE); if( !object.data ) { std::cout<< "Error reading object " << std::endl; return -1; } std::vector<Point2f> obj_corners(4); obj_corners[0] = cvPoint(0, 0); obj_corners[1] = cvPoint(object.cols, 0); obj_corners[2] = cvPoint(object.cols, object.rows); obj_corners[3] = cvPoint(0, object.rows); SurfFeatureDetector detector(400); SurfDescriptorExtractor extractor; FlannBasedMatcher matcher; std::vector<KeyPoint> kp_object; Mat des_object; detector.detect(object, kp_object); extractor.compute(object, kp_object, des_object); //miscellaneous char key = 'a'; int framecount = 0, count = 0; Camera cl("/dev/video2", w, h, 20); Camera cr("/dev/video1", w, h, 20); namedWindow("disparity"); namedWindow("object detection"); int window = 25, offset = 125; //35 pixels on either side, centre 25 pixels to the right of 240 bool is_open = false, isforward = false, nointerrupt = false; while (key != 27) { //flags bool ask = false, left = false, right = false, middle = false, inrange = false, detect = false, stop = false; //serial receiving FD_SET(fd, &readfs); select(fd + 1, &readfs, NULL, NULL, &Timeout); void *buf; int rx = 0; if (FD_ISSET(fd, &readfs)) { rx = read(fd, buf, 1); tcflush(fd, TCIFLUSH); ask = true; //isforward = false; } char extent = 0; float depth; IplImage *l=cvCreateImage(Size(w, h), 8, 3); IplImage *r=cvCreateImage(Size(w, h), 8, 3); cl.Update(&cr); if (framecount < 5) { framecount++; continue; } cl.toIplImage(l); cr.toIplImage(r); Mat lg, rg, lge, rge; cvtColor(Mat(l), lg, CV_RGB2GRAY); cvtColor(Mat(r), rg, CV_RGB2GRAY); equalizeHist(lg, lge); equalizeHist(rg, rge); line(lg, Point(w/2 - window + offset, 0), Point(w/2 - window + offset, h), Scalar(0, 255, 0), 2); line(lg, Point(w/2 + window + offset, 0), Point(w/2 + window + offset, h), Scalar(0, 255, 0), 2); line(rg, Point(w/2 - window - offset, 0), Point(w/2 - window - offset, h), Scalar(0, 255, 0), 2); line(rg, Point(w/2 + window - offset, 0), Point(w/2 + window - offset, h), Scalar(0, 255, 0), 2); Mat des_image, img_matches, H; std::vector<KeyPoint> kp_image; std::vector<vector<DMatch > > matches; std::vector<DMatch > good_matches; std::vector<Point2f> obj; std::vector<Point2f> scene; std::vector<Point2f> scene_corners(4); detector.detect(lg, kp_image); extractor.compute(lg, kp_image, des_image); matcher.knnMatch(des_object, des_image, matches, 2); for(int i = 0; i < matches.size(); i++) //THIS LOOP IS SENSITIVE TO SEGFAULTS { if(matches[i].size()==2 && (matches[i][0].distance < 0.8*(matches[i][1].distance)) ) { good_matches.push_back(matches[i][0]); obj.push_back(kp_object[matches[i][0].queryIdx].pt); scene.push_back(kp_image[matches[i][0].trainIdx].pt); } } if (good_matches.size() >= 35) { H = findHomography(obj, scene, CV_RANSAC); perspectiveTransform(obj_corners, scene_corners, H); RotatedRect box = minAreaRect(scene_corners); Point2f rect_corners[4]; box.points(rect_corners); Rect roi = box.boundingRect(); if (roi.area() > 3000) { detect = true; count = 0; for (int i = 0; i < 4; i++) { line(lg, rect_corners[i], rect_corners[(i+1)%4], Scalar(255, 255, 255), 4); } line(lg, box.center, box.center, Scalar(255, 255, 255), 8); if (box.center.x < w/2 - window + offset) { left = true; //write(fd, "a", 1); extent = (w/2 + offset - box.center.x) / 5; //std::cout << int(extent) << std::endl; if (extent < 6) extent = 6; if (isforward == true) stop = true; } else if (box.center.x > w/2 + window + offset) { right = true; //write(fd, "d", 1); extent = (box.center.x - (w/2 + offset)) / 5; //std::cout << int(extent) << std::endl; if (extent < 6) extent = 6; if (isforward == true) stop = true; } else if (box.center.x > w/2 - window + offset && box.center.x < w/2 + window + offset) { middle = true; Mat lr, rr; //imshow("l", lg); imshow("r", rg); remap(lge, lr, mx1, my1, INTER_LINEAR); remap(rge, rr, mx2, my2, INTER_LINEAR); Mat disp, vdisp, disp32; bm(lr, rr, disp); disp.convertTo(vdisp, CV_8U, 255/(ndisp*16.)); disp.convertTo(disp32, CV_32F, 1.f/16.f); for (int i = 0; i < 4; i++) { line(vdisp, rect_corners[i], rect_corners[(i+1)%4], Scalar(255, 255, 255), 4); } line(vdisp, box.center, box.center, Scalar(255, 255, 255), 8); imshow("disparity", vdisp); Mat xyz; reprojectImageTo3D(disp32, xyz, Q, true); int ch[] = {2, 0}; Mat z(xyz.size(), CV_32FC1); mixChannels(&xyz, 1, &z, 1, ch, 1); float dist = 0; unsigned long int npts = 0; for (int i = 0; i < z.rows; i++) { for (int j = 0; j < z.cols; j++) { if (roi.contains(Point(j, i)) && z.at<float>(i, j) > -500.0 && z.at<float>(i, j) < 500.0) { dist += z.at<float>(i, j); npts++; } } } //std::cout << -dist/npts << std::endl; depth = 1.1561 * ((-dist/npts) - 0.124); std::cout << depth << std::endl; extent = depth > 0 && depth < 45 ? (char(depth) - 6) / 3 : 2; if (depth > 0 && depth < 35) inrange = true; if (depth > 0 && depth < 30) nointerrupt = true; } } } //decisions and commanding if (stop && !nointerrupt) {write(fd, "x", 1); write(fd, &extent, 1); isforward = false; std::cout << "stop" << std::endl;} if (ask) { std::cout << "got" << std::endl; if (left) {write(fd, "a", 1); write(fd, &extent, 1); tcflush(fd, TCIFLUSH);} if (right) {write(fd, "d", 1); write(fd, &extent, 1); tcflush(fd, TCIFLUSH);} //if ((middle && !inrange) || (middle && is_open)) {write(fd, "w", 1); write(fd, &extent, 1); tcflush(fd, TCIFLUSH); isforward = true;} //if (inrange && !is_open){write(fd, "o", 1); write(fd, &extent, 1); is_open = true; std::cout << "open" << std::endl;} if (middle) { if (!is_open) {write(fd, "o", 1); write(fd, &extent, 1); is_open = true; std::cout << "open" << std::endl;} else {write(fd, "w", 1); write(fd, &extent, 1); tcflush(fd, TCIFLUSH); isforward = true;} } if (!detect) { count ++; if (count > 14) { count = 0; if (is_open) {write(fd, "c", 1); write(fd, &extent, 1); is_open = false; nointerrupt = false; std::cout << "close" << std::endl;} } } } imshow("object detection", lg); key = cv::waitKey(1); cvReleaseImage(&l); cvReleaseImage(&r); } return 0; }
vector<PlateRegion> DetectorMorph::detect(Mat frame, std::vector<cv::Rect> regionsOfInterest) { Mat frame_gray,frame_gray_cp; if (frame.channels() > 2) { cvtColor( frame, frame_gray, CV_BGR2GRAY ); } else { frame.copyTo(frame_gray); } frame_gray.copyTo(frame_gray_cp); blur(frame_gray, frame_gray, Size(5, 5)); vector<PlateRegion> detectedRegions; for (int i = 0; i < regionsOfInterest.size(); i++) { Mat img_open, img_result; Mat element = getStructuringElement(MORPH_RECT, Size(30, 4)); morphologyEx(frame_gray, img_open, CV_MOP_OPEN, element, cv::Point(-1, -1)); img_result = frame_gray - img_open; if (config->debugDetector && config->debugShowImages) { imshow("Opening", img_result); } //threshold image using otsu thresholding Mat img_threshold, img_open2; threshold(img_result, img_threshold, 0, 255, CV_THRESH_OTSU + CV_THRESH_BINARY); if (config->debugDetector && config->debugShowImages) { imshow("Threshold Detector", img_threshold); } Mat diamond(5, 5, CV_8U, cv::Scalar(1)); diamond.at<uchar>(0, 0) = 0; diamond.at<uchar>(0, 1) = 0; diamond.at<uchar>(1, 0) = 0; diamond.at<uchar>(4, 4) = 0; diamond.at<uchar>(3, 4) = 0; diamond.at<uchar>(4, 3) = 0; diamond.at<uchar>(4, 0) = 0; diamond.at<uchar>(4, 1) = 0; diamond.at<uchar>(3, 0) = 0; diamond.at<uchar>(0, 4) = 0; diamond.at<uchar>(0, 3) = 0; diamond.at<uchar>(1, 4) = 0; morphologyEx(img_threshold, img_open2, CV_MOP_OPEN, diamond, cv::Point(-1, -1)); Mat rectElement = getStructuringElement(cv::MORPH_RECT, Size(13, 4)); morphologyEx(img_open2, img_threshold, CV_MOP_CLOSE, rectElement, cv::Point(-1, -1)); if (config->debugDetector && config->debugShowImages) { imshow("Close", img_threshold); waitKey(0); } //Find contours of possibles plates vector< vector< Point> > contours; findContours(img_threshold, contours, // a vector of contours CV_RETR_EXTERNAL, // retrieve the external contours CV_CHAIN_APPROX_NONE); // all pixels of each contours //Start to iterate to each contour founded vector<vector<Point> >::iterator itc = contours.begin(); vector<RotatedRect> rects; //Remove patch that are no inside limits of aspect ratio and area. while (itc != contours.end()) { //Create bounding rect of object RotatedRect mr = minAreaRect(Mat(*itc)); if (mr.angle < -45.) { mr.angle += 90.0; swap(mr.size.width, mr.size.height); } if (!CheckSizes(mr)) itc = contours.erase(itc); else { ++itc; rects.push_back(mr); } } //Now prunning based on checking all candidate plates for a min/max number of blobsc Mat img_crop, img_crop_b, img_crop_th, img_crop_th_inv; vector< vector< Point> > plateBlobs; vector< vector< Point> > plateBlobsInv; double thresholds[] = { 10, 40, 80, 120, 160, 200, 240 }; const int num_thresholds = 7; int numValidChars = 0; Mat rotated; for (int i = 0; i < rects.size(); i++) { numValidChars = 0; RotatedRect PlateRect = rects[i]; Size rect_size = PlateRect.size; // get the rotation matrix Mat M = getRotationMatrix2D(PlateRect.center, PlateRect.angle, 1.0); // perform the affine transformation warpAffine(frame_gray_cp, rotated, M, frame_gray_cp.size(), INTER_CUBIC); //Crop area around candidate plate getRectSubPix(rotated, rect_size, PlateRect.center, img_crop); if (config->debugDetector && config->debugShowImages) { imshow("Tilt Correction", img_crop); waitKey(0); } for (int z = 0; z < num_thresholds; z++) { cv::threshold(img_crop, img_crop_th, thresholds[z], 255, cv::THRESH_BINARY); cv::threshold(img_crop, img_crop_th_inv, thresholds[z], 255, cv::THRESH_BINARY_INV); findContours(img_crop_th, plateBlobs, // a vector of contours CV_RETR_LIST, // retrieve the contour list CV_CHAIN_APPROX_NONE); // all pixels of each contours findContours(img_crop_th_inv, plateBlobsInv, // a vector of contours CV_RETR_LIST, // retrieve the contour list CV_CHAIN_APPROX_NONE); // all pixels of each contours int numBlobs = plateBlobs.size(); int numBlobsInv = plateBlobsInv.size(); float idealAspect = config->avgCharWidthMM / config->avgCharHeightMM; for (int j = 0; j < numBlobs; j++) { cv::Rect r0 = cv::boundingRect(cv::Mat(plateBlobs[j])); if (ValidateCharAspect(r0, idealAspect)) numValidChars++; } for (int j = 0; j < numBlobsInv; j++) { cv::Rect r0 = cv::boundingRect(cv::Mat(plateBlobsInv[j])); if (ValidateCharAspect(r0, idealAspect)) numValidChars++; } } //If too much or too lcittle might not be a true plate //if (numBlobs < 3 || numBlobs > 50) continue; if (numValidChars < 4 || numValidChars > 50) continue; PlateRegion PlateReg; // Ensure that the rectangle isn't < 0 or > maxWidth/Height Rect bounding_rect = PlateRect.boundingRect(); PlateReg.rect = expandRect(bounding_rect, 0, 0, frame.cols, frame.rows); detectedRegions.push_back(PlateReg); } } return detectedRegions; }
int main(int argc, char* argv[]) { //for opencv Mat // Mat m_srcdepth16u( XN_VGA_Y_RES,XN_VGA_X_RES,CV_16UC1); Mat m_depth16u( XN_VGA_Y_RES,XN_VGA_X_RES,CV_16UC1); Mat m_middepth8u( XN_VGA_Y_RES,XN_VGA_X_RES,CV_8UC1); Mat m_depth8u( XN_VGA_Y_RES,XN_VGA_X_RES,CV_8UC1); Mat m_rgb8u( XN_VGA_Y_RES,XN_VGA_X_RES,CV_8UC3); Mat m_DepthShow( XN_VGA_Y_RES,XN_VGA_X_RES,CV_8UC1); Mat m_srcDepthShow( XN_VGA_Y_RES,XN_VGA_X_RES,CV_8UC1); // openni variable // XnStatus nRet = XN_STATUS_OK ; char key = 0 ; xn::Context context ; nRet = context.Init() ; check_eorror(nRet,"context.Init" ) ; XnMapOutputMode mapMode ; mapMode.nXRes = XN_VGA_X_RES ; mapMode.nYRes = XN_VGA_Y_RES ; mapMode.nFPS = 30 ; xn::DepthGenerator depthGen ; nRet = depthGen.Create( context ) ; check_eorror(nRet,"depthGen.Create" ) ; nRet = depthGen.SetMapOutputMode( mapMode ) ; check_eorror(nRet,"depthGen.SetMapOutputMode" ) ; nRet = context.StartGeneratingAll() ; check_eorror(nRet,"StartGeneratingAll" ) ; nRet = context.WaitAndUpdateAll() ; check_eorror(nRet,"WaitAndUpdateAll" ) ; xn::DepthMetaData depthMD ; const int sizebuffer = XN_VGA_X_RES*XN_VGA_Y_RES*2; while ( key != 27 && !( nRet = context.WaitAndUpdateAll()) ) { depthGen.GetMetaData( depthMD ) ; memcpy(m_srcdepth16u.data,depthMD.Data(),sizebuffer); // 首先处理深度为 0 的点,这种实际上无法测量的点,所以将深度为 0 的点设成最大深度 // for( int i = 0; i < XN_VGA_Y_RES; i++) { for (int j = 0; j< XN_VGA_X_RES; j++) { unsigned short & temp = m_srcdepth16u.at<unsigned short>(i,j); if(temp == 0) { temp = 65535; } } } // 高斯滤波平滑 Ptr<FilterEngine> f = createGaussianFilter( m_srcdepth16u.type(), Size(9,9), 0.85, 0.85 ); f->apply(m_srcdepth16u, m_depth16u); // 深度图像二值化,阈值大概是取手掌的厚度, minValue存储的事距离kinect最近的指尖深度 double minValue, maxValue; minMaxIdx(m_depth16u, &minValue, &maxValue); for( int i = 0; i < XN_VGA_Y_RES; i++) { for (int j = 0; j<XN_VGA_X_RES; j++) { if(m_depth16u.at<unsigned short>(i,j) > minValue +50) { m_middepth8u.at<unsigned char>(i,j) =0; } else { m_middepth8u.at<unsigned char>(i,j) = 255; } } } m_middepth8u.copyTo(m_depth8u); // 取得手掌轮廓 // vector<vector<Point>> contours; findContours(m_middepth8u, contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE, Point(0,0)); Scalar color( 255, 0, 0 ); drawContours(m_depth8u, contours, -1, color); vector<Point> contourMerge; vector<vector<Point>>::iterator it; // 将轮廓数据合并到一个数组中 , 并获得包含此轮廓的最小矩形 // for (it=contours.begin(); it!=contours.end(); it++) { vector<Point> ¤tContour = *it; vector<Point>::iterator itContour; for (itContour=currentContour.begin();itContour!=currentContour.end(); itContour++) { contourMerge.push_back(*itContour); } } RotatedRect minRect = minAreaRect(Mat(contourMerge)); Point2f pt[4]; minRect.points(pt); line(m_depth8u, pt[0], pt[1], color); line(m_depth8u, pt[1], pt[2], color); line(m_depth8u, pt[2], pt[3], color); line(m_depth8u, pt[3], pt[0], color); // 将上述最小矩形取出,并旋转到正方向,横平竖直 Mat rotate8u = Mat(minRect.boundingRect().size(),CV_8UC1); Mat after_rotate8u =Mat(minRect.boundingRect().size(),CV_8UC1); getRectSubPix( m_depth8u, minRect.boundingRect().size(),minRect.center, rotate8u); Point2f rotateCenter = Point2f( minRect.boundingRect().size().width/2.0 , minRect.boundingRect().size().height/2.0 ); Mat rotateM = getRotationMatrix2D( rotateCenter, 90+minRect.angle, 1 ); warpAffine( rotate8u, after_rotate8u, rotateM, minRect.boundingRect().size() ); Mat scale8u = Mat( Size(30, minRect.size.width),CV_8UC1); getRectSubPix( after_rotate8u, Size(minRect.size.height,minRect.size.width), rotateCenter, scale8u ); rotate8u.convertTo(m_DepthShow,CV_8U); //m_depth8u.convertTo(m_DepthShow,CV_8U); // cvNamedWindow("before rotate"); imshow("before rotate",m_DepthShow); // scale8u.convertTo(m_DepthShow,CV_8U); //m_depth8u.convertTo(m_DepthShow,CV_8U); cvNamedWindow("test"); // 距离变换,获取骨架 Mat m_outdepth32u(scale8u.rows,scale8u.cols,CV_32FC1); distanceTransform(scale8u, m_outdepth32u, CV_DIST_L2,CV_DIST_MASK_5); // 显示距离变换得到结果 int i = 0, j = 0; float maxDist = 0.0; for( i = 0; i < scale8u.rows; i++) { for (j = 0; j<scale8u.cols; j++) { if(maxDist < m_outdepth32u.at<float>(i,j)) maxDist = m_outdepth32u.at<float>(i,j); } } m_outdepth32u.convertTo(m_DepthShow,CV_8U, 255/maxDist); imshow("test",m_DepthShow); key = cvWaitKey(330) ; }// while context.StopGeneratingAll() ; context.Shutdown() ; return 0; }// end of main