void TrackerMedianFlowImpl::check_NCC(const Mat& oldImage,const Mat& newImage,
        const std::vector<Point2f>& oldPoints,const std::vector<Point2f>& newPoints,std::vector<bool>& status){

    std::vector<float> NCC(oldPoints.size(),0.0);
    Size patch(30,30);
    Mat p1,p2;

	for (int i = 0; i < (int)oldPoints.size(); i++) {
		getRectSubPix( oldImage, patch, oldPoints[i],p1);
		getRectSubPix( newImage, patch, newPoints[i],p2);

        const int N=900;
        double s1=sum(p1)(0),s2=sum(p2)(0);
        double n1=norm(p1),n2=norm(p2);
        double prod=p1.dot(p2);
        double sq1=sqrt(n1*n1-s1*s1/N),sq2=sqrt(n2*n2-s2*s2/N);
        double ares=(sq2==0)?sq1/abs(sq1):(prod-s1*s2/N)/sq1/sq2;

		NCC[i] = (float)ares;
	}
	float median = getMedian(NCC);
	for(int i = 0; i < (int)oldPoints.size(); i++) {
        status[i] = status[i] && (NCC[i]>median);
	}
}
Пример #2
0
float CustomSIFT::getSubpixBlur(const Mat& img, Point2f off,KeyPoint p, double blur, map<double,Mat> &blurred)
{
    Mat use;
    if (blur < 1)
    {
        use=img;
    }
    else 
    {
        if (blurred.find(blur) == blurred.end())
        {
            Mat b;
            int size = (int)std::ceil(2*blur);
            size += size%2==0?1:0;
            GaussianBlur(img,b,Size(size,size),blur,blur);
            blurred[blur]=b;
        }
        use = blurred[blur];
    }
    Mat patch;
    Point2f pt (off.x+p.pt.x, off.y+p.pt.y);
    getRectSubPix(use, cv::Size(1,1), pt, patch);
    assert(patch.type() == CV_32F);
    float ret = patch.at<float>(0,0);
    assert(ret==ret);
    return ret;
}
Пример #3
0
//TODO this should blur the image before sampling. Maybe.
Vec2f CustomSIFT::getSubpix(const Mat& img, Point2f off,KeyPoint p)
{
    Mat patch;
    Point2f pt (off.x+p.pt.x, off.y+p.pt.y);
    getRectSubPix(img, cv::Size(1,1), pt, patch);
    return patch.at<Vec2f>(0,0);
}
Пример #4
0
Mat deskew(Mat img, double angle)
{
  bitwise_not(img, img);

  vector<Point> points;
  Mat_<uchar>::iterator it = img.begin<uchar>();
  Mat_<uchar>::iterator end = img.end<uchar>();
  for (; it != end; ++it)
    if (*it)
      points.push_back(it.pos());
 
  RotatedRect box = minAreaRect(Mat(points));

  Mat rot_mat = getRotationMatrix2D(box.center, angle, 1);

  Mat rotated;
  warpAffine(img, rotated, rot_mat, img.size(), INTER_CUBIC);

  Size box_size = box.size;
  if (box.angle < -45.)
    swap(box_size.width, box_size.height);

  Mat cropped;
  getRectSubPix(rotated, box_size, box.center, cropped);

  return cropped;
}
Пример #5
0
double getSubpix(const Mat& img, float x, float y, KeyPoint p)
{
    Mat patch;
    Point2f pt (x+p.pt.x,y+p.pt.y);
    getRectSubPix(img, cv::Size(1,1), pt, patch);
    return patch.at<int>(0,0);
}
bool ASM_Gaze_Tracker::calculatePupilCenter(){
    Mat  leftEyeImg,rightEyeImg,cropped;

    if (isTrackingSuccess == false) {
        return false;
    }
    
    canthusPts = vector<Point2f>(tracker.points.begin(),tracker.points.begin()+4);
    nosePts = vector<Point2f>(tracker.points.begin()+4,tracker.points.begin()+6);
    
    if (canthusPts[2].x < canthusPts[0].x && canthusPts[0].x < canthusPts[1].x && canthusPts[1].x < canthusPts[3].x) {
    } else {
        return false;
    }
    
    eyePairTileAngle = calculateEyePairTileAngle(canthusPts);
    glabellaPoint= caculateEyePairCenter(canthusPts);
    
    rotationMatrix = getRotationMatrix2D(glabellaPoint, eyePairTileAngle, 1.0);
    Mat Mback = getRotationMatrix2D(glabellaPoint, -eyePairTileAngle, 1.0);
    
    vector<Point2f> rotatedCanthusPts = rotatePointsByRotationMatrix(canthusPts, rotationMatrix);
    vector<Point2f> rotatedNosePts = rotatePointsByRotationMatrix(nosePts, rotationMatrix);
    
    float eyePairRectWidth =abs(rotatedCanthusPts[2].x - rotatedCanthusPts[3].x)+1;
    Size2f eyePairRectSize(eyePairRectWidth,eyePairRectWidth/7);
    Rect cropRect(Point2f(glabellaPoint.x-eyePairRectWidth/2,glabellaPoint.y -eyePairRectWidth/14.0f),eyePairRectSize);
    
    warpAffine(im, rotated_img, rotationMatrix, im.size(),CV_INTER_LINEAR);
    getRectSubPix(rotated_img, eyePairRectSize, glabellaPoint, cropped);
    
    Rect leftEyeRect = Rect(0,0,rotatedCanthusPts[0].x-rotatedCanthusPts[2].x,eyePairRectSize.height);
    Rect rightEyeRect = Rect(rotatedCanthusPts[1].x-rotatedCanthusPts[2].x,0,rotatedCanthusPts[3].x-rotatedCanthusPts[1].x,eyePairRectSize.height);
    
    if (leftEyeRect.area() < 50 || rightEyeRect.area()< 50) {
        return false;
    }
    
    Point2f leftEyeCenter, rightEyeCenter;
    
//    findEyeCenterByColorSegmentation(cropped(leftEyeRect), leftEyeCenter);
//    findEyeCenterByColorSegmentation(cropped(rightEyeRect), rightEyeCenter);
//    cout<<"debug"<<endl;
    
    boost::thread leftEyeThread(findEyeCenterByColorSegmentation, cropped(leftEyeRect), boost::ref(leftEyeCenter), 0.4,3,3,5);
    boost::thread  rightEyeThread(findEyeCenterByColorSegmentation, cropped(rightEyeRect), boost::ref(rightEyeCenter), 0.4,3,3,5);
    leftEyeThread.join();
    rightEyeThread.join();
    
    leftEyeCenter += Point2f(leftEyeRect.tl().x,leftEyeRect.tl().y);
    leftEyeCenter += Point2f(cropRect.tl().x, cropRect.tl().y);
    rightEyeCenter += Point2f(rightEyeRect.tl().x,rightEyeRect.tl().y);
    rightEyeCenter += Point2f(cropRect.tl().x,cropRect.tl().y);
    
    leftEyePoint= rotatePointByRotationMatrix(leftEyeCenter, Mback);
    rightEyePoint= rotatePointByRotationMatrix(rightEyeCenter, Mback);
    isTrackingSuccess = true;
    return true;
}
Пример #7
0
void
FaceDetector::run(){

    CascadeClassifier cascade;
    if (!cascade.load("res/haarcascade_frontalface_alt.xml") ) {
        qDebug() << "Erreur lors du chargement du haar cascade frontalface...";
        exit(0);
    }

    QSize processSize = keepAspectRatio(_image.cols, _image.rows, MAX_PROCESS_WIDTH, MAX_PROCESS_HEIGHT);
    Mat color;
    if ( _image.cols > processSize.width() ){
        cv::resize( _image, color, cv::Size(processSize.width(), processSize.height() ) );
    } else {
        color = _image.clone();
    }

    QSize displaySize = keepAspectRatio(color.cols, color.rows);
    _ratio = (double) color.cols/displaySize.width();

    Mat gray;
    cvtColor(color, gray, CV_BGR2GRAY);


    //PRETRAITEMENT
    equalizeHist(gray, gray);

    vector<Rect> facesRects;
    cascade.detectMultiScale(gray, facesRects, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, cvSize(16,16));

    // qDebug() << "detected faces size: " << facesRects.size();
    
    for (unsigned int i = 0; i < facesRects.size(); ++i){

        Rect r = facesRects[i];
        Mat croppedFace;
        getRectSubPix(color, Size(r.width, r.height), Point2f(r.x + r.width/2, r.y + r.height / 2), croppedFace);
        // qImageFaces << Mat2QImage(croppedFace);

        struct DetectorData tmpData;
        tmpData.id = i;
        cv::resize( croppedFace, croppedFace, Size(WORK_SIZE,WORK_SIZE) );
        tmpData.image = Mat2QImage(croppedFace);
        emit sendFace( tmpData.image );
        tmpData.rect = QRect(r.x/_ratio+1, r.y/_ratio+1, r.width/_ratio+1, r.height/_ratio+1);
        tmpData.cvRect = r;
        tmpData.mat = croppedFace;
        cvtColor(croppedFace, tmpData.gray, CV_RGB2GRAY);
        // cv::resize( tmpData.gray, tmpData.gray, Size(WORK_SIZE,WORK_SIZE) );
        
        detectorData << tmpData;
    }
    qRegisterMetaType< QList<struct DetectorData> >( "QList<struct DetectorData>" );
    emit detectionFinished( _index, detectorData );
}
Пример #8
0
//! 显示最终生成的车牌图像,便于判断是否成功进行了旋转。
Mat CPlateLocate::showResultMat(Mat src, Size rect_size, Point2f center)
{
	Mat img_crop;
	getRectSubPix(src, rect_size, center, img_crop);

	Mat resultResized;
	resultResized.create(HEIGHT, WIDTH, TYPE);

	resize(img_crop, resultResized, resultResized.size(), 0, 0, INTER_CUBIC);

	return resultResized;
}
void LKTracker::normCrossCorrelation(const Mat& img1, const Mat& img2, vector<Point2f>& points1, vector<Point2f>& points2)
{
	Mat rec0(10, 10, CV_8U);
	Mat rec1(10, 10, CV_8U);
	Mat res(1, 1, CV_32F);

	//double maxDis = 3.0f * sqrt(window_size.width*window_size.width + window_size.height*window_size.height); // 过滤距离过远的光流
	similarity.clear();
	for (int i = 0; i < points1.size(); i++) {
		if (status[i] == 1 /*&& norm(points1[i] - points2[i]) < maxDis*/) {
			getRectSubPix(img1, Size(10, 10), points1[i], rec0);
			getRectSubPix(img2, Size(10, 10), points2[i], rec1);
			matchTemplate(rec0, rec1, res, CV_TM_CCOEFF_NORMED);
			similarity.push_back( ((float *)(res.data))[0] );
		}
		else {
			similarity.push_back(0.0);
		}
	}
	rec0.release();
	rec1.release();
	res.release();
}
Пример #10
0
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;
}
Пример #11
0
void crop(Mat &segmentedHand, Mat &croppedHand) {
    // code taken from 
    // http://stackoverflow.com/questions/3669611/bounding-box-using-opencv
    vector<vector<Point> > v;
    // Finds contours
    findContours(segmentedHand,v,CV_RETR_LIST,CV_CHAIN_APPROX_NONE);

    // Finds the contour with the largest area
    int area = 0;
    int idx;
    for(int i=0; i<v.size();i++) {
        if(area < v[i].size())
            idx = i; 
    }

    // Calculates the bounding rect of the largest area contour
    Rect rect = boundingRect(v[idx]);
    getRectSubPix(
        segmentedHand,
        rect.size(),
        Point2f(rect.x + rect.width/2.0, rect.y + rect.height/2.0),
        croppedHand);
}
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;
}
Пример #13
0
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;
}
Пример #14
0
void cv::cornerSubPix( InputArray _image, InputOutputArray _corners,
                       Size win, Size zeroZone, TermCriteria criteria )
{
    CV_INSTRUMENT_REGION()

    const int MAX_ITERS = 100;
    int win_w = win.width * 2 + 1, win_h = win.height * 2 + 1;
    int i, j, k;
    int max_iters = (criteria.type & CV_TERMCRIT_ITER) ? MIN(MAX(criteria.maxCount, 1), MAX_ITERS) : MAX_ITERS;
    double eps = (criteria.type & CV_TERMCRIT_EPS) ? MAX(criteria.epsilon, 0.) : 0;
    eps *= eps; // use square of error in comparsion operations

    cv::Mat src = _image.getMat(), cornersmat = _corners.getMat();
    int count = cornersmat.checkVector(2, CV_32F);
    CV_Assert( count >= 0 );
    Point2f* corners = cornersmat.ptr<Point2f>();

    if( count == 0 )
        return;

    CV_Assert( win.width > 0 && win.height > 0 );
    CV_Assert( src.cols >= win.width*2 + 5 && src.rows >= win.height*2 + 5 );
    CV_Assert( src.channels() == 1 );

    Mat maskm(win_h, win_w, CV_32F), subpix_buf(win_h+2, win_w+2, CV_32F);
    float* mask = maskm.ptr<float>();

    for( i = 0; i < win_h; i++ )
    {
        float y = (float)(i - win.height)/win.height;
        float vy = std::exp(-y*y);
        for( j = 0; j < win_w; j++ )
        {
            float x = (float)(j - win.width)/win.width;
            mask[i * win_w + j] = (float)(vy*std::exp(-x*x));
        }
    }

    // make zero_zone
    if( zeroZone.width >= 0 && zeroZone.height >= 0 &&
        zeroZone.width * 2 + 1 < win_w && zeroZone.height * 2 + 1 < win_h )
    {
        for( i = win.height - zeroZone.height; i <= win.height + zeroZone.height; i++ )
        {
            for( j = win.width - zeroZone.width; j <= win.width + zeroZone.width; j++ )
            {
                mask[i * win_w + j] = 0;
            }
        }
    }

    // do optimization loop for all the points
    for( int pt_i = 0; pt_i < count; pt_i++ )
    {
        Point2f cT = corners[pt_i], cI = cT;
        int iter = 0;
        double err = 0;

        do
        {
            Point2f cI2;
            double a = 0, b = 0, c = 0, bb1 = 0, bb2 = 0;

            getRectSubPix(src, Size(win_w+2, win_h+2), cI, subpix_buf, subpix_buf.type());
            const float* subpix = &subpix_buf.at<float>(1,1);

            // process gradient
            for( i = 0, k = 0; i < win_h; i++, subpix += win_w + 2 )
            {
                double py = i - win.height;

                for( j = 0; j < win_w; j++, k++ )
                {
                    double m = mask[k];
                    double tgx = subpix[j+1] - subpix[j-1];
                    double tgy = subpix[j+win_w+2] - subpix[j-win_w-2];
                    double gxx = tgx * tgx * m;
                    double gxy = tgx * tgy * m;
                    double gyy = tgy * tgy * m;
                    double px = j - win.width;

                    a += gxx;
                    b += gxy;
                    c += gyy;

                    bb1 += gxx * px + gxy * py;
                    bb2 += gxy * px + gyy * py;
                }
            }

            double det=a*c-b*b;
            if( fabs( det ) <= DBL_EPSILON*DBL_EPSILON )
                break;

            // 2x2 matrix inversion
            double scale=1.0/det;
            cI2.x = (float)(cI.x + c*scale*bb1 - b*scale*bb2);
            cI2.y = (float)(cI.y - b*scale*bb1 + a*scale*bb2);
            err = (cI2.x - cI.x) * (cI2.x - cI.x) + (cI2.y - cI.y) * (cI2.y - cI.y);
            cI = cI2;
            if( cI.x < 0 || cI.x >= src.cols || cI.y < 0 || cI.y >= src.rows )
                break;
        }
        while( ++iter < max_iters && err > eps );

        // if new point is too far from initial, it means poor convergence.
        // leave initial point as the result
        if( fabs( cI.x - cT.x ) > win.width || fabs( cI.y - cT.y ) > win.height )
            cI = cT;

        corners[pt_i] = cI;
    }
}
  void ELucidBinaryDescriptorExtractor::computeDescriptors(
    const cv::Mat& image,
    const std::vector<cv::KeyPoint>& key_points,
    std::vector<bool> *valid_descriptors,
    cv::Mat *descriptors) const
  {    
    std::clock_t start = std::clock();
    cv::Mat blurred_image;
    int _blur_radius = 5; //FIXME: move this to class member
    cv::blur(image,
             blurred_image,
             cv::Size(_blur_radius, _blur_radius));

    const int num_channels = image.channels();
    
    uchar pixels[num_samples];

    valid_descriptors->reserve(key_points.size());

    // TODO: Clean this up and don't use redundant code
    if(!_useWideDesc)
    {
      int desc_width = 32;
      assert(desc_width == num_samples / 2);
      cv::Mat descs(key_points.size(),
                    desc_width,
                    CV_8UC1);

      /* Unary Representation Lookup Tables*/
      uchar lut_lower[4] =
        {
          0x00,
          0x01,
          0x03,
          0x07,
        };

      uchar lut_upper[4] =
        {
          0x00,
          0x10,
          0x30,
          0x70,
        };

      for(int k = 0; k < key_points.size(); ++k)
      {
        uchar *cur_desc = descs.ptr<uchar>(k);
        float x = key_points[k].pt.x;
        float y = key_points[k].pt.y;

        valid_descriptors->push_back(
          (x - patch_size/2) > 0 &&
          (y - patch_size/2) > 0 &&
          (x + patch_size/2) < image.cols &&
          (y + patch_size/2) < image.rows);

        if((*valid_descriptors)[k])
        {

          // TODO: Replace this by directly accessing pattern pixels
          cv::Mat patch;
          getRectSubPix(blurred_image,
                        cv::Size(patch_size, patch_size),
                        key_points[k].pt,
                        patch);
        
          uchar* patch_ptr = patch.data;

          for(int p = 0; p < num_samples; ++p)
          {
            pixels[p] = patch_ptr[pattern[p][1] * patch_size + pattern[p][0]];
          } 

          int bin_width = 16;
          uchar temp_desc[num_samples];
          Util::getRankVectors2(num_samples,
                                bin_width,
                                pixels,
                                &(temp_desc[0]));

          int next_idx = 0;
          for(int i = 0; i < num_samples; i+=2)
          {
            cur_desc[next_idx++] =
              lut_lower[temp_desc[i]] | lut_upper[temp_desc[i+1]];
          }
        }
      } 

      std::clock_t stop = std::clock();
      std::cout << "Time to compute eLUCID 256 bit descriptors "
                << (1000.0*(stop - start)) / CLOCKS_PER_SEC 
                << "ms"
                << std::endl;
      *descriptors = descs;
    }
    else
    {
      int desc_width = 64;
      assert(desc_width == num_samples);
      cv::Mat descs(key_points.size(),
                    desc_width,
                    CV_8UC1);

      /* Sampled Unary Representation Lookup Tables*/
      uchar lut[8] =
        {
          0x00,      
          0x01,
          0x03,
          0x07,
          0x0f,
          0x1f,
          0x3f,
          0x7f,
        };

      for(int k = 0; k < key_points.size(); ++k)
      {
        uchar *cur_desc = descs.ptr<uchar>(k);
        float x = key_points[k].pt.x;
        float y = key_points[k].pt.y;

        valid_descriptors->push_back(
          (x - patch_size/2) > 0 &&
          (y - patch_size/2) > 0 &&
          (x + patch_size/2) < image.cols &&
          (y + patch_size/2) < image.rows);

        if((*valid_descriptors)[k])
        {

          // TODO: Replace this by directly accessing pattern pixels
          cv::Mat patch;
          getRectSubPix(blurred_image,
                        cv::Size(patch_size, patch_size),
                        key_points[k].pt,
                        patch);
        
          uchar* patch_ptr = patch.data;

          for(int p = 0; p < num_samples; ++p)
          {
            pixels[p] = patch_ptr[pattern[p][1] * patch_size + pattern[p][0]];
          } 

          int bin_width = 8;
          uchar temp_desc[num_samples];
          Util::getRankVectors2(num_samples,
                                bin_width,
                                pixels,
                                &(temp_desc[0]));

          for(int i = 0; i < num_samples; i++)
          {
            cur_desc[i] = lut[temp_desc[i]];
          }

        }
      }
        std::clock_t stop = std::clock();
        std::cout << "Time to compute eLUCID 512 bit descriptors "
                  << (1000.0*(stop - start)) / CLOCKS_PER_SEC 
                  << "ms"
                  << std::endl;
        *descriptors = descs;
    }
  }
Пример #16
0
double getSubpix(const Mat& img, Point2f pt)
{
    Mat patch;
    getRectSubPix(img, cv::Size(1,1), pt, patch);
    return patch.at<int>(0,0);
}
void	DetectRegions::part2( const cv::Mat& input,
			      std::vector<img_Plate>& output,
			      cv::Mat& img_threshold,
			      const std::string& out_id )
{

  cv::Mat	my_input;
  input.copyTo(my_input);

  //Find contours of possibles plates
  std::vector< std::vector< cv::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
		CV_CHAIN_APPROX_SIMPLE );


  //Start to iterate to each contour founded
  std::vector< std::vector<cv::Point> >::iterator itc = contours.begin();
  std::vector<cv::RotatedRect> rects;



  cv::Mat	my_input_rect;
  input.copyTo(my_input_rect);

  //Remove patch that are no inside limits of aspect ratio and area.
  while (itc != contours.end())
    {

      //Create bounding rect of object
      cv::RotatedRect	mr = minAreaRect(cv::Mat(*itc));

      if (!verifySizes(mr))
	{
	  itc = contours.erase(itc);

	  // rotated rectangle drawing
	  cv::Point2f	rect_points[4];
	  mr.points( rect_points );
	  for (int j = 0; j < 4; ++j)
	    line( my_input_rect, rect_points[j], rect_points[ (j + 1) % 4 ],
		  cv::Scalar(255,0,0), 1, 8 );

	}
      else
  	{
  	  ++itc;
  	  rects.push_back(mr);

	  // rotated rectangle drawing
	  cv::Point2f	rect_points[4];
	  mr.points( rect_points );
	  for (int j = 0; j < 4; ++j)
	    line( my_input_rect, rect_points[j], rect_points[ (j + 1) % 4 ],
		  cv::Scalar(0,255,0), 2, 8 );

  	}

    }


  D_IMG_SAVE( my_input_rect, "img_" << out_id << "Rect.png" );


  // 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
		    // 3 ); // with a thickness of 1

  D_IMG_SAVE( result, "04_img_" << out_id << "Contours.png" );


  // std::cerr << "rects.size : " << rects.size() << std::endl;

  std::vector<cv::Mat>	Mats;

  for (unsigned 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, cv::Scalar(0,255,0), -1);

      //get the min size between width and height
      // float minSize = ( (rects[i].size.width < rects[i].size.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
      cv::Mat mask;
      mask.create(input.rows + 2, input.cols + 2, CV_8UC1);
      mask = cv::Scalar::all(0);
      int loDiff = 30;
      int upDiff = 30;
      int connectivity = 4;
      int newMaskVal = 255;
      // int NumSeeds = 100;
      cv::Rect ccomp;
      int flags = connectivity + (newMaskVal << 8) + CV_FLOODFILL_FIXED_RANGE + CV_FLOODFILL_MASK_ONLY;


      int	max_size = rects[i].size.width * rects[i].size.height;


      cv::Rect	b_rect = rects[i].boundingRect();

      int	min_x = b_rect.x;
      int	min_y = b_rect.y;

      int	max_x = min_x + b_rect.width;
      int	max_y = min_y + b_rect.height;

      for (int local_y = min_y; local_y < max_y; local_y += 5)
	for (int local_x = min_x; local_x < max_x; local_x += 5)
	  {
	    cv::Point	seed;

	    seed.x = local_x;
	    seed.y = local_y;

	    if (Collision( contours[i], seed ))
	      {
		cv::Mat	tmp_mask;
		tmp_mask.create( input.rows + 2, input.cols + 2, CV_8UC1 );
		tmp_mask = cv::Scalar::all(0);

		int	area = floodFill( input, tmp_mask, seed,
	  				  cv::Scalar(255,0,0), &ccomp,
	  				  cv::Scalar(loDiff, loDiff, loDiff),
	  				  cv::Scalar(upDiff, upDiff, upDiff), flags );



		{
		  cv::Point	c( ccomp.x + ccomp.width / 2,
			   ccomp.y + ccomp.height / 2 );

		  cv::Size	s( ccomp.width, ccomp.height );

		  cv::RotatedRect	tmp_rect( c, s, 0 );

		  // rotated rectangle drawing
		  cv::Point2f	rect_points[4];
		  tmp_rect.points( rect_points );
		  for (int j = 0; j < 4; ++j)
		    line( my_input, rect_points[j], rect_points[ (j + 1) % 4 ],
			  cv::Scalar(0,255,255), 1, 8 );
		}


		bool	rect_invalid = ( ccomp.x < min_x || ccomp.x > max_x ||
					 ccomp.y < min_y || ccomp.y > max_y );


		cv::Point	left_top( min_x, min_y );
		cv::Point	right_top( max_x, min_y );

		cv::Point	left_bottom( min_x, max_y );
		cv::Point	right_bottom( max_x, max_y );

		if (area > max_size)
		  {
		    circle( result, seed, 1, cv::Scalar(255,0,0), -1 );
		    circle( my_input, seed, 1, cv::Scalar(255,0,0), -1 );
		  }

		else if (rect_invalid)
		  {
		    circle( result, seed, 1, cv::Scalar(255,0,0), -1 );
		    circle( my_input, seed, 1, cv::Scalar(255,0,0), -1 );
		  }

		else
		  {
		    circle( result, seed, 1, cv::Scalar(0,255,0), -1 );
		    circle( my_input, seed, 1, cv::Scalar(0,255,0), -1 );

		    floodFill( input, mask, seed,
			       cv::Scalar(255,0,0), &ccomp,
			       cv::Scalar(loDiff, loDiff, loDiff),
			       cv::Scalar(upDiff, upDiff, upDiff), flags );
		  }

	      }
	    else
	      {
		circle( result, seed, 1, cv::Scalar(255,0,0), -1 );
		circle( my_input, seed, 1, cv::Scalar(255,0,0), -1 );
	      }

	  } // for (int j = 0; j < NumSeeds; ++j)


      {


	// rotated rectangle drawing
	cv::Point2f	rect_points[4];
	rects[i].points( rect_points );
	for (int j = 0; j < 4; ++j)
	  line( my_input, rect_points[j], rect_points[ (j + 1) % 4 ],
		cv::Scalar(255,255,255), 2, 8 );


	D_IMG_SAVE( mask, "img_" << out_id << "" << i << "_01_Mask.png" );

      }

      //cvWaitKey(0);

      //Check new floodfill mask match for a correct patch.
      //Get all points detected for get Minimal rotated Rect
      std::vector<cv::Point>	pointsInterest;
      cv::Mat_<uchar>::iterator	itMask = mask.begin<uchar>();
      cv::Mat_<uchar>::iterator	end = mask.end<uchar>();
      for (; itMask != end; ++itMask)
	if (*itMask == 255)
	  pointsInterest.push_back(itMask.pos());

      if (pointsInterest.size() < 2)
	continue;

      cv::RotatedRect	minRect = minAreaRect(pointsInterest);

      if (verifySizes(minRect))
	{

	  // rotated rectangle drawing
	  cv::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], cv::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;

	  cv::Mat rotmat = getRotationMatrix2D(minRect.center, angle,1);

	  //Create and rotate image
	  cv::Mat img_rotated;
	  warpAffine(input, img_rotated, rotmat, input.size(), CV_INTER_CUBIC);

	  //Crop image
	  cv::Size rect_size = minRect.size;

	  if (r < 1)
	    std::swap( rect_size.width, rect_size.height );

	  cv::Mat img_crop;
	  getRectSubPix(img_rotated, rect_size, minRect.center, img_crop);


	  D_IMG_SAVE( img_crop, "img_" << out_id << "" << i << "_02_crop.png" );

	  cv::Mat	resultResized;
	  resultResized.create(33,144, CV_8UC3);
	  resize(img_crop, resultResized, resultResized.size(), 0, 0, cv::INTER_CUBIC);


	  D_IMG_SAVE( resultResized, "img_" << out_id << "" << i << "_03_resultResized.png" );

	  output.push_back( img_Plate( resultResized, minRect.boundingRect() ) );

	  // //Equalize croped image
	  // cv::Mat grayResult;
	  // cvtColor(resultResized, grayResult, CV_BGR2GRAY);
	  // // blur(grayResult, grayResult, Size(3,3));
	  // grayResult = histeq(grayResult);


	  // D_IMG_SAVE( grayResult, "img_" << out_id << "" << i << "_04_grayResult.png" );

	  // output.push_back( Plate( grayResult, minRect.boundingRect() ) );

	} // if (verifySizes(minRect))

    } // for (int i = 0; i < rects.size(); ++i)

  D_IMG_SAVE( result, "10_img_" << out_id << "Contours.png" );

  D_IMG_SAVE( my_input, "11_img_" << out_id << "my_input.png" );
}
Пример #18
0
int parting_char(Mat &img)
{
	int nRows;
	int nCols;
	int nCnt;
	int sum;
	int avg;
	int start;
	Mat img_clip;
	

	if(img.channels() != 1)
	{
		printf("parting_char(Mat &img) channel is not 1\n");
		return -1;
	}
	nRows = img.rows;
	nCols = img.cols;
	int *h_Cnt = new int[nCols]; 
	memset(h_Cnt,0,sizeof(int)*nCols);
	for(int j=0;j<nCols;++j)
	{	
		for(int i=0;i<nRows;++i)
		{
			if(img.at<uchar>(i,j) != 0x0)
				++h_Cnt[j];
				
		}
	}

	//getRectSubPix(img,Size(img.width,),Point(img_rect.cols/2,up+(down-up)/2),img_clip);
	for(int i =0;i<nCols;++i)
	{
		if(h_Cnt[i] != 0)
		{
//			printf("i=%d,value=%d",i,h_Cnt[i]);
			start = i;
			nCnt = 0;
			while(i<nCols&&h_Cnt[i] != 0)
			{
				++nCnt;
				++i;
			}
			sum = 0;
			for(int j =0;j<nCnt;++j)
			{
				sum += h_Cnt[i+j];
			}
			avg = sum / nCnt;
			if(avg >= 3)
			{
			
				printf("start=%d,end=%d\n",start,i);
				getRectSubPix(img,Size(i-start,img.rows),Point(start+(i-start)/2,img.rows/2),img_clip);
				string str = "abc"+i;
				namedWindow(str,CV_WINDOW_NORMAL);
				imshow(str,img_clip);
			}
		}
	}
	
	delete h_Cnt;
	return 0;
}
Пример #19
0
int main(int argc,char**argv)
{
	int scale = 1;
	int delta = 0;
	int ddepth = CV_16S;
//	check the number of parameter
	if(argc !=2)
	{	
		printf("please follow like this\n");
		printf("exe[] img_name\n");
		return -1;
	}
//	reads image
	img_src = imread(argv[1]);
//	check whether read operation is ok or not 
	if(img_src.data == NULL)
	{	
		printf("could not open or find the image!\n");
		return -1;
	}
//	use Gaussian blur to reduce the noise
	GaussianBlur(img_src,img_src,Size(3,3),0,0,BORDER_DEFAULT);

//	convert source image to gray image
	cvtColor(img_src,img_gray,CV_BGR2GRAY);
//	sobel in x direction
	Sobel(img_gray,grad_x,ddepth,1,0,3,scale,delta,BORDER_DEFAULT);
	convertScaleAbs(grad_x,abs_grad_x);

//	use sobel in y direction
	Sobel(img_gray,grad_y,ddepth,0,1,3,scale,delta,BORDER_DEFAULT);
	convertScaleAbs(grad_y,abs_grad_y);
//	add weight,and 
	addWeighted(abs_grad_x,0.5,abs_grad_y,0.5,0,grad);

//	use threshold to binarition and threshold select use the OTSU method
	threshold(grad,img_bin_thre,0,255,THRESH_BINARY|THRESH_OTSU);
//	first Dilate,second erode
	Mat element = getStructuringElement(MORPH_RECT,Size(2*1+1,2*1+1),Point(-1,-1));
	for(int i = 0;i < 3; i++)
	{
		morphologyEx(img_bin_thre,img_bin_thre,MORPH_OPEN,element);
		morphologyEx(img_bin_thre,img_bin_thre,MORPH_CLOSE,element);
	}
//	origin method ,this is worse than morphologyEx 
	
//	dilate(img_bin_thre,img_bin_thre,element);
//	namedWindow("dilated",CV_WINDOW_NORMAL);
//	imshow("dilated",img_bin_thre);
//	erode(img_bin_thre,img_bin_thre,element);
//	namedWindow("erode",CV_WINDOW_NORMAL);
//	imshow("erode",img_bin_thre);

//	find contour,in here must use the binarition image
//	define 
	vector<Vec4i> hierarchy;
	vector< vector<Point> >contours;
//	use function
	findContours(img_bin_thre,contours,hierarchy,CV_RETR_CCOMP,CV_CHAIN_APPROX_SIMPLE,Point(0,0));
//	please change min and the max area value based on reality
	int min_area = 100000;
	int max_area = 300000;
	Rect mRect;
	int tempArea;
//	define the color drawing contour
	Scalar color = Scalar(255,255,0);
	Mat drawing = Mat::zeros(img_bin_thre.size(),CV_8UC1);
	for(int i = 0;i < contours.size();i++)
	{
//	get the minimum rectangle of the contours
		mRect = boundingRect(contours[i]);
//	computer the square of mRect
		tempArea = mRect.height * mRect.width;
//	for debug
//		printf("tempArea.height:%d\ttempArea.width:%d\ttempArea.area=%d\n",mRect.height,mRect.width,tempArea);
//	filter area which meet the requirement
		if(((double)mRect.width/(double)mRect.height) > 2.0 && (tempArea > min_area) && ((double)mRect.width/(double)mRect.height < 4) && (tempArea < max_area))
//	draw contours
		{
			drawContours(drawing,contours,i,color,2,8,hierarchy);
//	here use 2 image ,one is just from image which be processed by threshold,the other is the original gray image,if you just use first,you 
//	may not 
			getRectSubPix(img_bin_thre,Size(mRect.width,mRect.height),Point(mRect.x+mRect.width/2,mRect.y\
					 +mRect.height/2),img_get_rect);	
			getRectSubPix(img_gray,Size(mRect.width,mRect.height),Point(mRect.x+mRect.width/2,mRect.y\
					 +mRect.height/2),img_get_rect_new);
		}
	}
	if(img_get_rect.data == NULL)
	{
		printf("img_get rect is null\n");
		return -1;
	}
	if(img_get_rect_new.data == NULL)
	{
		printf("img_get_rect_new is null!\n");
		return -1;
	}

//	use the HoughLinesP

//	define lines
	vector<Vec4i> lines;
//	Mat color_dst;
//	img_lines = img_get_rect.clone();
	cvtColor(img_get_rect,img_lines,CV_GRAY2BGR);
//	check the line in image img_get_rect
	HoughLinesP(img_get_rect,lines,1,CV_PI/180,200,200,10);
	printf("lines.size()=%d\n",lines.size());
	
	int distance = 0;
//	int theta;
	double temp_slope = 0,slope;
	int res_x1,res_y1,res_x2,res_y2;
//	define map vector for computer the line used frequency
//	vector <int,int> ivect;//first is the number of this line , next is the longest distance 
//	map <double,ivect> imap;
	int delta_x,delta_y;

	
	std::vector <dou_int> ivec;
	std::vector <dou_int>::iterator iter;

	for(size_t i = 0;i < lines.size();i++)
	{
		Vec4i l = lines[i];
		line(img_lines,Point(l[0],l[1]),Point(l[2],l[3]),Scalar(0,0,255),3);
//	find tilt angle
		if(l[2]-l[0] == 0)
			;
		else
		{
//	computer this line 's slope
//	delta_x / delta_y
			delta_y = (l[3]-l[1]);
			delta_x = (l[2]-l[0]);
			
			distance = delta_y*delta_y+delta_x*delta_x;
			temp_slope = ((double)delta_y)/((double)(delta_x));
			printf("in i=%d,delta_y=%d,delta_x=%d\n",i,delta_y,delta_x);

			for(iter = ivec.begin();iter != ivec.end();iter++)
			{
//	if in one line,num++,update the max length
				if(abs(iter->slope - temp_slope) < (double)0.01)
				{
					iter->num++;
					if(iter->maxlength < distance)
					{
						iter->maxlength = distance;
						iter->v0 = Point(l[0],l[1]);
						iter->v1 = Point(l[2],l[3]);
					}
					break;
				}
			}
//	not find this slope ,must add it by hand 
			if(iter == ivec.end())
			{
				ivec.push_back(dou_int(temp_slope,distance,1,Point(l[0],l[1]),Point(l[2],l[3])));	
			}
		}
	}
	int max = 0;
	int j = 0;
	int index = 0;
	dou_int res;

	for(j=0,iter = ivec.begin();iter != ivec.end();j++,iter++)
	{
		if(iter->num > max)
		{
			max = iter->num;
			index = j;
		}
	}
	printf("index is %d\n",index);
	for(j=0,iter = ivec.begin();iter != ivec.end() && j <= index;j++,iter++)
	{
		if(j == index)
		{
			res = dou_int(iter->slope,iter->maxlength,iter->num,iter->v0,iter->v1);
			printf("slope is %f\n",iter->slope);
			break;
		}
	}
//	drawing the tilt line
	line(img_lines,res.v0,res.v1,Scalar(255,255,0),1);


	Mat img_lines_out;
	Point center = Point(img_lines.cols/2,img_lines.rows/2);
	double angle =(double)(180/CV_PI)*(double)atan(res.slope);
	printf("angle is :%f\n",angle);
	Mat rot_mat = getRotationMatrix2D(center,angle,1.0);
	warpAffine(img_lines,img_lines_out,rot_mat,img_lines.size());
	Mat img_rect;
	warpAffine(img_get_rect_new,img_rect,rot_mat,img_get_rect_new.size());

	cvtColor(img_lines_out,img_lines_out,CV_BGR2GRAY);
	printf("img_clip's channel is:%d\n",img_lines_out.channels());
	threshold(img_lines_out,img_lines_out,10,255,THRESH_BINARY | THRESH_OTSU);

	Mat img_clip;
	int up,down;

	if(-1 != remove_Border_Vertical(img_lines_out,up,down))
	{
		printf("up=%d,down=%d\n",up,down);
		getRectSubPix(img_lines_out,Size(img_lines_out.cols,down-up),Point(img_lines_out.cols/2,up+(down-up)/2),img_clip);
		namedWindow("line_clip",CV_WINDOW_NORMAL);
		imshow("line_clip",img_clip);
		getRectSubPix(img_rect,Size(img_rect.cols,down-up),Point(img_rect.cols/2,up+(down-up)/2),img_clip);
		namedWindow("new_clip",CV_WINDOW_NORMAL);
		imshow("new_clip",img_clip);
	}
//	binarition OTSU
	threshold(img_clip,img_clip,10,255,THRESH_BINARY | THRESH_OTSU);
	namedWindow("newrect",CV_WINDOW_NORMAL);
	imshow("newrect",img_clip);

	parting_char(img_clip);
	
	waitKey(0);
	return 0;
}
Пример #20
0
void ModelMaker::extractModel(cv::Mat origframe)
{
    //       qDebug()<<"Frame is"<<frame.empty();
    for(int i = 0; i < centroids.size(); i++) {
        
        Mat subtractedframe(origframe);
        subtractedframe = subtractBack(origframe);
        Mat polymask = subtractedframe.clone();
        
        //                cv::cvtColor(frameMat, frameMat, CV_BGR2BGRA);
        
        //                cv::cvtColor(polymask, polymask, CV_BGR2BGRA);
        
        
        //cv::rectangle(mask, Point( 0, 0 ), Point( mask.cols, mask.rows), Scalar( 0, 255,0,255 ),-1, 8 ); //Fill all mask in
        
        polymask.setTo(Scalar(0,0,0,0));
        //Polgon Masking
        polygon = paintCanvas->polygons.at(i);
        
        Point poly_points[polygon.size()];
        
        //Find point furthest from center
        Point furthest = Point(paintCanvas->centerPoint.x()*xscale,paintCanvas->centerPoint.y()*yscale);  //set to center
        
        int scaledcenterx = paintCanvas->centerPoint.x()*xscale;
        int scaledcentery = paintCanvas->centerPoint.y()*yscale;
        int scaledheadx= paintCanvas->headPoint.x()*xscale;
        int scaledheady=paintCanvas->headPoint.y()*yscale;
        
        
        float biggestdistancesquared=0;
        
        
        for(int j=0;j<polygon.size();j++)
        {
            poly_points[j]=Point(xscale*polygon.at(j).x(), yscale*polygon.at(j).y());
            
            Point candidate = Point(xscale*polygon.at(j).x(), yscale*polygon.at(j).y());
            float distancecandidatesquared;
            //Find furthest
            distancecandidatesquared= (candidate.x - scaledcenterx)*(candidate.x - scaledcenterx) + (candidate.y - scaledcentery)*(candidate.y - scaledcentery);
            if(distancecandidatesquared>biggestdistancesquared){
                biggestdistancesquared=distancecandidatesquared;
                qDebug()<<"biggcandidate x "<<candidate.x <<"  y "<<candidate.y << "    distance ="<<biggestdistancesquared;
                
            }
            
            
            
        }
        
        const Point* ppt[1] = { poly_points };
        int npt[] = { polygon.size() };
        
        
        
        fillPoly( polymask,
                  ppt,
                  npt,
                  1,
                  Scalar( 255, 255,255,255 ),
                  
                  8,
                  0);
        
        
        
        //Debug
        //                                cv::circle(origframe,cv::Point(scaledcenterx,scaledcentery),1,Scalar(255,255,255,255),2);
        //                                cv::circle(origframe,cv::Point(scaledheadx,scaledheady),1,Scalar(255,0,255, 254),2);
        
        //cv::circle(polymask,cv::Point(scaledcenterx,scaledcentery),1,Scalar(255,255,255,255),2);
        //  cv::circle(polymask,cv::Point(scaledheadx,scaledheady),1,Scalar(255,0,255, 254),2);
        
        //  cv::circle(subtractedframe,cv::Point(scaledcenterx,scaledcentery),1,Scalar(255,255,255,255),2);
        //  cv::circle(subtractedframe,cv::Point(scaledheadx,scaledheady),1,Scalar(255,0,255, 254),2);
        
        
        
        //background subtraction: take original image, apply background as a mask, save over original
        //bitwise_and(subtractedframe, polymask, subtractedframe);
        
        qDebug()<<"Roi "<<x1<<"  "<<y1<<"  "<<x2<<"  "<<y2<<"  ";
        
        
        cv::cvtColor(polymask,polymask, CV_RGB2GRAY);
        
        
        //Full alpha mask = polygon selection (a =200) + BG subtracted organism (a= 255) + Center Mark ( a = 250) + head mark (a = 240)
        //Set Head to alpha=240
        //Set Center to Alpha = 250
        //Everything inside mask == alpha 200
        //Everything outside alpha=100;
        //BG subtracted ant = 255
        
        Mat maskedsubtraction;
        subtractedframe.copyTo(maskedsubtraction,polymask); // note that m.copyTo(m,mask) will have no masking effect
        cvtColor(maskedsubtraction, maskedsubtraction,CV_BGR2GRAY);
        polymask = polymask+155;   //255 moves to 255, 0 moves to 155
        polymask = polymask - 55;  //255 moves to 200, 155 moves to 100
        maskedsubtraction = polymask+maskedsubtraction;
        
        cv::circle(maskedsubtraction,cv::Point(scaledcenterx,scaledcentery),1,Scalar(250),2); //Encode the Center
        cv::circle(maskedsubtraction,cv::Point(scaledheadx,scaledheady),1,Scalar(240),2); //encode the head
        
        Mat bgr;
        bgr=origframe.clone();
        
        Mat alpha;
        maskedsubtraction.copyTo(alpha);
        Mat bgra;
        cvtColor(origframe, bgra,CV_BGR2BGRA); //Copy the origframe, we'll write over it next
        
        
        
        
        // forming array of matrices is quite efficient operations,
        // because the matrix data is not copied, only the headers
        Mat in[] = { bgr, alpha };
        // BGRa[0] -> bgr[0], BGRa[1] -> bgr[1],
        // BGRa[2] -> bgr[2], BGRa[3] -> alpha[0]
        int from_to[] = { 0,0,  1,1,  2,2,  3,3 };
        mixChannels( in, 2, &bgra, 1, from_to, 4 ); // input array, number of files in input array, destination, number of files in destination, from-to array, number of pairs in from-to
        
        
        
        QString ext = ".png";
        // QString fullframe = savepath+paintCanvas->polyNames.at(i)+"_"+QString::number(centroids[i].x())+"_"+QString::number(centroids[i].y())+"_"+QString::number(currentFrame)+ext;
        QString modelfilename = savepath+paintCanvas->polyNames.at(i)+"_f"+QString::number(currentFrame)+ext;
        
        //DEBUG IMAGES
        /*
              imwrite(modelfilename.toStdString()+"_subtraction",subtractedframe);
                imwrite(modelfilename.toStdString()+"_polymask",polymask);
                imwrite(modelfilename.toStdString()+"_alpha",alpha);
        */
        
        
        
        //save out Model
        
        //Full Keyframe
//        imwrite(modelfilename.toStdString()+"_keyframe",bgra); //Disabled for now
        
        qDebug()<<"Saved out: "<<modelfilename;
        
        //***Crop and Rotate ***//
        qDebug()<<"crop centered on  "<<scaledcenterx<<"  "<<scaledcentery;
        //crop the frame based on ROI
        Point2f src_center(scaledcenterx, scaledcentery);
        //To do this correctly use getRectSubPix instead of frameMat(MYROI) method
        // getRectSubPix only works with certain image formats (this is undocumented in opencv : P
        // so we have to do that cutting and mixing again!
        getRectSubPix(bgr, cv::Size(sqrt(biggestdistancesquared)*2,sqrt(biggestdistancesquared)*2), src_center, bgr);
        getRectSubPix(alpha, cv::Size(sqrt(biggestdistancesquared)*2,sqrt(biggestdistancesquared)*2), src_center, alpha);
        
        Mat bgracropped;
        cvtColor(bgr, bgracropped,CV_BGR2BGRA); //Copy the origframe, we'll write over it next
        Mat inagain[] = { bgr, alpha };
        int from_to2[] = { 0,0,  1,1,  2,2,  3,3 };
        
        //Note: the height and width dimensions have to be the same for the inputs and outputs
        mixChannels( inagain, 2, &bgracropped, 1, from_to2, 4 ); // input array, number of files in input array, destination, number of files in destination, from-to array, number of pairs in from-to
        
        
        //rotate the cropped frame about the center of the cropped frame.
        qDebug()<<"Rotate that image  "<<angle;
        bgracropped = rotateImage(bgracropped, angle);//Rotate full image about this center
        
        //after I rotate clear the global angle
        angle =0;
        //debug
        angle=-1;
        
        

        // Save the Nicely Rotated and Cropped Model File
        imwrite(modelfilename.toStdString(),bgracropped);
        
        
        centroids.clear();
        maxXY.clear();
        minXY.clear();
        paintCanvas->polyNames.clear();
        paintCanvas->polygons.clear();
        paintCanvas->masks.pop_back();
        polyinfo = "Polygon cleared";
        paintCanvas->temp.clear();
        ui->statusBar->showMessage(polyinfo,2000);
        paintCanvas->replyMask = replyNull;
        capture.set(CV_CAP_PROP_POS_FRAMES,(double)currentFrame);
    }
    
    
}
Пример #21
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;
  }