vector<int> FRID::getFeaturePoints() { int i,j; vector<int> r; uint _order = getOrder(); int sz=w4*h4; Mat sobelx, gradx, sobely,grady,sobel; Mat sobelgray_,sobelgray__,sobelgray; int totalPoints; Sobel(orderMap[_order],sobelx,CV_16S,1,0,3,1, 0, BORDER_DEFAULT ); convertScaleAbs( sobelx, gradx ); Sobel(orderMap[_order],sobely,CV_16S,0,1,3,1, 0, BORDER_DEFAULT ); convertScaleAbs( sobely, grady ); addWeighted( gradx, 0.5, grady, 0.5, 0, sobel ); cvtColor(sobel,sobelgray_,CV_RGB2GRAY); sobelgray_.convertTo(sobelgray__,CV_8UC1); double min,max; int maxid[2]; minMaxIdx(sobelgray__,&min,&max,0,maxid); threshold(sobelgray__,sobelgray__,(int)(((float)max)/255*100),1,THRESH_BINARY); totalPoints = sum(sobelgray__)[0]; cout<<"max: "<<max<<endl; cout<<"totalPoints: "<<totalPoints<<endl; double br; double bg; double bb; double bsr; double bsg; double bsb; int xmin,xmax,ymin,ymax; //Mat bufABSmat; //Mat bufABS2mat; Mat result1; Mat cdmat; orderMap[_order].copyTo(cdmat); for (i=0; i<sz; i++){ if (sobelgray__.at<uchar>(i/w4,i%w4) == 0) continue; float* bufABS = getFeatureVector(i%w4,i/w4,br,bg,bb,bsr,bsg,bsb); Mat bufABSmat ((_order/2-1)*3+3,1,CV_32FC1,bufABS); //bufABSmat; Mat corImg = Mat::zeros(Size(w4,h4),CV_8UC1); xmin=w4-1,xmax=0,ymin=h4-1,ymax=0; for (j=0; j<sz; j++){ if (sobelgray__.at<uchar>(j/w4,j%w4) == 0) continue; float* bufABS2 = getFeatureVector(j%w4,j/w4,br,bg,bb,bsr,bsg,bsb); Mat bufABS2mat ((_order/2-1)*3+3,1,CV_32FC1,bufABS2); matchTemplate(bufABSmat, bufABS2mat, result1, CV_TM_CCOEFF_NORMED); if (bsr>255 && bsg>255 && bsb>255 && pow(result1.at<float>(0),3)>0.5) { if (xmin > j%w4) xmin = j%w4; if (xmax < j%w4) xmax = j%w4; if (ymin > j/w4) ymin = j/w4; if (ymax < j/w4) ymax = j/w4; corImg.at<uchar>(j) = 1;//(result1.at<float>(0) > 0)? pow(result1.at<float>(0),10):0; if ((xmax-xmin)>6 && (ymax-ymin)>6)break; } } // namedWindow( "c", CV_WINDOW_AUTOSIZE ); // imshow( "c", corImg*255);//thrCrCb[0] ); // // waitKey(0); if ((xmax-xmin)<=6 && (ymax-ymin)<=6) { cout<<"xy: "<<i%w4<<", "<<i/w4<<endl; cout<<"totalPoints: "<<sum(sobelgray__)[0]<<endl; circle( cdmat, Point(i%w4,i/w4), 1, Scalar( 0, 0, 255 ), -1, 8 ); r.push_back(i%w4); r.push_back(i/w4); } //sobelgray__=sobelgray__-corImg; } //circle( cdmat, Point(maxid[1],maxid[0]), 1, Scalar( 0, 0, 255 ), -1, 8 ); return r; }
void ThresholdWindow::on_sizeSpinBox_valueChanged(int) { threshold(); }
void imageCb(const sensor_msgs::ImageConstPtr& msg) { ros::Time start = ros::Time::now(); cv_bridge::CvImagePtr cv_ptr; try { cv_ptr = cv_bridge::toCvCopy(msg, enc::BGR8); } catch (cv_bridge::Exception& e) { ROS_ERROR("cv_bridge exception: %s", e.what()); return; } // function call threshold_frame = threshold(cv_ptr->image); // MORPH_ELLIPSE=2 cv::Mat kernel = cv::getStructuringElement(2, cv::Size( 3, 3 ), cv::Point( -1, -1 )); // Dilate the image cv::dilate(threshold_frame, dilated, kernel, cv::Point(-1,-1), 5); // Erode the image cv::erode(dilated, eroded, kernel, cv::Point(-1,-1), 2); clone_eroded = eroded.clone(); std::vector< std::vector<cv::Point> > contours; // storage for the contours std::vector<cv::Vec4i> hierarchy; // hierachy // for saving the result frame //origin_result = result.clone(); // for saving the eroded frame200 clone_eroded = eroded.clone(); // just get the contours // using clone_eroded image cv::findContours( clone_eroded, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0,0) ); int no_ellipse(0); for( int i(0); i< (contours.size()); i++ ) { if( contours[i].size() < 50 ) continue; cv::drawContours( cv_ptr->image, contours, i, cv::Scalar(255,0,0), 1, 8 ); cv::Moments moms = cv::moments( cv::Mat(contours[i])); double area = moms.m00; double perimeter = cv::arcLength(cv::Mat(contours[i]),true); double circularity = 4*CV_PI*area/(perimeter*perimeter); if( circularity > 0.3 ) { cv::RotatedRect ellipse_candidate = cv::fitEllipse( cv::Mat(contours[i]) ); cv::ellipse( cv_ptr->image, ellipse_candidate, cv::Scalar(0,255,0), 2, 8 ); no_ellipse ++; // radius -> {(W+H)/2}/2 double radius_i = (ellipse_candidate.size.height+ellipse_candidate.size.width)/4; //std::cout << "height : " << std::setw(7) << ellipse_candidate.size.height // << " " << "width : " << std::setw(7) << ellipse_candidate.size.width // << " " << "radius : " << radius_i << std::endl; double f= 700; dist = 3 * f / radius_i; printf("R | Z = %f | %f\n", radius_i, double(dist) ); } //std::cout << "circularity " << circularity << std::endl; } cmd_command(); //cv::Rect rect(320-40, 240-30, 80, 60); //cv::rectangle(cv_ptr->image, rect, cv::Scalar(0,0,255), 5); cv::imshow("origin", cv_ptr->image); cv::imshow("threshold", threshold_frame); cv::waitKey(3); ros::Time now = ros::Time::now(); //std::cout << "processing time : " << now - start << " sec" << std::endl; image_pub_.publish(cv_ptr->toImageMsg()); }
bool cv::find4QuadCornerSubpix(InputArray _img, InputOutputArray _corners, Size region_size) { CV_INSTRUMENT_REGION() Mat img = _img.getMat(), cornersM = _corners.getMat(); int ncorners = cornersM.checkVector(2, CV_32F); CV_Assert( ncorners >= 0 ); Point2f* corners = cornersM.ptr<Point2f>(); const int nbins = 256; float ranges[] = {0, 256}; const float* _ranges = ranges; Mat hist; Mat black_comp, white_comp; for(int i = 0; i < ncorners; i++) { int channels = 0; Rect roi(cvRound(corners[i].x - region_size.width), cvRound(corners[i].y - region_size.height), region_size.width*2 + 1, region_size.height*2 + 1); Mat img_roi = img(roi); calcHist(&img_roi, 1, &channels, Mat(), hist, 1, &nbins, &_ranges); int black_thresh = 0, white_thresh = 0; segment_hist_max(hist, black_thresh, white_thresh); threshold(img, black_comp, black_thresh, 255.0, THRESH_BINARY_INV); threshold(img, white_comp, white_thresh, 255.0, THRESH_BINARY); const int erode_count = 1; erode(black_comp, black_comp, Mat(), Point(-1, -1), erode_count); erode(white_comp, white_comp, Mat(), Point(-1, -1), erode_count); std::vector<std::vector<Point> > white_contours, black_contours; std::vector<Vec4i> white_hierarchy, black_hierarchy; findContours(black_comp, black_contours, black_hierarchy, RETR_LIST, CHAIN_APPROX_SIMPLE); findContours(white_comp, white_contours, white_hierarchy, RETR_LIST, CHAIN_APPROX_SIMPLE); if(black_contours.size() < 5 || white_contours.size() < 5) continue; // find two white and black blobs that are close to the input point std::vector<std::pair<int, float> > white_order, black_order; orderContours(black_contours, corners[i], black_order); orderContours(white_contours, corners[i], white_order); const float max_dist = 10.0f; if(black_order[0].second > max_dist || black_order[1].second > max_dist || white_order[0].second > max_dist || white_order[1].second > max_dist) { continue; // there will be no improvement in this corner position } const std::vector<Point>* quads[4] = {&black_contours[black_order[0].first], &black_contours[black_order[1].first], &white_contours[white_order[0].first], &white_contours[white_order[1].first]}; std::vector<Point2f> quads_approx[4]; Point2f quad_corners[4]; for(int k = 0; k < 4; k++) { std::vector<Point2f> temp; for(size_t j = 0; j < quads[k]->size(); j++) temp.push_back((*quads[k])[j]); approxPolyDP(Mat(temp), quads_approx[k], 0.5, true); findCorner(quads_approx[k], corners[i], quad_corners[k]); quad_corners[k] += Point2f(0.5f, 0.5f); } // cross two lines Point2f origin1 = quad_corners[0]; Point2f dir1 = quad_corners[1] - quad_corners[0]; Point2f origin2 = quad_corners[2]; Point2f dir2 = quad_corners[3] - quad_corners[2]; double angle = acos(dir1.dot(dir2)/(norm(dir1)*norm(dir2))); if(cvIsNaN(angle) || cvIsInf(angle) || angle < 0.5 || angle > CV_PI - 0.5) continue; findLinesCrossPoint(origin1, dir1, origin2, dir2, corners[i]); } return true; }
void ThresholdWindow::on_otsuCheckBox_toggled(bool checked) { ui->thresholdSlider->setDisabled(checked); threshold(); }
void otsu(const ImageType& src,LabelImageType& label,class LabelImageType::value_type foreground = 1,class LabelImageType::value_type background = 0) { threshold(src,label,otsu_threshold(src),foreground,background); }
void l0Smooth(InputArray src, OutputArray dst, double lambda, double kappa) { Mat S = src.getMat(); CV_Assert(!S.empty()); CV_Assert(S.depth() == CV_8U || S.depth() == CV_16U || S.depth() == CV_32F || S.depth() == CV_64F); dst.create(src.size(), src.type()); if(S.data == dst.getMat().data) { S = S.clone(); } if(S.depth() == CV_8U) { S.convertTo(S, CV_32F, 1/255.0f); } else if(S.depth() == CV_16U) { S.convertTo(S, CV_32F, 1/65535.0f); } else if(S.depth() == CV_64F) { S.convertTo(S, CV_32F); } const double betaMax = 100000; // gradient operators in frequency domain Mat otfFx, otfFy; float kernel[2] = {-1, 1}; float kernel_inv[2] = {1,-1}; psf2otf(Mat(1,2,CV_32FC1, kernel_inv), otfFx, S.rows, S.cols); psf2otf(Mat(2,1,CV_32FC1, kernel_inv), otfFy, S.rows, S.cols); vector<Mat> denomConst; Mat tmp = pow2absComplex(otfFx) + pow2absComplex(otfFy); for(int i = 0; i < S.channels(); i++) { denomConst.push_back(tmp); } // input image in frequency domain vector<Mat> numerConst; dftMultiChannel(S, numerConst); /********************************* * solver *********************************/ double beta = 2 * lambda; while(beta < betaMax){ // h, v subproblem Mat h, v; filter2D(S, h, -1, Mat(1, 2, CV_32FC1, kernel), Point(0, 0), 0, BORDER_REPLICATE); filter2D(S, v, -1, Mat(2, 1, CV_32FC1, kernel), Point(0, 0), 0, BORDER_REPLICATE); Mat hvMag = h.mul(h) + v.mul(v); Mat mask; if(S.channels() == 1) { threshold(hvMag, mask, lambda/beta, 1, THRESH_BINARY); } else if(S.channels() > 1) { vector<Mat> channels(S.channels()); split(hvMag, channels); hvMag = channels[0]; for(int i = 1; i < S.channels(); i++) { hvMag = hvMag + channels[i]; } threshold(hvMag, mask, lambda/beta, 1, THRESH_BINARY); Mat in[] = {mask, mask, mask}; merge(in, 3, mask); } h = h.mul(mask); v = v.mul(mask); // S subproblem vector<Mat> denom(S.channels()); for(int i = 0; i < S.channels(); i++) { denom[i] = beta * denomConst[i] + 1; } Mat hGrad, vGrad; filter2D(h, hGrad, -1, Mat(1, 2, CV_32FC1, kernel_inv)); filter2D(v, vGrad, -1, Mat(2, 1, CV_32FC1, kernel_inv)); vector<Mat> hvGradFreq; dftMultiChannel(hGrad+vGrad, hvGradFreq); vector<Mat> numer(S.channels()); for(int i = 0; i < S.channels(); i++) { numer[i] = numerConst[i] + hvGradFreq[i] * beta; } vector<Mat> sFreq(S.channels()); divComplexByRealMultiChannel(numer, denom, sFreq); idftMultiChannel(sFreq, S); beta = beta * kappa; } Mat D = dst.getMat(); if(D.depth() == CV_8U) { S.convertTo(D, CV_8U, 255); } else if(D.depth() == CV_16U) { S.convertTo(D, CV_16U, 65535); } else if(D.depth() == CV_64F) { S.convertTo(D, CV_64F); } else { S.copyTo(D); } }
void AndarPelaParedeAteLinha::execute(Robotino *robotino) { float Vx = 200, Vy, w, distParede; float erroDist = 0; int paredeAlvo = robotino->paredeAlvo(); static State<Robotino> * voltar; static float a = std::sin(60*PI/180)/std::sin(80*PI/180); static float cos20 = std::cos(20*PI/180); static float K = R*(a-1); static float erro_int = 0; float e1 = robotino->irDistance(Robotino::IR_ESQUERDO_1); float e2 = robotino->irDistance(Robotino::IR_ESQUERDO_2); float ref_e1 = e2*a+K; float d1 = robotino->irDistance(Robotino::IR_DIREITO_1); float d2 = robotino->irDistance(Robotino::IR_DIREITO_2); float ref_d1 = 1.15*(d2*a+K); float distancia_da_esquerda, distancia_da_direita; float erro; vector<Vec4i> lines; Vec4i l, l2; Mat img, cdst; int num_linha = 0; int min_Hough = 70, dist_Hough = 50; int min_canny =150 , max_canny = 3*min_canny; distParede = robotino->getRefDistParede(); distParede += R; img = robotino->getImage(); cvtColor( img, cdst, CV_BGR2GRAY ); Canny( cdst, cdst, (double)min_canny, (double)max_canny, 3 ); convertScaleAbs(cdst, cdst); //cv::imshow("Canny",cdst); //cv::waitKey(1); threshold(cdst, cdst, (double)5, (double)255, CV_THRESH_BINARY); HoughLinesP(cdst, lines, 1, CV_PI/180, min_Hough, min_Hough, dist_Hough ); cvtColor( cdst, cdst, CV_GRAY2BGR ); if (paredeAlvo == Robotino::NORTEN90 || paredeAlvo == Robotino::OESTE0 || paredeAlvo == Robotino::SUL90 || paredeAlvo == Robotino::LESTE180){ erro = (e1-ref_e1); erro_int += erro*dt; w = Kp*erro+Ki*erro_int; distancia_da_esquerda = ((e1+ref_e1+2*R)*cos20)/2; erroDist = (distancia_da_esquerda) - distParede; Vy = Kpy*erroDist; std::cout << "erro dist: " << erroDist << "\n"; std::cout<< "Esquerda 1: " << e1 << std::endl; std::cout<< "RefEsquerda 1: " << ref_e1 << std::endl; std::cout<< "Esquerda 2: " << e2 << std::endl; std::cout << "Distância da esquerda: " << distancia_da_esquerda << "\n"; if (lines.size() > numeroLinhasMin){ if (paredeAlvo == Robotino::OESTE0) { robotino->setOdometry(robotino->odometryX(),-(distancia_da_esquerda*10+15),0); } if (paredeAlvo == Robotino::NORTEN90) { robotino->setOdometry((robotino->getAlturaMapa())*10 -(distancia_da_esquerda*10+15),robotino->odometryY(),-90); } if (paredeAlvo == Robotino::SUL90) { robotino->setOdometry((distancia_da_esquerda*10+15),robotino->odometryY(),90); } if (paredeAlvo == Robotino::LESTE180) { robotino->setOdometry(robotino->odometryX(),-((robotino->getLarguraMapa())*10 -(distancia_da_esquerda*10+15)),180); } } }else if (paredeAlvo == Robotino::SULN90 || paredeAlvo == Robotino::LESTE0 || paredeAlvo == Robotino::NORTE90 || paredeAlvo == Robotino::OESTE180) { erro = (d1-ref_d1); erro_int += erro*dt; w = -Kp*erro-Ki*erro_int; distancia_da_direita = ((d1+ref_d1+2*R)*cos20)/2; erroDist = distParede - ( distancia_da_direita ); Vy = Kpy*erroDist; std::cout<< "Direita 1: " << d1 << std::endl; std::cout<< "RefDireita 1: " << ref_d1 << std::endl; std::cout<< "Direita 2: " << d2 << std::endl; std::cout << "Distância da direita: " << distancia_da_direita << "\n"; if (lines.size() > numeroLinhasMin){ if (paredeAlvo == Robotino::SULN90) { robotino->setOdometry((distancia_da_direita*10+15),robotino->odometryY(),-90); } if (paredeAlvo == Robotino::LESTE0) { robotino->setOdometry(robotino->odometryX(),-((robotino->getLarguraMapa()) * 10-(distancia_da_direita*10+15)),0); } if (paredeAlvo == Robotino::NORTE90) { robotino->setOdometry((robotino->getAlturaMapa()*10 - (distancia_da_direita*10+15)),robotino->odometryY(),90); } if (paredeAlvo == Robotino::OESTE180) { robotino->setOdometry(robotino->odometryX(),-((distancia_da_direita*10+15)),180); } } } if(distParede > 99){ robotino->setVelocity(Vx,0,0); }else{ robotino->setVelocity(Vx,Vy,w); } for( size_t i = 0; i < lines.size(); i++ ){ Vec4i l = lines[i]; //if (l[3] > 100 || l[1] > 100){ num_linha++; //} } if (num_linha > numeroLinhasMin){ robotino->setVelocity(0,0,0); robotino->change_state(robotino->previous_state()); } }
//Role: Detecter les plaques d'immatriculation potentielles //Entrées: Image a traiter (const cv::Mat&) //Sorties: liste de plaque d'immatriculation (std::vector<Plate>&) bool PlateRecognizer::Detection( const cv::Mat& input_image, std::vector<Plate>& plates ) { cv::Mat gray; cv::cvtColor( input_image, gray, cv::COLOR_BGR2GRAY ); if ( showSteps ) { cv::imshow( "test", gray ); cv::waitKey(); } cv::Mat blur; cv::GaussianBlur( gray, blur, cv::Size( 5, 5 ), 0 ); if ( showSteps ) { cv::imshow( "test", blur ); cv::waitKey(); } cv::Mat sobel; cv::Sobel( blur, sobel, CV_8U, 1, 0, 3 ); if ( showSteps ) { cv::imshow( "test", sobel ); cv::waitKey(); } cv::Mat tres; threshold( sobel, tres, 0, 255, cv::THRESH_BINARY + cv::THRESH_OTSU ); if ( showSteps ) { cv::imshow( "test", tres ); cv::waitKey(); } cv::Mat element = cv::getStructuringElement( cv::MORPH_RECT, cv::Size( 23, 2 ) ); cv::Mat closing; cv::morphologyEx( tres, closing, cv::MORPH_CLOSE, element ); if ( showSteps ) { cv::imshow( "test", closing ); cv::waitKey(); } std::vector<std::vector<cv::Point>> contours; cv::findContours( closing, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE ); if ( showSteps ) { cv::Mat contourImg; closing.copyTo( contourImg ); cv::drawContours( contourImg, contours, -1, // draw all contours cv::Scalar( 255, 0, 0 ), // in blue 1 ); // with a thickness of 1 cv::imshow( "test", contourImg ); cv::waitKey(); } std::vector<std::vector<cv::Point> >::iterator itc = contours.begin(); cv::Mat result; input_image.copyTo( result ); while ( itc != contours.end() ) { if ( Validate( *itc ) ) { cv::RotatedRect rect = cv::minAreaRect( cv::Mat( *itc ) ); cv::Rect r = rect.boundingRect(); if ( r.x + r.width >= input_image.size().width ) r.width -= std::abs( ( input_image.size().width - ( r.x + r.width ) ) ); if ( r.y + r.height >= input_image.size().height ) r.height -= std::abs( ( input_image.size().height - ( r.y + r.height ) ) ); if ( r.x < 0 ) r.x = 0; if ( r.y < 0 ) r.y = 0; std::cout << rect.boundingRect() << std::endl; rect.boundingRect() = r; std::cout << rect.boundingRect() << std::endl; cv::Mat pMat = input_image( r ); plates.push_back( Plate( pMat, rect ) ); ++itc; } else itc = contours.erase( itc ); } return plates.size() > 0 ? true : false; }
int beaconpics_main(struct beacon_loc orientation) { int thresh=140; namedWindow("Original 1", WINDOW_NORMAL); namedWindow("Original 2", WINDOW_NORMAL); namedWindow("Original 3", WINDOW_NORMAL); namedWindow("Diff", WINDOW_NORMAL); //hsvParams hsv = {76,0,224,97,37,255}; hsvParams hsv = {20,0,0,97,37,255}; //Set up blob detection parameters SimpleBlobDetector::Params params; // params.blobColor //can we use this??? // params.minDistBetweenBlobs = 50.0f; params.filterByInertia = true; params.filterByConvexity = false; params.filterByColor = false; params.filterByCircularity = false; params.filterByArea = true; params.minThreshold = 150; params.maxThreshold = 255; params.thresholdStep = 1; params.minArea = 0; params.minConvexity = 0.3; params.minInertiaRatio = 0.10; params.maxArea = 2000; params.maxConvexity = 10; vector<KeyPoint> keypoints; VideoCapture cap(0); //capture the video from web cam if ( !cap.isOpened() ) // if not success, exit program { cout << "Cannot open the web cam" << endl; return -1; } while(true) { Mat imgOriginal1 = getPic(cap); Mat imgOriginal2 = getPic(cap); Mat imgOriginal3 = getPic(cap); Mat imgHSV1,imgHSV2, imgHSV3; if(imgOriginal1.empty() || imgOriginal2.empty() || imgOriginal3.empty()) { cout << "can not open " << endl; return -1; } Mat diff; absdiff(imgOriginal1,imgOriginal2,diff); cvtColor(diff, diff, COLOR_BGR2GRAY); //Convert the captured threshold(diff, diff, thresh, 255, cv::THRESH_BINARY); dilate(diff, diff, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)) ); //opencv 3.0 version //detect beacon blobs between pictures 1&2 Ptr<SimpleBlobDetector> blobDetect = SimpleBlobDetector::create(params); blobDetect->detect( diff, keypoints ); cout<<keypoints.size()<<endl; //detect blobs between images 2&3 if(keypoints.size() ==0) { absdiff(imgOriginal2,imgOriginal3,diff); cvtColor(diff, diff, COLOR_BGR2GRAY); //Convert the captured threshold(diff, diff, thresh, 255, cv::THRESH_BINARY); dilate(diff, diff, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)) ); blobDetect = SimpleBlobDetector::create(params); blobDetect->detect( diff, keypoints ); } cout<<keypoints.size()<<endl; Mat out; drawKeypoints(diff, keypoints, out, CV_RGB(0,0,0), DrawMatchesFlags::DEFAULT); /*//finding if things are green or red cvtColor(out, out, COLOR_BGR2HSV); inRange(out, Scalar(hsv.hL, hsv.sL, hsv.vL), Scalar(hsv.hH, hsv.sH, hsv.vH), out); blobDetect.detect( out, keypoints ); drawKeypoints(out, keypoints, out, CV_RGB(0,0,0), DrawMatchesFlags::DEFAULT); for(int i=0;i<diff.rows;i++){ for(int j=0;j<diff.cols;j++){ if(out.at<Vec3b>(i,j)[0]==0 && out.at<Vec3b>(i,j)[1]==0 && out.at<Vec3b>(i,j)[2]==0){ imgOriginalON.at<Vec3b>(i,j)=(0,0,0); } } } inRange(imgOriginalON, Scalar(hsv.hL, hsv.sL, hsv.vL), Scalar(hsv.hH, hsv.sH, hsv.vH), out); blobDetect.detect( out, keypoints ); drawKeypoints(out, keypoints, out, CV_RGB(0,0,0), DrawMatchesFlags::DEFAULT); */ //Circle blobs for(int i = 0; i < keypoints.size(); i++) { if(keypoints[i].size>0) circle(out, keypoints[i].pt, 1.5*keypoints[i].size, CV_RGB(0,255,0), 1, 8); } string text; if(keypoints.size() == 4) { text = "Object Found"; cout<<endl<<endl<<"Object Found"<<endl; Point cent; cent=findkeyPoint(keypoints); // cout<<"dist: "<<printDistanceFromLights(keypoints)<<endl; circle(out, cent, 5, CV_RGB(0,100,0), -1, 8); robot_angle(diff, cent.y, cent.x, 1); } else { text = "Error"; cout<<endl<<endl<<"No Object Found"<<endl; // while(keypoints.size() > 2) // thresh+=5; } imshow("Original 1", imgOriginal1); //show the original image imshow("Original 2", imgOriginal2); //show the original image imshow("Original 3", imgOriginal3); //show the original image imshow("Diff", out); waitKey(-1); } return 0; }
int Judgement::JudgementYON(Mat &image) { int success = 0; MatND dstHist; Mat histoImg = image.clone(); calcHist(&histoImg, 1, &channels, Mat(), dstHist, 1, &size, ranges); Mat dstImg(256, 256, CV_8U, Scalar(0));//画直方图 double minValue = 0; double maxValue = 0; Point maxloc; minMaxLoc(dstHist, &minValue, &maxValue, NULL, &maxloc); //cout << " " << n << "." << m << " " << maxValue << endl; int hpt = saturate_cast<int>(0.9 * 256); vector<int> Boundnum; for (int j = 0; j < 256; j++) { float binValue = dstHist.at<float>(j); int realValue = saturate_cast<int>(binValue * hpt / maxValue); if (realValue != 0) { rectangle(dstImg, Point(j, 255), Point(j, 256 - realValue), Scalar(255)); Boundnum.push_back(j); } } int maxdata = *max_element(Boundnum.begin(), Boundnum.end()); int mindata = *min_element(Boundnum.begin(), Boundnum.end());//寻找直方图动态范围 Rect recttemp; recttemp.x = maxloc.x; recttemp.y = maxloc.y - int((maxdata - mindata)*0.15); recttemp.width = 1; recttemp.height = int((maxdata - mindata)*0.3); rectangle(dstHist, recttemp, Scalar(0), -1); minMaxLoc(dstHist, &minValue, &maxValue, NULL, &maxloc); int anoThres = maxloc.y;//寻找次峰值 Scalar avgnum; Mat StdDevImg; meanStdDev(histoImg, avgnum, StdDevImg); double Stdnum = StdDevImg.at<double>(Point(0, 0)); int ThreStep = maxdata - mindata; int StepNum = 30; int OrStep = mindata + int(ThreStep / 10); int Dstep = int(ThreStep / 30.0 + 0.5); if (Dstep == 0) { Dstep = 1; StepNum = ThreStep; } Mat TempImg; histoImg.copyTo(TempImg); vector<vector<Point>> contours; vector<Vec4i> hierarchy; Point pointSN, maxPoint = Point(0, 0); int Marknumone = 0; int Marknumtwo = 0; int Marknumthree = 0; for (int i = 0; i < StepNum; i++) { vector<Point> SN; OrStep = OrStep + Dstep; threshold(histoImg, TempImg, OrStep, 255, CV_THRESH_BINARY); /*Mat element = getStructuringElement(MORPH_RECT,Size(2,2)); erode(TempImg, TempImg, cv::Mat()); dilate(TempImg, TempImg, cv::Mat());*/ TempImg = ~TempImg; /*stringstream strstrone; strstrone << "水渍动态图" << i << ".jpg"; imwrite(strstrone.str(), TempImg);*/ Mat BoundImg(TempImg.rows, TempImg.cols, CV_8UC1, Scalar(255)); Rect Wrect; Wrect.x = 1; Wrect.y = 1; Wrect.width = BoundImg.cols - 2; Wrect.height = BoundImg.rows - 2; rectangle(BoundImg, Wrect, Scalar(0), -1); Mat PlusImg(TempImg.rows + 2, TempImg.cols + 2, CV_8UC1, Scalar(255)); Mat PlusROI = PlusImg(Rect(1, 1, TempImg.cols, TempImg.rows)); TempImg.copyTo(PlusROI); Mat ContoursImg = PlusImg.clone(); findContours(ContoursImg, contours, hierarchy, RETR_TREE, CV_CHAIN_APPROX_SIMPLE); for (size_t j = 0; j < contours.size(); j++) { double area = cv::contourArea(contours[j]); pointSN.x = int(area); pointSN.y = j; SN.push_back(pointSN); } if (contours.size() != 0) { sort(SN.begin(), SN.end(), SortByM2); maxPoint = SN.back(); if (OrStep > anoThres - 5 && OrStep<anoThres + 20) Dstep = 1; else { Dstep = int(ThreStep / 30.0 + 0.5); } if (Dstep == 0) Dstep = 1; int k = maxPoint.y; Mat MarkImg(TempImg.rows, TempImg.cols, CV_8UC1, Scalar(0)); drawContours(MarkImg, contours, k, Scalar(255), -1); bitwise_and(BoundImg, MarkImg, MarkImg); int Mbound = 0;//判断轮廓是否到边界 Mbound = countNonZero(MarkImg); if (Mbound>0.5*(histoImg.cols)) break; if (contours[k].size() <= 4) continue; int son = hierarchy[k][2]; Point gravitycore = barycenter(contours[k]);//寻找轮廓重心 Rect maxcontours = boundingRect(contours[k]); int wValue = maxcontours.width / 12; gravitycore = gravitycore + Point(wValue - 1, wValue - 1); Mat gravityImg(TempImg.rows + 2 * wValue, TempImg.cols + 2 * wValue, CV_8UC1, Scalar(0)); Mat gravityImgROI = gravityImg(Rect(wValue, wValue, TempImg.cols, TempImg.rows)); TempImg.copyTo(gravityImgROI); Rect gravityrect = Rect(gravitycore - Point(1, 1), gravitycore + Point(2 * wValue, 2 * wValue) - Point(2, 2));//画出重心周围(2 * wValue)*(2 * wValue)的矩形区域 if (gravityrect.x < 0 || gravityrect.y < 0) continue; int avnum = countNonZero(gravityImg(Rect(gravityrect))); vector<Point> hull; convexHull(contours[k], hull, false); double promark = (contourArea(contours[k])) / (contourArea(hull)); if (son >= 0)//判断是否为父轮廓 { int sonarea = 0; for (size_t j = 0; j < contours.size(); j++) { if (hierarchy[j][3] == k&&contourArea(contours[j])>4.0) sonarea = sonarea + contourArea(contours[j]); } if (50 * sonarea>maxPoint.x)//此处忽略一些偶然出现的中空点 Marknumone++; } if (avnum < double(0.5 * gravityrect.width*gravityrect.width))//在重心区域中的白色点的数量是否过半 Marknumtwo++; if (promark < 0.6) Marknumthree++; } } if (Marknumone > 2 || Marknumtwo >= 2 || Marknumthree > 3)//缺陷点也可能偶然出现包含 { /*cout << "该点是水渍2" << endl;*/ } else { /*cout << "该点是缺陷2" << endl;*/ success++; } return success; }
void BackgroundSubtractorGMG::operator()(InputArray _image, OutputArray _fgmask, double newLearningRate) { if (!isDataInitialized) { CV_Error(CV_StsError,"BackgroundSubstractorGMG has not been initialized. Call initialize() first.\n"); } /* * Update learning rate parameter, if desired */ if (newLearningRate != -1.0) { if (newLearningRate < 0.0 || newLearningRate > 1.0) { CV_Error(CV_StsOutOfRange,"Learning rate for Operator () must be between 0.0 and 1.0.\n"); } this->learningRate = newLearningRate; } Mat image = _image.getMat(); _fgmask.create(imHeight,imWidth,CV_8U); fgMaskImage = _fgmask.getMat(); // 8-bit unsigned mask. 255 for FG, 0 for BG /* * Iterate over pixels in image */ // grab data at each pixel (1,2,3 channels, int, float, etc.) // grab data as an array of bytes. Then, send that array to a function that reads data into vector of appropriate types... and quantizing... before saving as a feature, which is a vector of flexitypes, so code can be portable. // multiple channels do have sequential storage, use mat::elemSize() and mat::elemSize1() vector<PixelModelGMG>::iterator pixel; vector<PixelModelGMG>::iterator pixel_end = pixels.end(); size_t i; //#pragma omp parallel for (i = 0, pixel=pixels.begin(); pixel != pixel_end; ++i,++pixel) { HistogramFeatureGMG newFeature; newFeature.color.clear(); int irow = int(i / imWidth); int icol = i % imWidth; for (size_t c = 0; c < numChannels; ++c) { /* * Perform quantization. in each channel. (color-min)*(levels)/(max-min). * Shifts min to 0 and scales, finally casting to an int. */ double color; switch(image.depth()) { case CV_8U: color = image.ptr<uchar>(irow)[icol * numChannels + c]; break; case CV_8S: color = image.ptr<schar>(irow)[icol * numChannels + c]; break; case CV_16U: color = image.ptr<ushort>(irow)[icol * numChannels + c]; break; case CV_16S: color = image.ptr<short>(irow)[icol * numChannels + c]; break; case CV_32S: color = image.ptr<int>(irow)[icol * numChannels + c]; break; case CV_32F: color = image.ptr<float>(irow)[icol * numChannels + c]; break; case CV_64F: color = image.ptr<double>(irow)[icol * numChannels + c]; break; default: color = 0; break; } size_t quantizedColor = (size_t)((color-minVal)*quantizationLevels/(maxVal-minVal)); newFeature.color.push_back(quantizedColor); } // now that the feature is ready for use, put it in the histogram if (frameNum > numInitializationFrames) // typical operation { newFeature.likelihood = float(learningRate); /* * (1) Query histogram to find posterior probability of feature under model. */ float likelihood = (float)pixel->getLikelihood(newFeature); // see Godbehere, Matsukawa, Goldberg (2012) for reasoning behind this implementation of Bayes rule float posterior = float((likelihood*backgroundPrior)/(likelihood*backgroundPrior+(1-likelihood)*(1-backgroundPrior))); /* * (2) feed posterior probability into the posterior image */ int row,col; col = i%imWidth; row = int(i-col)/imWidth; posteriorImage.at<float>(row,col) = (1.0f-posterior); } pixel->setLastObservedFeature(newFeature); } /* * (3) Perform filtering and threshold operations to yield final mask image. * * 2 options. First is morphological open/close as before. Second is "median filtering" which Jon Barron says is good to remove noise */ Mat thresholdedPosterior; threshold(posteriorImage,thresholdedPosterior,decisionThreshold,1.0,THRESH_BINARY); thresholdedPosterior.convertTo(fgMaskImage,CV_8U,255); // convert image to integer space for further filtering and mask creation medianBlur(fgMaskImage,fgMaskImage,smoothingRadius); fgMaskImage.copyTo(_fgmask); ++frameNum; // keep track of how many frames we have processed }
/** * Detects the basic scale parameters of a musical score. * Uses the well known histogram approach to find the most common pair of a consecutive black and white run. */ void RLEDetector::heightEstimation(const Mat& inputImage, int& lineheight_result, int& spaceheight_result, float lineTolerance, float spaceTolerance){ // 0. Apply threshold Mat threshImage; threshold(inputImage, threshImage, NULL, WHITE, CV_THRESH_OTSU); // 1. CREATE HISTOGRAM OF COMBINED WHITE-BLACK RUNS int state = WHITE; int whiteRun = 0; int blackRun = 0; uchar data; Mat h = Mat::zeros(Size(MAX_EXP_WHITE,MAX_EXP_BLACK),CV_16UC1); for(int x=0; x < threshImage.cols; x++){ whiteRun = 0; for(int y=0; y < threshImage.rows; y++){ data = threshImage.at<uchar>(y,x); switch(state){ case WHITE: if(data == BLACK){ state = BLACK; blackRun = 1; } else whiteRun++; break; case BLACK: if(data == WHITE || y == threshImage.rows-1){ state = WHITE; if(blackRun<h.rows && whiteRun < h.cols){ h.at<ushort>(blackRun,whiteRun)++;// = h.at<unsigned int>(blackRun,whiteRun)+1; } whiteRun = 1; blackRun = 0; } else blackRun++; break; } } } // 2. CLUSTER PEAKS // result: clusterEnd[i] saves the idx of the first element that does not belonging to that cluster anymore Point shortList[HISTO_SHORTLIST_LENGTH] = {}; Point *maxLoc = shortList; int clusterEnd[HISTO_SHORTLIST_LENGTH] = {1}; // second element doesn't yet belong to cluster 1 for(int i=1; i<HISTO_SHORTLIST_LENGTH; i++) clusterEnd[i] = -1; // 2.1 SHORTLIST N STRONGEST PEAKS (sorted) Mat1b mask(h.rows, h.cols); mask.setTo(1); for(int peakIdx=0; peakIdx<HISTO_SHORTLIST_LENGTH; peakIdx++){ minMaxLoc(h, 0, 0, 0, maxLoc,mask); mask.at<uchar>(*maxLoc) = 0; // exclude found maximum for next run //cout << peakIdx << ": " << *maxLoc << h.at<ushort>(*maxLoc) << endl; maxLoc++; // continue with next peak } // 2.2 SORT & CLUSTER for(int clusterIdx=0; clusterIdx<HISTO_SHORTLIST_LENGTH; clusterIdx++){ // representative = first element of a cluster, gives reference line and space heights int repIdx; // index of representative repIdx = clusterIdx > 0 ? clusterEnd[clusterIdx-1] : 0; if(repIdx >= HISTO_SHORTLIST_LENGTH) break; Point representative = shortList[repIdx]; // first unclustered is always the element after representative // check unclustered elements for(int elemIdx=repIdx+1; elemIdx<HISTO_SHORTLIST_LENGTH; elemIdx++){ // compare to first element of cluster and expand cluster if appropriate Point max = shortList[elemIdx]; if( abs(max.BLACKRUN-representative.BLACKRUN) <= representative.BLACKRUN*lineTolerance && abs(max.WHITERUN-representative.WHITERUN) <= representative.WHITERUN*spaceTolerance){ // expand cluster int lastElem = clusterEnd[clusterIdx]; Point temp = shortList[lastElem]; shortList[lastElem] = shortList[elemIdx]; shortList[elemIdx] = temp; clusterEnd[clusterIdx]++; } } // prepare next cluster only if this is not the last possible cluster and there are still free elements to be clustered if(clusterIdx+1 < HISTO_SHORTLIST_LENGTH && clusterEnd[clusterIdx]+1 < HISTO_SHORTLIST_LENGTH) clusterEnd[clusterIdx+1] = clusterEnd[clusterIdx]+1; /*cout << endl; for(int peakIdx=0; peakIdx<HISTO_SHORTLIST_LENGTH; peakIdx++) cout << peakIdx << ": " << shortList[peakIdx] << endl; cout << "cluster end: " << clusterEnd[clusterIdx] << endl; */ } // 2.3 DETERMINE WEIGHTS AND AVERAGES Point weightedSums[HISTO_SHORTLIST_LENGTH]; int clusterWeights[HISTO_SHORTLIST_LENGTH] = {}; int fattestClusterIdx = 0; ushort weight; int clusterElemIdx = 0; // for each cluster for(int clusterIdx=0; clusterEnd[clusterIdx]>=0; clusterIdx++){ // add all belonging elements to weights and averages for(; clusterElemIdx<clusterEnd[clusterIdx]; clusterElemIdx++){ weight = h.at<ushort>(shortList[clusterElemIdx]); // weight = number of occurences in histogram clusterWeights[clusterIdx] += weight; weightedSums[clusterIdx] += shortList[clusterElemIdx]*weight; } if(clusterWeights[clusterIdx] > clusterWeights[fattestClusterIdx]) fattestClusterIdx = clusterIdx; } Point result = weightedSums[fattestClusterIdx] * (1.f/clusterWeights[fattestClusterIdx]); //cout << clusterWeights[fattestClusterIdx] << endl; lineheight_result = result.BLACKRUN; spaceheight_result = result.WHITERUN; // show histogram //normalize(h,h,0,65535,CV_MINMAX); //namedWindow("Histogram",0); //imshow("Histogram",h); //cout << "used histo entries: "<<countNonZero(h) << " of " << h.rows*h.cols << endl; }
void ForegroundProcessor::threshMap(Mat foreground, int threshval) { int maxVal = 255; threshold(foreground, foreground, threshval, maxVal, THRESH_BINARY); }
/** @function thresh_callback */ void thresh_callback( Mat final_image , double yawO , vector<Point2i> cent_i , vector<double> area1 , int thresh, int max_thresh , RNG rng , int g) { Mat threshold_output; vector<vector<Point> > contours; vector<Vec4i> hierarchy; double largest_area = 0; int largest_contour_index = 0; double ang = 0; /// Detect edges using Threshold threshold( final_image, threshold_output, thresh, 255, THRESH_BINARY ); cvtColor(threshold_output, threshold_output, CV_BGR2GRAY); /// Find contours findContours( threshold_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) ); if( contours.size() > 0 ) { /// checking if any countour is detected /// Approximate contours to polygons + get bounding rects and circles vector<vector<Point> > contours_poly( contours.size() ); // vector<Rect> boundRect( contours.size() ); vector<Point2f>center( contours.size() ); vector<float>radius( contours.size() ); for( int i = 0; i < contours.size(); i++ ) { approxPolyDP( Mat(contours[i]), contours_poly[i], 3, true ); // boundRect[i] = boundingRect( Mat(contours_poly[i]) ); minEnclosingCircle( (Mat)contours_poly[i], center[i], radius[i] ); } // double b = contourArea( contours[0],false); for( int i = 0; i< contours.size(); i++ ) // iterate through each contour. { double a = contourArea( contours[i],false); // Find the area of contour if(a>largest_area){ largest_area=a; largest_contour_index = i; //Store the index of largest contour } } // minEnclosingCircle( (Mat)contours_poly[largest_contour_index], center[largest_contour_index], radius[largest_contour_index] ); /// Draw polygonal contour + bonding rects + circles Mat drawing = Mat::zeros( threshold_output.size(), CV_8UC3 ); for( int i = 0; i< contours.size(); i++ ) { Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) ); // drawContours( drawing, contours_poly, i, color, 1, 8, vector<Vec4i>(), 0, Point() ); //rectangle( drawing, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0 ); circle( drawing, center[i], (int)radius[i], color, 2, 8, 0 ); setLabel(drawing, "Target", contours[0]); // Triangles } ////////////////////////////////////////////////////////////////////////////////// /////////// FInding the angle //////////////////////////////////////////////////// int dist_x = center[0].x - cent_i[0].x; int dist_y = center[0].y - cent_i[0].y; cout<< " dist_x = " << dist_x << " dist_y =" << dist_y <<endl; //int ang = atan2 (dist_y,dist_x) * 180 / PI; ang = atan2 ( (dist_x) , (dist_y)) * 180 / PI; //cout<< "The target is "<< ( 90 - (ang - 90 ) ) << " degrees from x-axis"<<endl; // if( dist_x > 0 && ) // yawO = yawO - (-ang); yawO = -ang - 180 ; cout<< "The output yaw is "<<yawO<<endl; int area = (int)largest_area; cout<<"area = "<<area<<endl; cout<<endl; cout<< "frame no. = " << g << endl; area1.push_back(area); if( g > 3) { if( (area1[g-2] + area1[g-1] + area1[g])/3 > area ) cout<<" wrong direction "<<endl; else cout<<" right direction "<<endl; } ///////////////////////////////////////////////////////////////////////////////////////// /////////////////// putting the label ////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// /////// drawing the lines n the image ////////////////////////////////////////////// vector<Point2i> cent_k(1); vector<Point2i> cent_j(1); cent_k[0] = cent_i[0]; cent_k[0].x = cent_i[0].x - 20; cent_j[0] = cent_i[0]; cent_j[0].x = cent_i[0].x + 20; // Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) ); circle( drawing , cent_i[0] , 5 , Scalar( 72, 209, 51 ) , 2, 8 , 0); //circle( drawing , cent_i[0] , 2*5 , Scalar( 72, 209, 51 ) , 2, 8 , 0); //circle( drawing , cent_i[0] , 4*5 , Scalar( 72, 209, 51 ) , 2, 8 , 0); MyLine(drawing , (cent_k[0] ), (cent_j[0])); cent_k[0] = cent_i[0]; cent_k[0].y = cent_i[0].y - 20; cent_j[0] = cent_i[0]; cent_j[0].y = cent_i[0].y + 20; MyLine(drawing , (cent_k[0] ), (cent_j[0])); //////////////////////////////////////////////////////////////////////////////// // string x = -ang; std::vector<cv::Point> c_print; Point temp; temp.x = 10; temp.y = 10; c_print.push_back(temp); temp.x = 100; temp.y = 10; c_print.push_back(temp); temp.x = 10; temp.y = 20; c_print.push_back(temp); temp.x = 100; temp.y = 20; c_print.push_back(temp); setLabel(drawing, "Property of Somi" , c_print); stringstream ang_s; ang_s<< -ang; string ang_s1 = ang_s.str(); string s = "The angle of the target from x-axis is " + ang_s1; temp.x = 10; temp.y = 30; c_print.push_back(temp); temp.x = 100; temp.y = 30; c_print.push_back(temp); temp.x = 10; temp.y = 40; c_print.push_back(temp); temp.x = 100; temp.y = 40; c_print.push_back(temp); setLabel(drawing, s , c_print); /// Show in a window namedWindow( "Contours", CV_WINDOW_AUTOSIZE ); imshow( "Contours", drawing ); } }
void Decoder_LDPC_IEEE_802_11ad::Set_LDPC_Parameters() { /* * Parameterize the _Share class with the parameters from the configuration. */ check_node_algorithm_ = dec_algorithm(); num_lambda_min_ = num_lambda_min(); esf_factor_ = esf_factor(); bw_fract_ = bw_fract(); num_partitions_ = num_partitions(); threshold_ = threshold(); // Calculate the maximum values that can be represented by the chosen quantization. max_msg_extr_ = (1 << (bw_extr() - 1)) - 1; // max_msg_extr = 31 max_msg_app_ = (1 << (bw_app() - 1)) - 1; // Set LDPC code parameters. switch(ldpc_code()) { case IEEE_802_11AD_P42_N672_R050: num_variable_nodes_ = 672; num_check_nodes_ = 336; src_parallelism_ = 42; dst_parallelism_ = 42; max_check_degree_ = 8; is_IRA_code_ = false; addr_vector_ = &ieee_802_11ad_p42_n672_r050_addr[0]; shft_vector_ = &ieee_802_11ad_p42_n672_r050_shft[0]; break; case IEEE_802_11AD_P42_N672_R062: num_variable_nodes_ = 672; num_check_nodes_ = 252; src_parallelism_ = 42; dst_parallelism_ = 42; max_check_degree_ = 10; is_IRA_code_ = false; addr_vector_ = &ieee_802_11ad_p42_n672_r062_addr[0]; shft_vector_ = &ieee_802_11ad_p42_n672_r062_shft[0]; break; case IEEE_802_11AD_P42_N672_R075: num_variable_nodes_ = 672; num_check_nodes_ = 168; src_parallelism_ = 42; dst_parallelism_ = 42; max_check_degree_ = 15; is_IRA_code_ = false; addr_vector_ = &ieee_802_11ad_p42_n672_r075_addr[0]; shft_vector_ = &ieee_802_11ad_p42_n672_r075_shft[0]; break; case IEEE_802_11AD_P42_N672_R081: num_variable_nodes_ = 672; num_check_nodes_ = 126; src_parallelism_ = 42; dst_parallelism_ = 42; max_check_degree_ = 16; is_IRA_code_ = false; addr_vector_ = &ieee_802_11ad_p42_n672_r081_addr[0]; shft_vector_ = &ieee_802_11ad_p42_n672_r081_shft[0]; break; } }
void colorDetector::filter(pcl::PointIndices& fingertip_ptIdx, CloudPtr& detected_cloud) { //convert 3D color cloud to 2D color image cv::Mat image; rgbd_vision::convert_rgbd_to_image(_cloud, _clusters, image); if(DEBUG_COLOR) { cv::imshow("frame", image); cv::waitKey(-1); } // opencv color filtering in 2D images cv::Mat threshold(image.rows, image.cols, CV_8UC1); cv::inRange(image, cv::Scalar(_bl,_gl,_rl), cv::Scalar(_bh,_gh,_rh),threshold); // scalar(b,g,r) if(DEBUG_COLOR) { cv::imshow("color detection", threshold); cv::waitKey(-1); } // find largest connected component with detected color std::vector<std::vector<cv::Point> > contours; cv::findContours(threshold,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE); double max_area=0; int fingretip_index; for(int i=0; i<contours.size(); i++) { if(VERBOSE) std::cout << "contour[" << i << "] size = " << cv::contourArea(contours[i]) << std::endl; if(cv::contourArea(contours[i]) > max_area) { max_area = cv::contourArea(contours[i]); fingretip_index = i; } } // draw detected color object contour if(DEBUG_COLOR) { cv::Mat finger_image(image.rows, image.cols, CV_8UC1, cv::Scalar(0)); cv::drawContours(finger_image,contours,fingretip_index,cv::Scalar(255),CV_FILLED); cv::imshow("fingertip",finger_image); cv::waitKey(-1); } // find point indices of detected color object points _fingertip_ptIdx.indices.clear(); for(int r=0; r<threshold.rows; r++) { for(int c=0;c<threshold.cols; c++) { cv::Point pt(c,r); if(threshold.at<uchar>(r,c)!=0 & cv::pointPolygonTest(contours[fingretip_index],pt,false)>=0) { _fingertip_ptIdx.indices.push_back(r*threshold.cols+c); } } } std::cout << "fingertip size = " << _fingertip_ptIdx.indices.size() << std::endl; fingertip_ptIdx = _fingertip_ptIdx; _detectedCloud.reset(new Cloud); TableObject::convertCloud(_cloud, _fingertip_ptIdx, _detectedCloud); *detected_cloud = *_detectedCloud; }
//bool Depth_and_Disparity::calc_disperity(int desiredPhase, Mat in_left_clr, Mat in_right_clr, bool Depth_and_Disparity::calc_disperity(int desiredPhase, Mat left_im_gray, Mat right_im_gray, Mat BgMask , Target *previousTarget, Mat *disperity_out, double *min_depth_of_ROI) { double max_disperity; const double allowed_disp_delta_between_cycles = 0.1 ; //10[%] if ( ! (desiredPhase==2) ) //calculate the new disparity for new inputs { // delivers new input , when the process is waiting (not in calculation process) set_disparity_input(right_im_gray,left_im_gray, /*myStereoCams.GetFrameCycleCounter()*/ 1 ); // waiting trial : while (! get_rectified_and_disparity(last_result_of_disparity, last_result_of_disparity_struct) ) { } if ((desiredPhase==1)) { *disperity_out = last_result_of_disparity.clone() ; return true; } } // continue to give the filtered disparity (for the new or the last calculated) /* if output is ready from disparity calculation , it returns true */ //if ( localDisp.get_rectified_and_disparity(disp_temporary, disperity_struct) ) { /* calculate average depth for the ROI of the target */ Mat tmpma = last_result_of_disparity; if ( ! BgMask.empty() ) { filtered_disparity = Mat(); last_result_of_disparity.copyTo(filtered_disparity , BgMask); threshold (filtered_disparity , filtered_disparity , minDisparityToCut , 255,THRESH_TOZERO); } else /* no additional mask */ if ((*previousTarget).target_object_prop.relevant_disparity > -999) { threshold (last_result_of_disparity , filtered_disparity , (*previousTarget).target_object_prop.relevant_disparity * (1-allowed_disp_delta_between_cycles) , (*previousTarget).target_object_prop.relevant_disparity * (1+allowed_disp_delta_between_cycles), THRESH_TOZERO); //.15?? } else /* loose the far away objects (small disparities) */ threshold (last_result_of_disparity , filtered_disparity , minDisparityToCut , 255,THRESH_TOZERO); int an=1; //an=1->kernel of 3 Mat element = getStructuringElement(MORPH_RECT, Size(an*2+1, an*2+1), Point(an, an) ); medianBlur (filtered_disparity, filtered_disparity, an*3); erode (filtered_disparity , filtered_disparity, element); dilate (filtered_disparity, filtered_disparity, element); //max disperity into avg_disp var // minMaxLoc(filtered_disparity, 0, &max_disperity ); // convert_disperity_value_to_depth(max_disperity , *min_depth_of_ROI); // last_disparity_min_depth = *min_depth_of_ROI; Scalar mean; Scalar stddev; Rect tmp = boundingRect(filtered_disparity); Mat tmpMask = filtered_disparity; ///meanStdDev ( filtered_disparity, mean, stddev ); ///meanStdDev ( filtered_disparity(tmp), mean, stddev ); meanStdDev ( filtered_disparity, mean, stddev , tmpMask); //uchar mean_pxl = mean.val[0]; int mean_val = mean.val[0]; //uchar stddev_pxl = stddev.val[0]; int stddev_val = stddev.val[0]; int minDispToTake = mean_val - stddev_val * 1 ; if (minDispToTake > mean_val * (1-allowed_disp_delta_between_cycles/2.) ) minDispToTake = mean_val * (1-allowed_disp_delta_between_cycles/2.) ; //minimum for case of ~zero std ; // furthest object //int maxDispToTake = max_disperity ; // closest object convert_disperity_value_to_depth(mean_val , *min_depth_of_ROI); last_disparity_depth = *min_depth_of_ROI; /* filter far or close objects then the target itself (mean) */ threshold (filtered_disparity , filtered_disparity , minDispToTake , 255/*max_disperity*/,THRESH_TOZERO); /* set partial data for current target */ (*previousTarget).target_object_prop.relevant_disparity = mean_val; } *disperity_out = filtered_disparity.clone() ; return true; // TODO: set as SUCCESS system enum }
int main() { std::vector<ContourWithData> allContoursWithData; std::vector<ContourWithData> validContoursWithData; cv::Mat matClassificationFloats; cv::FileStorage fsClassifications("classifications.xml", cv::FileStorage::READ); if (fsClassifications.isOpened() == false) { std::cout << "error, unable to open training classifications file, exiting program\n\n"; return(0); } fsClassifications["classifications"] >> matClassificationFloats; fsClassifications.release(); cv::Mat matTrainingImages; cv::FileStorage fsTrainingImages("images.xml", cv::FileStorage::READ); if (fsTrainingImages.isOpened() == false) { std::cout << "error, unable to open training images file, exiting program\n\n"; return(0); } fsTrainingImages["images"] >> matTrainingImages; fsTrainingImages.release(); cv::Ptr<cv::ml::KNearest> kNearest = cv::ml::KNearest::create(); cv::Ptr<cv::ml::TrainData> trainingData = cv::ml::TrainData::create(matTrainingImages, cv::ml::SampleTypes::ROW_SAMPLE, matClassificationFloats); kNearest->setIsClassifier(true); kNearest->setAlgorithmType(cv::ml::KNearest::Types::BRUTE_FORCE); kNearest->setDefaultK(101); cv::Mat matResults(0, 0, CV_32F); kNearest->train(trainingData); cv::Mat matTestingNumbers = cv::imread("test_numbers.png"); if (matTestingNumbers.empty()) { std::cout << "error: image not read from file\n\n"; return(0); } cv::Mat matGrayscale; cv::Mat matBlurred; cv::Mat matThresh; cv::Mat matThreshCopy; cv::cvtColor(matTestingNumbers, matGrayscale, CV_BGR2GRAY); threshold(matGrayscale, matThresh, 10, 255, CV_THRESH_BINARY_INV); matThreshCopy = matThresh.clone(); std::vector<std::vector<cv::Point> > ptContours; std::vector<cv::Vec4i> v4iHierarchy; cv::findContours(matThreshCopy, ptContours, v4iHierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_TC89_KCOS); for (int i = 0; i < ptContours.size(); i++) { ContourWithData contourWithData; contourWithData.ptContour = ptContours[i]; contourWithData.boundingRect = cv::boundingRect(contourWithData.ptContour); contourWithData.fltArea = cv::contourArea(contourWithData.ptContour); allContoursWithData.push_back(contourWithData); } for (int i = 0; i < allContoursWithData.size(); i++) { if (allContoursWithData[i].checkIfContourIsValid()) { validContoursWithData.push_back(allContoursWithData[i]); } } std::sort(validContoursWithData.begin(), validContoursWithData.end(), ContourWithData::sortByBoundingRectXPosition); std::string strFinalString; for (int i = 0; i < validContoursWithData.size(); i++) { cv::rectangle(matTestingNumbers, validContoursWithData[i].boundingRect, cv::Scalar(0, 255, 0), 2); cv::Mat matROI = matThresh(validContoursWithData[i].boundingRect); cv::Mat matROIResized; cv::resize(matROI, matROIResized, cv::Size(RESIZED_IMAGE_WIDTH, RESIZED_IMAGE_HEIGHT)); cv::Mat matROIFloat; matROIResized.convertTo(matROIFloat, CV_32FC1); float fltCurrentChar = kNearest->findNearest(matROIFloat.reshape(1,1), kNearest->getDefaultK(), matResults); strFinalString = strFinalString + char(int(fltCurrentChar)); } cv::Mat string_box(100,500,CV_8UC3, cv::Scalar::all(0)); int baseLine = 0; cv::Size string_size = cv::getTextSize(strFinalString, CV_FONT_HERSHEY_DUPLEX, 1, 2, &baseLine); baseLine += 2; cv::Point textOrg((string_box.cols - string_size.width) / 2, (string_box.rows + string_size.height) / 2); cv::putText(string_box, strFinalString, textOrg, CV_FONT_HERSHEY_DUPLEX, 1, cv::Scalar::all(255), 2, 8); cv::imshow("result", string_box); cv::imshow("matTestingNumbers", matTestingNumbers); cv::waitKey(0); return(0); }
void Vehicle::trackVehicles() { Blob _blob; vector <Blob> _Blob; //Mat object to store the diffrence of the frame Mat diffFrame; Mat threshedImg; //Mat object to grab the frames from the video Mat videoFrame2; //to store the copies of the frame Mat videoFrame2Copy, videoFrame1Copy,threshedImgCopy; _video >> videoFrame2; //resize the video to 640x360; resize(videoFrame2, videoFrame2, Size(FRAME_WIDTH, FRAME_HEIGHT), 0, 0, INTER_CUBIC); //copy the frame for other use videoFrame2Copy = videoFrame2.clone(); videoFrame1Copy = _firstFrame.clone(); cvtColor(videoFrame1Copy, videoFrame1Copy, CV_BGR2GRAY); cvtColor(videoFrame2Copy, videoFrame2Copy, CV_BGR2GRAY); GaussianBlur(videoFrame1Copy, videoFrame1Copy, Size(5, 5), 0); GaussianBlur(videoFrame2Copy, videoFrame2Copy, Size(5, 5), 0); absdiff(videoFrame2Copy, videoFrame1Copy, diffFrame); //calcute the FPS //putText(_firstFrame, _FPS, Point(600, 100), CV_FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 0, 255), 8); //display the frames //imshow("Video", _firstFrame); threshold(diffFrame, threshedImg, 30, 255.0, CV_THRESH_BINARY); //dilate and erode for better results dilate(threshedImg, threshedImg, getStructuringElement(CV_SHAPE_RECT, Size(5, 5))); dilate(threshedImg, threshedImg, getStructuringElement(CV_SHAPE_RECT, Size(5, 5))); erode(threshedImg, threshedImg, getStructuringElement(CV_SHAPE_RECT, Size(5, 5))); //clone the threshed image because finding contors will change the image threshedImgCopy = threshedImg.clone(); //find the contours findContours(threshedImgCopy, _contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE); Mat contoursImg(threshedImgCopy.size(), CV_8UC3, Scalar(0,0,0)); drawContours(contoursImg, _contours, -1, Scalar(255, 255, 255), -1); vector < vector<Point> > _convexHulls(_contours.size()); ////extract the convex hulls out of the contours for (int j=0; j < _contours.size(); j++) { convexHull(_contours[j], _convexHulls[j]); } convexImg=Mat(_firstFrame.size(), CV_8UC3, Scalar(0, 0, 0)); //extract the cars out of the video _extractCars(_convexHulls, _blob,_Blob); imshow("Contours", contoursImg); imshow("thresh", threshedImg); //_Blob.clear(); //_existingBlob.clear(); _firstFrame = videoFrame2.clone(); isFirstFrame = false; frameCount++; }
//! 字符分割与排序 int CCharsSegment::charsSegment(Mat input, vector<Mat>& resultVec) { if( !input.data ) { return -1; } //判断车牌颜色以此确认threshold方法 int plateType = getPlateType(input); cvtColor(input, input, CV_RGB2GRAY); //Threshold input image Mat img_threshold; if (1 == plateType) { threshold(input, img_threshold, 10, 255, CV_THRESH_OTSU+CV_THRESH_BINARY); } else { threshold(input, img_threshold, 10, 255, CV_THRESH_OTSU+CV_THRESH_BINARY_INV); } //去除车牌上方的柳钉以及下方的横线等干扰 clearLiuDing(img_threshold); Mat img_contours; img_threshold.copyTo(img_contours); vector< vector< Point> > contours; findContours(img_contours, 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<Rect> vecRect; //Remove patch that are no inside limits of aspect ratio and area. //将不符合特定尺寸的图块排除出去 while (itc != contours.end()) { Rect mr = boundingRect(Mat(*itc)); Mat auxRoi(img_threshold, mr); if (verifySizes(auxRoi)) { vecRect.push_back(mr); } ++itc; } if (vecRect.size() == 0) return -1; vector<Rect> sortedRect; //对符合尺寸的图块按照从左到右进行排序 SortRect(vecRect, sortedRect); int specIndex = 0; //获得指示城市的特定Rect,如苏A的"A" specIndex = GetSpecificRect(sortedRect); //根据特定Rect向左反推出中文字符 //这样做的主要原因是根据findContours方法很难捕捉到中文字符的准确Rect,因此仅能 //退过特定算法来指定 Rect chineseRect; if (specIndex < sortedRect.size()) chineseRect = GetChineseRect(sortedRect[specIndex]); else return -1; //新建一个全新的排序Rect //将中文字符Rect第一个加进来,因为它肯定是最左边的 //其余的Rect只按照顺序去6个,车牌只可能是7个字符!这样可以避免阴影导致的“1”字符 vector<Rect> newSortedRect; newSortedRect.push_back(chineseRect); RebuildRect(sortedRect, newSortedRect, specIndex); if (newSortedRect.size() == 0) return -1; for (int i = 0; i < newSortedRect.size(); i++) { Rect mr = newSortedRect[i]; Mat auxRoi(img_threshold, mr); if (1) { auxRoi = preprocessChar(auxRoi); resultVec.push_back(auxRoi); } } return 0; }
bool HumanBodyLaser::init(string fn) { fstream fin(fn.c_str(), ios::in); if(fin.is_open() == false) { cout << "failed to open " << fn << endl; return false; } string suffix = fn.substr(fn.rfind('.'), fn.length() - fn.rfind('.')); if(suffix != ".info") { cout << "wrong format" << endl; return false; } //获得输入文件夹 string indir = fn.substr(0, fn.find("stereos")-1); string scenename = indir.substr(indir.rfind('/')+1); if(scenename == "input") scenename = ""; fin >> name; fin >> frame; //which frame; fin >> camL; fin >> camR; fin >> stPointL.x >> stPointL.y ; fin >> stPointR.x >> stPointR.y ; fin >> imSize.width >> imSize.height; fin >> maxDisp >> minDisp; QMatrix = Mat::zeros(4,4,CV_64FC1); for(int i = 0; i < 4; i++) { for(int j = 0; j < 4; j++) fin >> QMatrix.at<double>(i,j) ; } #ifdef _DEBUG if(scenename != "") outdir = "../output/" + scenename; else outdir = "../output"; _mkdir(outdir.c_str()); outdir = outdir + "/" + name + "_" + camL + camR; _mkdir(outdir.c_str()); cout << "outdir: " << outdir << endl; cout << "stPointL: " << stPointL << endl; cout << "stPointR: " << stPointR << endl; cout << "imSize: " << imSize << endl; cout << "disp: " << minDisp << "~" << maxDisp << endl; cout << "QMatrix: " << QMatrix << endl; #endif //naming rules are known string imLFn, imRFn; string mskLFn, mskRFn; char cwd[1024]; getcwd(cwd,1024) ; cout << cwd << endl; imLFn = indir +"/images/image" + frame + "_" + camL + ".jpg"; imRFn = indir +"/images/image" + frame + "_" + camR + ".jpg"; mskLFn = indir + "/images/mask" + frame + "_" + camL + ".jpg"; mskRFn = indir + "/images/mask" + frame + "_" + camR + ".jpg"; //original images Mat fullImL, fullImR; Mat fullMskL, fullMskR; if( !readInImage(imLFn, CV_LOAD_IMAGE_UNCHANGED, fullImL) || !readInImage(imRFn, CV_LOAD_IMAGE_UNCHANGED, fullImR) ) { cout << "failed to initialize HumanBodyLaser" << endl; return false; } //tailoring imL = fullImL(Rect(stPointL, imSize)).clone(); imR = fullImR(Rect(stPointR, imSize)).clone(); if( !readInImage(mskLFn, CV_LOAD_IMAGE_GRAYSCALE, fullMskL) || !readInImage(mskRFn, CV_LOAD_IMAGE_GRAYSCALE, fullMskR) ) { cout << "no mask here" << endl; mskL = Mat(imSize, CV_8UC1, cv::Scalar(255)); mskR = Mat(imSize, CV_8UC1, cv::Scalar(255)); } else { //binarization threshold(fullMskL, fullMskL, 75, 255, THRESH_BINARY); threshold(fullMskR, fullMskR, 75, 255, THRESH_BINARY); //tailoring mskL = fullMskL(Rect(stPointL, imSize)).clone(); mskR = fullMskR(Rect(stPointR, imSize)).clone(); } #ifdef _DEBUG imwrite(outdir + "/cut_imL.jpg", imL); imwrite(outdir + "/cut_imR.jpg", imR); imwrite(outdir + "/cut_mskL.jpg", mskL); imwrite(outdir + "/cut_mskR.jpg", mskR); #endif // normalizing image format and values cvtColor( imL, imL, CV_BGR2RGB ); cvtColor( imR, imR, CV_BGR2RGB ); imL.convertTo( imL, CV_64F, 1 / 255.0f ); imR.convertTo( imR, CV_64F, 1 / 255.0f ); fin.close(); cout << "read in " << fn << " done." << endl; cout << "Human Body Laser initlization done." << endl; return true; }
void ThresholdWindow::on_invertedCheckBox_toggled(bool) { threshold(); }
static void process_file(FILE *fin, FILE *fout, char *infile, char *outfile) { int r; greymap_t *gm; potrace_bitmap_t *bm; void *sm; int x, y; int count; for (count=0; ; count++) { r = gm_read(fin, &gm); switch (r) { case -1: /* system error */ fprintf(stderr, "mkbitmap: %s: %s\n", infile, strerror(errno)); exit(2); case -2: /* corrupt file format */ fprintf(stderr, "mkbitmap: %s: file format error: %s\n", infile, gm_read_error); exit(2); case -3: /* empty file */ if (count>0) { /* end of file */ return; } fprintf(stderr, "mkbitmap: %s: empty file\n", infile); exit(2); case -4: /* wrong magic */ if (count>0) { fprintf(stderr, "mkbitmap: %s: warning: junk at end of file\n", infile); return; } fprintf(stderr, "mkbitmap: %s: file format not recognized\n", infile); fprintf(stderr, "Possible input file formats are: pnm (pbm, pgm, ppm), bmp.\n"); exit(2); case 1: /* unexpected end of file */ fprintf(stderr, "mkbitmap: %s: warning: premature end of file\n", infile); break; } if (info.invert) { for (y=0; y<gm->h; y++) { for (x=0; x<gm->w; x++) { GM_UPUT(gm, x, y, 255-GM_UGET(gm, x, y)); } } } if (info.highpass) { r = highpass(gm, info.lambda); if (r) { fprintf(stderr, "mkbitmap: %s: %s\n", infile, strerror(errno)); exit(2); } } if (info.lowpass) { lowpass(gm, info.lambda1); } if (info.scale == 1 && info.bilevel) { /* no interpolation necessary */ sm = threshold(gm, info.level); gm_free(gm); } else if (info.scale == 1) { sm = gm; } else if (info.linear) { /* linear interpolation */ sm = interpolate_linear(gm, info.scale, info.bilevel, info.level); gm_free(gm); } else { /* cubic interpolation */ sm = interpolate_cubic(gm, info.scale, info.bilevel, info.level); gm_free(gm); } if (!sm) { fprintf(stderr, "mkbitmap: %s: %s\n", infile, strerror(errno)); exit(2); } if (info.bilevel) { bm = (potrace_bitmap_t *)sm; bm_writepbm(fout, bm); bm_free(bm); } else { gm = (greymap_t *)sm; gm_writepgm(fout, gm, NULL, 1, GM_MODE_POSITIVE, 1.0); gm_free(gm); } } }
void ThresholdWindow::on_toZeroRadioButton_toggled(bool checked) { if (checked) threshold(); }
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 CCharsSegment::charsSegment(Mat input, vector<Mat>& resultVec, int index) { if (!input.data) return 0x01; int w = input.cols; int h = input.rows; Mat tmpMat = input(Rect_<double>(w * 0.1, h * 0.1, w * 0.8, h * 0.8)); // 判断车牌颜色以此确认threshold方法 Color plateType = getPlateType(tmpMat, true); Mat input_grey; cvtColor(input, input_grey, CV_BGR2GRAY); Mat img_threshold; // 二值化 // 根据车牌的不同颜色使用不同的阈值判断方法 // TODO:使用MSER来提取这些轮廓 if (BLUE == plateType) { // cout << "BLUE" << endl; img_threshold = input_grey.clone(); int w = input_grey.cols; int h = input_grey.rows; Mat tmp = input_grey(Rect_<double>(w * 0.1, h * 0.1, w * 0.8, h * 0.8)); int threadHoldV = ThresholdOtsu(tmp); threshold(input_grey, img_threshold, threadHoldV, 255, CV_THRESH_BINARY); } else if (YELLOW == plateType) { // cout << "YELLOW" << endl; img_threshold = input_grey.clone(); int w = input_grey.cols; int h = input_grey.rows; Mat tmp = input_grey(Rect_<double>(w * 0.1, h * 0.1, w * 0.8, h * 0.8)); int threadHoldV = ThresholdOtsu(tmp); // utils::imwrite("resources/image/tmp/inputgray2.jpg", input_grey); threshold(input_grey, img_threshold, threadHoldV, 255, CV_THRESH_BINARY_INV); } else if (WHITE == plateType) { // cout << "WHITE" << endl; threshold(input_grey, img_threshold, 10, 255, CV_THRESH_OTSU + CV_THRESH_BINARY_INV); } else { // cout << "UNKNOWN" << endl; threshold(input_grey, img_threshold, 10, 255, CV_THRESH_OTSU + CV_THRESH_BINARY); } if (0) { imshow("threshold", img_threshold); waitKey(0); destroyWindow("threshold"); } if (m_debug) { stringstream ss(stringstream::in | stringstream::out); ss << "resources/image/tmp/debug_char_threshold_" << index << ".jpg"; utils::imwrite(ss.str(), img_threshold); } // 去除车牌上方的柳钉以及下方的横线等干扰 // 并且也判断了是否是车牌 // 并且在此对字符的跳变次数以及字符颜色所占的比重做了是否是车牌的判别条件 // 如果不是车牌,返回ErrorCode=0x02 if (!clearLiuDing(img_threshold)) return 0x02; if (m_debug) { stringstream ss(stringstream::in | stringstream::out); ss << "resources/image/tmp/debug_char_clearLiuDing_" << index << ".jpg"; utils::imwrite(ss.str(), img_threshold); } // 在二值化图像中提取轮廓 Mat img_contours; img_threshold.copyTo(img_contours); vector<vector<Point> > contours; findContours(img_contours, contours, // a vector of contours CV_RETR_EXTERNAL, // retrieve the external contours CV_CHAIN_APPROX_NONE); // all pixels of each contours vector<vector<Point> >::iterator itc = contours.begin(); vector<Rect> vecRect; // 将不符合特定尺寸的字符块排除出去 while (itc != contours.end()) { Rect mr = boundingRect(Mat(*itc)); Mat auxRoi(img_threshold, mr); if (verifyCharSizes(auxRoi)) vecRect.push_back(mr); ++itc; } // 如果找不到任何字符块,则返回ErrorCode=0x03 if (vecRect.size() == 0) return 0x03; // 对符合尺寸的图块按照从左到右进行排序; // 直接使用stl的sort方法,更有效率 vector<Rect> sortedRect(vecRect); std::sort(sortedRect.begin(), sortedRect.end(),[](const Rect& r1, const Rect& r2) { return r1.x < r2.x; }); size_t specIndex = 0; // 获得特殊字符对应的Rectt,如苏A的"A" specIndex = GetSpecificRect(sortedRect); if (m_debug) { if (specIndex < sortedRect.size()) { Mat specMat(img_threshold, sortedRect[specIndex]); stringstream ss(stringstream::in | stringstream::out); ss << "resources/image/tmp/debug_specMat_" << index << ".jpg"; utils::imwrite(ss.str(), specMat); } } // 根据特定Rect向左反推出中文字符 // 这样做的主要原因是根据findContours方法很难捕捉到中文字符的准确Rect,因此仅能 // 退过特定算法来指定 Rect chineseRect; if (specIndex < sortedRect.size()) chineseRect = GetChineseRect(sortedRect[specIndex]); else return 0x04; if (m_debug) { Mat chineseMat(img_threshold, chineseRect); stringstream ss(stringstream::in | stringstream::out); ss << "resources/image/tmp/debug_chineseMat_" << index << ".jpg"; utils::imwrite(ss.str(), chineseMat); } //新建一个全新的排序Rect //将中文字符Rect第一个加进来,因为它肯定是最左边的 //其余的Rect只按照顺序去6个,车牌只可能是7个字符!这样可以避免阴影导致的“1”字符 vector<Rect> newSortedRect; newSortedRect.push_back(chineseRect); RebuildRect(sortedRect, newSortedRect, specIndex); if (newSortedRect.size() == 0) return 0x05; // 开始截取每个字符 for (size_t i = 0; i < newSortedRect.size(); i++) { Rect mr = newSortedRect[i]; //Mat auxRoi(img_threshold, mr); // 使用灰度图来截取图块,然后依次对每个图块进行大津阈值来二值化 Mat auxRoi(input_grey, mr); Mat newRoi; if (BLUE == plateType) { /* img_threshold = auxRoi.clone(); int w = input_grey.cols; int h = input_grey.rows; Mat tmp = input_grey(Rect_<double>(w * 0.1, h * 0.1, w * 0.8, h * 0.8)); int threadHoldV = ThresholdOtsu(tmp);*/ threshold(auxRoi, newRoi, 5, 255, CV_THRESH_BINARY + CV_THRESH_OTSU); } else if (YELLOW == plateType) { threshold(auxRoi, newRoi, 5, 255, CV_THRESH_BINARY_INV + CV_THRESH_OTSU); } else if (WHITE == plateType) { threshold(auxRoi, newRoi, 5, 255, CV_THRESH_OTSU + CV_THRESH_BINARY_INV); } else { threshold(auxRoi, newRoi, 5, 255, CV_THRESH_OTSU + CV_THRESH_BINARY); } // 归一化大小 newRoi = preprocessChar(newRoi); // 假设我们要重新训练ANN模型,在这里需要把训练样板输出 if (i == 0) { stringstream ss(stringstream::in | stringstream::out); ss << "resources/image/tmp/debug_char_auxRoi_" << index << "_" << (i) << ".jpg"; utils::imwrite(ss.str(), newRoi); } // 每个字符图块输入到下面的步骤进行处理 resultVec.push_back(newRoi); } return 0; }
/* compute the average of the affine transformations in each node in the hierarchy at level l returns a vector of the top local maxima that were localized with their corresponding node in the hierarhcy */ vector<LocalMaximum> CoarseToFineAffineSearch::computeBestMatches(vector<LocalMaximum> subsets, int l, vector<vector<PQ> > pqV, int& numNCC){ int N = params.N; int L = params.affineLevels; int numElems = (1 << L-l); int numSamples = ceil(sqrt(numElems*1.0f)); int *pSet, *qSet; int pSetSize = numElems; pSet = new int[pSetSize]; qSet = new int[pSetSize]; int incr = numElems/((numSamples>1)?numSamples:1); int kk = 0; for(int k = 0; k < numElems; k++){ pSet[kk] = k; qSet[kk++] = k; } int cType = CV_32FC3; Mat initialMask(region.size(),cType); for(int i =0; i < initialMask.rows; i++){ for(int j =0; j < initialMask.cols; j++){ for( int cn = 0; cn < initialMask.channels(); cn++ ) initialMask.at<Vec3f>(i,j)[cn] = 1; } } vector<LocalMaximum> topLocalMaxima; timer affine_timer; double tTime =0; double minScore = 1000000; maxScore = secondMaxScore =0; long affine_time = 0; int itrIndex = -1; int i = 0; timer subset_timer; subset_timer.tic(); int numThreads = omp_get_max_threads(); omp_set_dynamic(1); int* localNCCs = new int[numThreads]; vector<LocalMaximum>* topLocalMaximaArr = new vector<LocalMaximum>[numThreads]; for(int i =0 ;i < numThreads; i++){ localNCCs[i] = 0; topLocalMaximaArr[i] = vector<LocalMaximum>(); } #ifdef USE_OMP #pragma omp parallel shared(topLocalMaximaArr, subsets, pSet, qSet, initialMask, localNCCs) { #pragma omp for #endif for(i = 0; i < subsets.size(); i++){ // loop over the affine parameters subsets itrIndex++; int pIndex = subsets[i].p; int qIndex = subsets[i].q; int stP = (1 << L-l)*(pIndex-1) + 1; int enP = (1 << L-l)*(pIndex) + 1; int stQ= (1 << L-l)*(qIndex-1) + 1; int enQ= (1 << L-l)*(qIndex) + 1; Mat *transformsB, *transformsMask; transformsB = new Mat[pSetSize]; transformsMask = new Mat[pSetSize]; double s, lambda, theta, h; int minWidth, minHeight; minWidth = minHeight = 1000000; int maxWidth, maxHeight; maxWidth = maxHeight = 0; for(int k = 0; k < pSetSize; k++){ /*apply each affine transformation on both the region and a mask*/ s = pqV[pIndex][pSet[k]].p.s; lambda = pqV[pIndex][pSet[k]].p.lambda; theta = pqV[pIndex][pSet[k]].q.theta; h = pqV[pIndex][pSet[k]].q.h; Mat bTmp = AffineTransformGenerator::generateTransform(region, s, lambda, theta, h); Mat maskTemp = AffineTransformGenerator::generateTransform(initialMask, s, lambda, theta, h); transformsB[k] = bTmp; transformsMask[k] = maskTemp; if(bTmp.rows < minHeight) minHeight = bTmp.rows; if(bTmp.cols < minWidth) minWidth = bTmp.cols; } Mat Bi = Mat::zeros(minHeight, minWidth, cType); Mat maskT = Mat::zeros(minHeight, minWidth, cType); // compute the average of all transformed patches intersected together for(int k = 0 ; k < pSetSize; k++){ Mat currR = transformsB[k]; Mat currM = transformsMask[k]; Mat imRoi = currR(Rect(currR.cols/2-minWidth/2, currR.rows/2-minHeight/2, minWidth,minHeight)); Mat maskRoi = currM(Rect(currM.cols/2-minWidth/2, currM.rows/2-minHeight/2, minWidth,minHeight)); transformsB[k] = imRoi.clone(); transformsMask[k] = maskRoi.clone(); Bi = Bi + transformsB[k]; maskT = maskT + transformsMask[k]; } Bi /= (pSetSize*1.0); maskT /= (pSetSize*1.0); Mat tmp (maskT.size(), CV_8UC3); threshold(maskT, maskT, 0.999,1.,THRESH_BINARY); maskT.convertTo(tmp,CV_8UC3); Mat BiU; Bi.copyTo(BiU, tmp); Mat mask32FC3(tmp.size(), CV_32FC3); tmp.convertTo(mask32FC3, CV_32FC3); Mat imgSqr; // compute the square of the region (needed for the NCC computation) subsets[i].region.convertTo(imgSqr,CV_32FC3); imgSqr = imgSqr.mul(imgSqr); bool debug = false; #ifdef DEBUG debug = true; #else debug = false; #endif int lNCC = 0; Mat response; affine_timer.tic(); response = TemplateMatcher::computeResponseMap(subsets[i].region, BiU, mask32FC3, mask32FC3, imgSqr, debug, lNCC); // perform NCC double affineInSub = affine_timer.toc(); tTime += affineInSub; LocalMaximum* localMaxima = new LocalMaximum[params.numPatchLocalMaxima]; if(response.cols != 0){ // find top n local maxima Mat tmp = img.clone(); int returned = 0; long elapsedTime = 0; localMaxima = TemplateMatcher::findTopNLocalMaxima(response,params.numPatchLocalMaxima,1,returned,elapsedTime ); int j = 0; Point tmpLoc = localMaxima[0].loc; for(j = 0; j < returned; j++){ localMaxima[j].p = pIndex; localMaxima[j].q = qIndex; Point currTmpLoc = localMaxima[j].loc; localMaxima[j].regionAnchor = localMaxima[j].loc; #ifndef SEARCH_ALL_IMG localMaxima[j].regionAnchor.x += subsets[i].regionAnchor.x; localMaxima[j].regionAnchor.y += subsets[i].regionAnchor.y; localMaxima[j].loc.x += (BiU.cols/2 + subsets[i].regionAnchor.x); localMaxima[j].loc.y += (BiU.rows/2 + subsets[i].regionAnchor.y); localMaxima[j].patch = BiU.clone(); #endif topLocalMaximaArr[omp_get_thread_num()].push_back(localMaxima[j]); } #pragma omp critical (REG2) { localNCCs[omp_get_thread_num()]++; if(localMaxima[0].val > maxScore){ maxScore = localMaxima[0].val; topLocalMaximum = localMaxima[0]; if(returned > 1){ secondMaxScore = localMaxima[1].val; secondMaxLoc = localMaxima[1].regionAnchor; }else{ secondMaxScore = -1; secondMaxLoc = Point(-1,-1); } } } } delete[] localMaxima; localMaxima=0; delete[] transformsB; transformsB=0; delete[] transformsMask; transformsMask=0; } #ifdef USE_OMP } #endif for(int i = 0; i < numThreads; i++){ numNCC += localNCCs[i]; for(int j = 0; j < topLocalMaximaArr[i].size();j++) topLocalMaxima.push_back(topLocalMaximaArr[i][j]); } if(topLocalMaxima.size() > 0){ sort(topLocalMaxima.begin(), topLocalMaxima.end(), LocalMaximumComparator()); topLocalMaximum = topLocalMaxima[0]; }else{ topLocalMaximum.loc = Point(-1,-1); topLocalMaximum.val = -1; } return topLocalMaxima; }
void Escena::procesar( Mat &frame ) { Mat matImagenActual = frame.clone(); // PROCESAMIENTO // Declaramos un vector para guardar las caras detectadas std::vector<Rect> vectorCaras; vectorCaras.clear(); // Detectamos las caras en toda la extStream.reimagen completa clasificadorCara.detectMultiScale( matImagenActual, vectorCaras, 1.1, 2, 0|CASCADE_SCALE_IMAGE, Size( 100,100 ) ); for ( unsigned int i = 0; i < vectorCaras.size(); i++ ) { // Dibujamos el rectangulo de la cara //rectangle( matImagenActual, vectorCaras.at(i), Scalar( 0, 255, 0 ), linesWidth ); // Declaramos y dibujamos un contenedor para el ojo izquierdo Rect rectParaOjosIzquierdos( vectorCaras.at(i).x + vectorCaras.at(i).width/2, vectorCaras.at(i).y + vectorCaras.at(i).height*MARGEN_VERTICAL_CONTENEDOR_OJOS/100, vectorCaras.at(i).width*ANCHO_CONTENEDOR_OJO/100, vectorCaras.at(i).height*ALTO_CONTENEDOR_OJO/100); // rectangle( matImagenActual, rectParaOjosIzquierdos, Scalar( 0, 0, 200 ), linesWidth ); // Declaramos y dibujamos un contenedor para el ojo derecho Rect rectParaOjosDerechos( vectorCaras.at(i).x + vectorCaras.at(i).width*MARGEN_LATERAL_CONTENEDOR_OJOS/100, vectorCaras.at(i).y + vectorCaras.at(i).height*MARGEN_VERTICAL_CONTENEDOR_OJOS/100, vectorCaras.at(i).width*ANCHO_CONTENEDOR_OJO/100, vectorCaras.at(i).height*ALTO_CONTENEDOR_OJO/100); // rectangle( matImagenActual, rectParaOjosDerechos, Scalar( 0, 0, 200 ), linesWidth ); // Declaramos un vector para guardar los ojos izquierdos detectados std::vector<Rect> vectorOjosIzquierdos; vectorOjosIzquierdos.clear(); // Detectamos ojos izquierdos en el mat designado por el rectOjosIzquierdos Mat matParaOjosIzquierdos( matImagenActual, rectParaOjosIzquierdos ); clasificadorOjoIzquierdo.detectMultiScale( matParaOjosIzquierdos, vectorOjosIzquierdos, 1.1, 2, 0|CASCADE_SCALE_IMAGE, Size( 30, 30 ) ); Rect ojoIzquierdoLocalAlContenedor; if ( vectorOjosIzquierdos.size() > 0 ) { // Descartamos los ojos izquierdos que no sean el mas grande ojoIzquierdoLocalAlContenedor = rectanguloMasGrande( vectorOjosIzquierdos ); Rect rectanguloOjoIzquierdoDesplazado( rectParaOjosIzquierdos.x + ojoIzquierdoLocalAlContenedor.x, rectParaOjosIzquierdos.y + ojoIzquierdoLocalAlContenedor.y, ojoIzquierdoLocalAlContenedor.width, ojoIzquierdoLocalAlContenedor.height ); rectangle( matImagenActual, rectanguloOjoIzquierdoDesplazado, Scalar( 255, 255, 255 ), linesWidth ); } // Declaramos un vector para guardar los ojos derechos detectados std::vector<Rect> vectorOjosDerechos; vectorOjosDerechos.clear(); // Detectamos ojos derechos en el mat designado por el rectOjosDerechos Mat matParaOjosDerechos( matImagenActual, rectParaOjosDerechos ); clasificadorOjoDerecho.detectMultiScale( matParaOjosDerechos, vectorOjosDerechos, 1.1, 2, 0|CASCADE_SCALE_IMAGE, Size( 30, 30 ) ); Rect ojoDerechoLocalAlContenedor; if ( vectorOjosDerechos.size() > 0 ) { // Descartamos los ojos derechos que no sean el mas grande ojoDerechoLocalAlContenedor = rectanguloMasGrande( vectorOjosDerechos ); Rect rectanguloOjoDerechoDesplazado( rectParaOjosDerechos.x + ojoDerechoLocalAlContenedor.x, rectParaOjosDerechos.y + ojoDerechoLocalAlContenedor.y, ojoDerechoLocalAlContenedor.width, ojoDerechoLocalAlContenedor.height ); rectangle( matImagenActual, rectanguloOjoDerechoDesplazado, Scalar( 255, 255, 255 ), linesWidth ); } //Creo la matriz en la que voy a meter los posibles circulos //metodo para deteccion de parpadeo int threshold_value = 0; int threshold_type = 3;; int const max_value = 255; int const max_type = 4; int const max_BINARY_value = 255; //Mat src, src_gray, dst; std::vector<Vec3f> storageCir; Mat img; int dp = 2; float minDist = 300.0 ; int param1 = 32 ; int param2 = 60; int minRadius = 10; int maxRadius = 22; //GaussianBlur( img, img, Size(7,7), 2, 2 ); cvtColor( matParaOjosDerechos, img, CV_BGR2GRAY ); threshold( img, img, threshold_value, max_BINARY_value,threshold_type ); HoughCircles(img, storageCir, CV_HOUGH_GRADIENT , dp, minDist, param1, param2, minRadius, maxRadius); if (storageCir.empty()) { //qDebug()<<"ojo cerrado"; //storageCir.clear(); cant++; } else{ cant=0; //qDebug()<<"ojo abierto"; //storageCir.clear(); } storageCir.clear(); if (cant==3){ qDebug()<<"parpadeo"; cant=0; } if ( vectorOjosIzquierdos.size() > 0 && vectorOjosDerechos.size() > 0 ) { // A estos puntos les llamo centros globales, pero son los centros desplazados (1/4 y 3/4) Point centroOjoIzquierdoGlobal( rectParaOjosIzquierdos.x + ojoIzquierdoLocalAlContenedor.x + ojoIzquierdoLocalAlContenedor.width*3/4, rectParaOjosIzquierdos.y + ojoIzquierdoLocalAlContenedor.y + ojoIzquierdoLocalAlContenedor.height/2 ); Point centroOjoDerechoGlobal( rectParaOjosDerechos.x + ojoDerechoLocalAlContenedor.x + ojoDerechoLocalAlContenedor.width*1/4, rectParaOjosDerechos.y + ojoDerechoLocalAlContenedor.y + ojoDerechoLocalAlContenedor.height/2 ); // qDebug()<<cv::Point ('centroOjoDerechoGlobal'); //QDebug(centroOjoDerechoGlobal); //QDebug(centroOjoIzquierdoGlobal); line( matImagenActual, centroOjoIzquierdoGlobal, centroOjoDerechoGlobal, Scalar( 100, 50, 255 ), linesWidth ); float anguloEntreOjos = anguloEntre ( centroOjoDerechoGlobal, centroOjoIzquierdoGlobal ); float largoLineaOjoBoca = vectorCaras.at(i).height/9*6; float baseTrianguloOjoBoca = sin( anguloEntreOjos ) * largoLineaOjoBoca; if ( centroOjoDerechoGlobal.y < centroOjoIzquierdoGlobal.y ) baseTrianguloOjoBoca = -baseTrianguloOjoBoca; float alturaTrianguloOjoBoca = cos( anguloEntreOjos ) * largoLineaOjoBoca; Point finLineaOjoIzquierdo( centroOjoIzquierdoGlobal.x + baseTrianguloOjoBoca, centroOjoIzquierdoGlobal.y + alturaTrianguloOjoBoca ); Point finLineaOjoDerecho( centroOjoDerechoGlobal.x + baseTrianguloOjoBoca, centroOjoDerechoGlobal.y + alturaTrianguloOjoBoca ); line( matImagenActual, centroOjoIzquierdoGlobal, finLineaOjoIzquierdo, Scalar( 150, 20, 255 ), linesWidth ); line( matImagenActual, centroOjoDerechoGlobal, finLineaOjoDerecho, Scalar( 150, 20, 255 ), linesWidth ); // Saco dos promedios consecutivos Point bocaSupIzq( (finLineaOjoIzquierdo.x + centroOjoIzquierdoGlobal.x)/2, ( finLineaOjoIzquierdo.y + centroOjoIzquierdoGlobal.y)/2 ); Point bocaSupDer( (finLineaOjoDerecho.x + centroOjoDerechoGlobal.x)/2, ( finLineaOjoDerecho.y + centroOjoDerechoGlobal.y)/2 ); line( matImagenActual, bocaSupIzq, bocaSupDer, Scalar( 150, 20, 255 ), linesWidth ); line( matImagenActual, finLineaOjoIzquierdo, finLineaOjoDerecho, Scalar( 150, 20, 255 ), linesWidth ); //Point bocaInfIzq( (finLineaOjoIzquierdo.x + centroOjoIzquierdoGlobal.x)/2, (finLineaOjoIzquierdo.y + centroOjoIzquierdoGlobal.y)/2 ); //Point bocaInfDer( (finLineaOjoIzquierdo.x + centroOjoIzquierdoGlobal.x)/2, (finLineaOjoIzquierdo.y + centroOjoIzquierdoGlobal.y)/2 ); } // Estiramos un poco la cara y la dibujamos vectorCaras.at(i).height *= 1.2; rectangle( matImagenActual, vectorCaras.at(i), Scalar( 0, 0, 0 ), linesWidth ); } // FIN PROCESAMIENTO frame = matImagenActual.clone(); }
INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& printInfo) { WCHAR namePath[MAX_PATH]; GetModuleFileName(NULL, namePath, MAX_PATH); WCHAR *progName = PathFindFileName(namePath); po::options_description desc; desc.add_options() ("help,h", "Print help message and exit") ("version,V", "Print version and exit") ("debug,d", "Verbose/Debug output") ("warning,w", po::wvalue<std::wstring>(), "Warning threshold") ("critical,c", po::wvalue<std::wstring>(), "Critical threshold") ("unit,u", po::wvalue<std::wstring>(), "The unit to use for display (default MB)") ; po::basic_command_line_parser<WCHAR> parser(ac, av); try { po::store( parser .options(desc) .style( po::command_line_style::unix_style | po::command_line_style::allow_long_disguise) .run(), vm); vm.notify(); } catch (std::exception& e) { std::cout << e.what() << '\n' << desc << '\n'; return 3; } if (vm.count("help")) { std::wcout << progName << " Help\n\tVersion: " << VERSION << '\n'; wprintf( L"%s is a simple program to check a machines swap in percent.\n" L"You can use the following options to define its behaviour:\n\n", progName); std::cout << desc; wprintf( L"\nIt will then output a string looking something like this:\n\n" L"\tSWAP WARNING - 20%% free | swap=2000B;3000;500;0;10000\n\n" L"\"SWAP\" being the type of the check, \"WARNING\" the returned status\n" L"and \"20%%\" is the returned value.\n" L"The performance data is found behind the \"|\", in order:\n" L"returned value, warning threshold, critical threshold, minimal value and,\n" L"if applicable, the maximal value. Performance data will only be displayed when\n" L"you set at least one threshold\n\n" L"%s' exit codes denote the following:\n" L" 0\tOK,\n\tNo Thresholds were broken or the programs check part was not executed\n" L" 1\tWARNING,\n\tThe warning, but not the critical threshold was broken\n" L" 2\tCRITICAL,\n\tThe critical threshold was broken\n" L" 3\tUNKNOWN, \n\tThe program experienced an internal or input error\n\n" L"Threshold syntax:\n\n" L"-w THRESHOLD\n" L"warn if threshold is broken, which means VALUE > THRESHOLD\n" L"(unless stated differently)\n\n" L"-w !THRESHOLD\n" L"inverts threshold check, VALUE < THRESHOLD (analogous to above)\n\n" L"-w [THR1-THR2]\n" L"warn is VALUE is inside the range spanned by THR1 and THR2\n\n" L"-w ![THR1-THR2]\n" L"warn if VALUE is outside the range spanned by THR1 and THR2\n\n" L"-w THRESHOLD%%\n" L"if the plugin accepts percentage based thresholds those will be used.\n" L"Does nothing if the plugin does not accept percentages, or only uses\n" L"percentage thresholds. Ranges can be used with \"%%\", but both range values need\n" L"to end with a percentage sign.\n\n" L"All of these options work with the critical threshold \"-c\" too.\n" , progName); std::cout << '\n'; return 0; } if (vm.count("version")) std::wcout << L"Version: " << VERSION << '\n'; if (vm.count("warning")) { try { printInfo.warn = threshold(vm["warning"].as<std::wstring>()); } catch (std::invalid_argument& e) { std::cout << e.what() << '\n'; return 3; } printInfo.warn.legal = !printInfo.warn.legal; } if (vm.count("critical")) { try { printInfo.crit = threshold(vm["critical"].as<std::wstring>()); } catch (std::invalid_argument& e) { std::cout << e.what() << '\n'; return 3; } printInfo.crit.legal = !printInfo.crit.legal; } if (vm.count("debug")) debug = TRUE; if (vm.count("unit")) { try { printInfo.unit = parseBUnit(vm["unit"].as<std::wstring>()); } catch (std::invalid_argument& e) { std::cout << e.what() << '\n'; return 3; } } return -1; }