/*
 * objective : get the gray level map of the input image and rescale it to the range [0-255]
 */
 static void rescaleGrayLevelMat(const cv::Mat &inputMat, cv::Mat &outputMat, const float histogramClippingLimit)
 {

     // adjust output matrix wrt the input size but single channel
     std::cout<<"Input image rescaling with histogram edges cutting (in order to eliminate bad pixels created during the HDR image creation) :"<<std::endl;
     //std::cout<<"=> image size (h,w,channels) = "<<inputMat.size().height<<", "<<inputMat.size().width<<", "<<inputMat.channels()<<std::endl;
     //std::cout<<"=> pixel coding (nbchannel, bytes per channel) = "<<inputMat.elemSize()/inputMat.elemSize1()<<", "<<inputMat.elemSize1()<<std::endl;

     // rescale between 0-255, keeping floating point values
     cv::normalize(inputMat, outputMat, 0.0, 255.0, cv::NORM_MINMAX);

     // extract a 8bit image that will be used for histogram edge cut
     cv::Mat intGrayImage;
     if (inputMat.channels()==1)
     {
         outputMat.convertTo(intGrayImage, CV_8U);
     }else
     {
         cv::Mat rgbIntImg;
         outputMat.convertTo(rgbIntImg, CV_8UC3);
         cvtColor(rgbIntImg, intGrayImage, cv::COLOR_BGR2GRAY);
     }

     // get histogram density probability in order to cut values under above edges limits (here 5-95%)... usefull for HDR pixel errors cancellation
     cv::Mat dst, hist;
     int histSize = 256;
     calcHist(&intGrayImage, 1, 0, cv::Mat(), hist, 1, &histSize, 0);
     cv::Mat normalizedHist;
     normalize(hist, normalizedHist, 1, 0, cv::NORM_L1, CV_32F); // normalize histogram so that its sum equals 1

     double min_val, max_val;
     minMaxLoc(normalizedHist, &min_val, &max_val);
     //std::cout<<"Hist max,min = "<<max_val<<", "<<min_val<<std::endl;

     // compute density probability
     cv::Mat denseProb=cv::Mat::zeros(normalizedHist.size(), CV_32F);
     denseProb.at<float>(0)=normalizedHist.at<float>(0);
     int histLowerLimit=0, histUpperLimit=0;
     for (int i=1;i<normalizedHist.size().height;++i)
     {
         denseProb.at<float>(i)=denseProb.at<float>(i-1)+normalizedHist.at<float>(i);
         //std::cout<<normalizedHist.at<float>(i)<<", "<<denseProb.at<float>(i)<<std::endl;
         if ( denseProb.at<float>(i)<histogramClippingLimit)
             histLowerLimit=i;
         if ( denseProb.at<float>(i)<1-histogramClippingLimit)
             histUpperLimit=i;
     }
     // deduce min and max admitted gray levels
     float minInputValue = (float)histLowerLimit/histSize*255;
     float maxInputValue = (float)histUpperLimit/histSize*255;

     std::cout<<"=> Histogram limits "
             <<"\n\t"<<histogramClippingLimit*100<<"% index = "<<histLowerLimit<<" => normalizedHist value = "<<denseProb.at<float>(histLowerLimit)<<" => input gray level = "<<minInputValue
             <<"\n\t"<<(1-histogramClippingLimit)*100<<"% index = "<<histUpperLimit<<" => normalizedHist value = "<<denseProb.at<float>(histUpperLimit)<<" => input gray level = "<<maxInputValue
             <<std::endl;
     //drawPlot(denseProb, "input histogram density probability", histLowerLimit, histUpperLimit);
     drawPlot(normalizedHist, "input histogram", histLowerLimit, histUpperLimit);

     // rescale image range [minInputValue-maxInputValue] to [0-255]
     outputMat-=minInputValue;
     outputMat*=255.0/(maxInputValue-minInputValue);
     // cut original histogram and back project to original image
     cv::threshold( outputMat, outputMat, 255.0, 255.0, 2 ); //THRESH_TRUNC, clips values above 255
     cv::threshold( outputMat, outputMat, 0.0, 0.0, 3 ); //THRESH_TOZERO, clips values under 0

 }
Mat TemplateMatching::run(Mat & src)
{

    Mat img = src;



    // Source image to display
    Mat img_display;
    img.copyTo( img_display );

    int result_cols; int result_rows;

    // Para minmaxLoc
    double minVal; double maxVal; Point minLoc; Point maxLoc;
    //guardar maximo global
    double MAX = 0; Point MAXLoc; int num;

    //cargar templates
    templ[0][0] = imread("Template/template/template11.jpg");
    templ[0][1] = imread("Template/template/template12.jpg");
    templ[0][2] = imread("Template/template/template13.jpg");
    templ[0][3] = imread("Template/template/template14.jpg");
    templ[1][0] = imread("Template/template/template21.jpg");
    templ[1][1] = imread("Template/template/template22.jpg");
    templ[1][2] = imread("Template/template/template23.jpg");
    templ[1][3] = imread("Template/template/template24.jpg");
    templ[2][0] = imread("Template/template/template31.jpg");
    templ[2][1] = imread("Template/template/template32.jpg");
    templ[2][2] = imread("Template/template/template33.jpg");
    templ[2][3] = imread("Template/template/template34.jpg");
    templ[3][0] = imread("Template/template/template41.jpg");
    templ[3][1] = imread("Template/template/template42.jpg");
    templ[3][2] = imread("Template/template/template43.jpg");
    templ[3][3] = imread("Template/template/template44.jpg");
    templ[4][0] = imread("Template/template/template51.jpg");
    templ[4][1] = imread("Template/template/template52.jpg");
    templ[4][2] = imread("Template/template/template53.jpg");
    templ[4][3] = imread("Template/template/template54.jpg");

    //FOR tamaños templates
    for (int i=0;i<5;i++)
    {

        // Matriz de resultados
        result_cols =  img.cols - templ[i][0].cols + 1;
        result_rows = img.rows - templ[i][0].rows + 1;

        result[i].create( result_cols, result_rows, CV_32FC1 );

        //FOR rotacion
        for (int j=0;j<4;j++)
        {

            // Matching y normalizacion
            matchTemplate( img, templ[i][j], result[i], CV_TM_CCOEFF_NORMED);

            //guardar maximo para esta rotacion de template
            minMaxLoc( result[i], &minVal, &maxVal, &minLoc, &maxLoc, Mat() );

            //comparar con maximo global para este tamaño
            if (maxVal>MAX)
            {
                MAX = maxVal;
                num = j;
                MAXLoc = maxLoc;
            }
            normalize( result[i], result[i], 0, 1, NORM_MINMAX, -1, Mat() );
            //buscar maximo
            minMaxLoc( result[i], &minVal, &maxVal, &minLoc, &maxLoc, Mat() );

        }
        //termina FOR rotacion

        //buscar nuevamente aquella rotacion que arrojo mejor resultado
        matchTemplate( img, templ[i][num], result[i], CV_TM_CCOEFF_NORMED);
        minMaxLoc( result[i], &minVal, &maxVal, &minLoc, &maxLoc, Mat() );

        // mostrar resultados
        rectangle( img_display, Point( maxLoc.x-10,maxLoc.y-10),
                   Point( maxLoc.x+10 + templ[i][num].cols , maxLoc.y + templ[i][num].rows+10 ),
                   Scalar::all(0), 2, 8, 0 );
        rectangle( result[i], maxLoc, Point( maxLoc.x + templ[i][num].cols ,
                                             maxLoc.y + templ[i][num].rows ), Scalar::all(0), 2, 150, 0 );

        //termina FOR tamaños

    }
    // imshow( "result_window", result[4] );
    //Mostrar mejor resultado de cada template
    imshow( "resultado MatchTemplate", img_display ); //comentar
    return img_display;       //DEBIESE DEVOLVER EL RESULTADO? ( result[0] hasta [result[4] )
}
void RecognitionDemos( Mat& full_image, Mat& template1, Mat& template2, Mat& template1locations, Mat& template2locations, VideoCapture& bicycle_video, Mat& bicycle_background, Mat& bicycle_model, VideoCapture& people_video, CascadeClassifier& cascade, Mat& numbers, Mat& good_orings, Mat& bad_orings, Mat& unknown_orings )
{
	Timestamper* timer = new Timestamper();

	// Principal Components Analysis
	PCASimpleExample();
    char ch = cvWaitKey();
	cvDestroyAllWindows();

	PCAFaceRecognition();
    ch = cvWaitKey();
	cvDestroyAllWindows();

	// Statistical Pattern Recognition
	Mat gray_numbers,binary_numbers;
	cvtColor(numbers, gray_numbers, CV_BGR2GRAY);
	threshold(gray_numbers,binary_numbers,128,255,THRESH_BINARY_INV);
    vector<vector<Point>> contours;
	vector<Vec4i> hierarchy;
	findContours(binary_numbers,contours,hierarchy,CV_RETR_TREE,CV_CHAIN_APPROX_NONE);
	Mat contours_image = Mat::zeros(binary_numbers.size(), CV_8UC3);
	contours_image = Scalar(255,255,255);
	// Do some processing on all contours (objects and holes!)
	vector<RotatedRect> min_bounding_rectangle(contours.size());
	vector<vector<Point>> hulls(contours.size());
	vector<vector<int>> hull_indices(contours.size());
	vector<vector<Vec4i>> convexity_defects(contours.size());
	vector<Moments> contour_moments(contours.size());
	for (int contour_number=0; (contour_number<(int)contours.size()); contour_number++)
	{
		if (contours[contour_number].size() > 10)
		{
			min_bounding_rectangle[contour_number] = minAreaRect(contours[contour_number]);
			convexHull(contours[contour_number], hulls[contour_number]);
			convexHull(contours[contour_number], hull_indices[contour_number]);
			convexityDefects( contours[contour_number], hull_indices[contour_number], convexity_defects[contour_number]);
			contour_moments[contour_number] = moments( contours[contour_number] );
		}
	}
	for (int contour_number=0; (contour_number>=0); contour_number=hierarchy[contour_number][0])
	{
		if (contours[contour_number].size() > 10)
		{
        Scalar colour( rand()&0x7F, rand()&0x7F, rand()&0x7F );
        drawContours( contours_image, contours, contour_number, colour, CV_FILLED, 8, hierarchy );
		char output[500];
		double area = contourArea(contours[contour_number])+contours[contour_number].size()/2+1;
		// Process any holes (removing the area from the are of the enclosing contour)
		for (int hole_number=hierarchy[contour_number][2]; (hole_number>=0); hole_number=hierarchy[hole_number][0])
		{
			area -= (contourArea(contours[hole_number])-contours[hole_number].size()/2+1);
			Scalar colour( rand()&0x7F, rand()&0x7F, rand()&0x7F );
 			drawContours( contours_image, contours, hole_number, colour, CV_FILLED, 8, hierarchy );
			sprintf(output,"Area=%.0f", contourArea(contours[hole_number])-contours[hole_number].size()/2+1);
			Point location( contours[hole_number][0].x +20, contours[hole_number][0].y +5 );
			putText( contours_image, output, location, FONT_HERSHEY_SIMPLEX, 0.4, colour );
		}
		// Draw the minimum bounding rectangle
		Point2f bounding_rect_points[4];
		min_bounding_rectangle[contour_number].points(bounding_rect_points);
		line( contours_image, bounding_rect_points[0], bounding_rect_points[1], Scalar(0, 0, 127));
		line( contours_image, bounding_rect_points[1], bounding_rect_points[2], Scalar(0, 0, 127));
		line( contours_image, bounding_rect_points[2], bounding_rect_points[3], Scalar(0, 0, 127));
		line( contours_image, bounding_rect_points[3], bounding_rect_points[0], Scalar(0, 0, 127));
		float bounding_rectangle_area = min_bounding_rectangle[contour_number].size.area();
		// Draw the convex hull
        drawContours( contours_image, hulls, contour_number, Scalar(127,0,127) );
		// Highlight any convexities
		int largest_convexity_depth=0;
		for (int convexity_index=0; convexity_index < (int)convexity_defects[contour_number].size(); convexity_index++)
		{
			if (convexity_defects[contour_number][convexity_index][3] > largest_convexity_depth)
				largest_convexity_depth = convexity_defects[contour_number][convexity_index][3];
			if (convexity_defects[contour_number][convexity_index][3] > 256*2)
			{
				line( contours_image, contours[contour_number][convexity_defects[contour_number][convexity_index][0]], contours[contour_number][convexity_defects[contour_number][convexity_index][2]], Scalar(0,0, 255));
				line( contours_image, contours[contour_number][convexity_defects[contour_number][convexity_index][1]], contours[contour_number][convexity_defects[contour_number][convexity_index][2]], Scalar(0,0, 255));
			}
		}
		double hu_moments[7];
		HuMoments( contour_moments[contour_number], hu_moments );
		sprintf(output,"Perimeter=%d, Area=%.0f, BArea=%.0f, CArea=%.0f", contours[contour_number].size(),area,min_bounding_rectangle[contour_number].size.area(),contourArea(hulls[contour_number]));
		Point location( contours[contour_number][0].x, contours[contour_number][0].y-3 );
		putText( contours_image, output, location, FONT_HERSHEY_SIMPLEX, 0.4, colour );
		sprintf(output,"HuMoments = %.2f, %.2f, %.2f", hu_moments[0],hu_moments[1],hu_moments[2]);
		Point location2( contours[contour_number][0].x+100, contours[contour_number][0].y-3+15 );
		putText( contours_image, output, location2, FONT_HERSHEY_SIMPLEX, 0.4, colour );
		}
	}
	imshow("Shape Statistics", contours_image );
	char c = cvWaitKey();
	cvDestroyAllWindows();

	// Support Vector Machine
	imshow("Good - original",good_orings);
	imshow("Defective - original",bad_orings);
	imshow("Unknown - original",unknown_orings);
	SupportVectorMachineDemo(good_orings,"Good",bad_orings,"Defective",unknown_orings);
	c = cvWaitKey();
	cvDestroyAllWindows();

	// Template Matching
	Mat display_image, correlation_image;
	full_image.copyTo( display_image );
	double min_correlation, max_correlation;
	Mat matched_template_map;
	int result_columns =  full_image.cols - template1.cols + 1;
	int result_rows = full_image.rows - template1.rows + 1;
	correlation_image.create( result_columns, result_rows, CV_32FC1 );
	timer->reset();
	double before_tick_count = static_cast<double>(getTickCount());
	matchTemplate( full_image, template1, correlation_image, CV_TM_CCORR_NORMED );
	double after_tick_count = static_cast<double>(getTickCount());
	double duration_in_ms = 1000.0*(after_tick_count-before_tick_count)/getTickFrequency();
	minMaxLoc( correlation_image, &min_correlation, &max_correlation );
	FindLocalMaxima( correlation_image, matched_template_map, max_correlation*0.99 );
	timer->recordTime("Template Matching (1)");
	Mat matched_template_display1;
	cvtColor(matched_template_map, matched_template_display1, CV_GRAY2BGR);
	Mat correlation_window1 = convert_32bit_image_for_display( correlation_image, 0.0 );
	DrawMatchingTemplateRectangles( display_image, matched_template_map, template1, Scalar(0,0,255) );
	double precision, recall, accuracy, specificity, f1;
	Mat template1locations_gray;
	cvtColor(template1locations, template1locations_gray, CV_BGR2GRAY);
	CompareRecognitionResults( matched_template_map, template1locations_gray, precision, recall, accuracy, specificity, f1 );
	char results[400];
	Scalar colour( 255, 255, 255);
	sprintf( results, "precision=%.2f", precision);
	Point location( 7, 213 );
	putText( display_image, "Results (1)", location, FONT_HERSHEY_SIMPLEX, 0.4, colour );
	location.y += 13;
	putText( display_image, results, location, FONT_HERSHEY_SIMPLEX, 0.4, colour );
	sprintf( results, "recall=%.2f", recall);
	location.y += 13;
	putText( display_image, results, location, FONT_HERSHEY_SIMPLEX, 0.4, colour );
	sprintf( results, "accuracy=%.2f", accuracy);
	location.y += 13;
	putText( display_image, results, location, FONT_HERSHEY_SIMPLEX, 0.4, colour );
	sprintf( results, "specificity=%.2f", specificity);
	location.y += 13;
	putText( display_image, results, location, FONT_HERSHEY_SIMPLEX, 0.4, colour );
	sprintf( results, "f1=%.2f", f1);
	location.y += 13;
	putText( display_image, results, location, FONT_HERSHEY_SIMPLEX, 0.4, colour );
  
	result_columns =  full_image.cols - template2.cols + 1;
	result_rows = full_image.rows - template2.rows + 1;
	correlation_image.create( result_columns, result_rows, CV_32FC1 );
	timer->ignoreTimeSinceLastRecorded();
	matchTemplate( full_image, template2, correlation_image, CV_TM_CCORR_NORMED );
	minMaxLoc( correlation_image, &min_correlation, &max_correlation );
	FindLocalMaxima( correlation_image, matched_template_map, max_correlation*0.99 );
	timer->recordTime("Template Matching (2)");
	Mat matched_template_display2;
	cvtColor(matched_template_map, matched_template_display2, CV_GRAY2BGR);
	Mat correlation_window2 = convert_32bit_image_for_display( correlation_image, 0.0 );
	DrawMatchingTemplateRectangles( display_image, matched_template_map, template2, Scalar(0,0,255) );
	timer->putTimes(display_image);
	Mat template2locations_gray;
	cvtColor(template2locations, template2locations_gray, CV_BGR2GRAY);
	CompareRecognitionResults( matched_template_map, template2locations_gray, precision, recall, accuracy, specificity, f1 );
	sprintf( results, "precision=%.2f", precision);
	location.x = 123;
	location.y = 213;
	putText( display_image, "Results (2)", location, FONT_HERSHEY_SIMPLEX, 0.4, colour );
	location.y += 13;
	putText( display_image, results, location, FONT_HERSHEY_SIMPLEX, 0.4, colour );
	sprintf( results, "recall=%.2f", recall);
	location.y += 13;
	putText( display_image, results, location, FONT_HERSHEY_SIMPLEX, 0.4, colour );
	sprintf( results, "accuracy=%.2f", accuracy);
	location.y += 13;
	putText( display_image, results, location, FONT_HERSHEY_SIMPLEX, 0.4, colour );
	sprintf( results, "specificity=%.2f", specificity);
	location.y += 13;
	putText( display_image, results, location, FONT_HERSHEY_SIMPLEX, 0.4, colour );
	sprintf( results, "f1=%.2f", f1);
	location.y += 13;
	putText( display_image, results, location, FONT_HERSHEY_SIMPLEX, 0.4, colour );
	Mat correlation_display1, correlation_display2;
	cvtColor(correlation_window1, correlation_display1, CV_GRAY2BGR);
	cvtColor(correlation_window2, correlation_display2, CV_GRAY2BGR);

	Mat output1 = JoinImagesVertically(template1,"Template (1)",correlation_display1,"Correlation (1)",4);
	Mat output2 = JoinImagesVertically(output1,"",matched_template_display1,"Local maxima (1)",4);
	Mat output3 = JoinImagesVertically(template2,"Template (2)",correlation_display2,"Correlation (2)",4);
	Mat output4 = JoinImagesVertically(output3,"",matched_template_display2,"Local maxima (2)",4);
	Mat output5 = JoinImagesHorizontally( full_image, "Original Image", output2, "", 4 );
	Mat output6 = JoinImagesHorizontally( output5, "", output4, "", 4 );
	Mat output7 = JoinImagesHorizontally( output6, "", display_image, "", 4 );
	imshow( "Template matching result", output7 );
	c = cvWaitKey();
	cvDestroyAllWindows();

	// Chamfer Matching
    Mat model_gray,model_edges,model_edges2;
	cvtColor(bicycle_model, model_gray, CV_BGR2GRAY);
	threshold(model_gray,model_edges,127,255,THRESH_BINARY);
	Mat current_frame;
	bicycle_video.set(CV_CAP_PROP_POS_FRAMES,400);  // Just in case the video has already been used.
	bicycle_video >> current_frame;
	bicycle_background = current_frame.clone();
	bicycle_video.set(CV_CAP_PROP_POS_FRAMES,500); 
	timer->reset();
	int count = 0;
	while (!current_frame.empty() && (count < 8))
    {
		Mat result_image = current_frame.clone();
		count++;
		Mat difference_frame, difference_gray, current_edges;
		absdiff(current_frame,bicycle_background,difference_frame);
		cvtColor(difference_frame, difference_gray, CV_BGR2GRAY);
		Canny(difference_frame, current_edges, 100, 200, 3);

		vector<vector<Point> > results;
		vector<float> costs;
		threshold(model_gray,model_edges,127,255,THRESH_BINARY);
		Mat matching_image, chamfer_image, local_minima;
		timer->ignoreTimeSinceLastRecorded();
		threshold(current_edges,current_edges,127,255,THRESH_BINARY_INV);
		distanceTransform( current_edges, chamfer_image, CV_DIST_L2 , 3);
		timer->recordTime("Chamfer Image");
		ChamferMatching( chamfer_image, model_edges, matching_image );
		timer->recordTime("Matching");
		FindLocalMinima( matching_image, local_minima, 500.0 );
		timer->recordTime("Find Minima");
		DrawMatchingTemplateRectangles( result_image, local_minima, model_edges, Scalar( 255, 0, 0 ) );
		Mat chamfer_display_image = convert_32bit_image_for_display( chamfer_image );
		Mat matching_display_image = convert_32bit_image_for_display( matching_image );
		//timer->putTimes(result_image);
		Mat current_edges_display, local_minima_display, model_edges_display, colour_matching_display_image, colour_chamfer_display_image;
		cvtColor(current_edges, current_edges_display, CV_GRAY2BGR);
		cvtColor(local_minima, local_minima_display, CV_GRAY2BGR);
		cvtColor(model_edges, model_edges_display, CV_GRAY2BGR);
		cvtColor(matching_display_image, colour_matching_display_image, CV_GRAY2BGR);
		cvtColor(chamfer_display_image, colour_chamfer_display_image, CV_GRAY2BGR);

		Mat output1 = JoinImagesVertically(current_frame,"Video Input",current_edges_display,"Edges from difference", 4);
		Mat output2 = JoinImagesVertically(output1,"",model_edges_display,"Model", 4);
		Mat output3 = JoinImagesVertically(bicycle_background,"Static Background",colour_chamfer_display_image,"Chamfer image", 4);
		Mat output4 = JoinImagesVertically(output3,"",colour_matching_display_image,"Degree of fit", 4);
		Mat output5 = JoinImagesVertically(difference_frame,"Difference",result_image,"Result", 4);
		Mat output6 = JoinImagesVertically(output5,"",local_minima_display,"Local minima", 4);
		Mat output7 = JoinImagesHorizontally( output2, "", output4, "", 4 );
		Mat output8 = JoinImagesHorizontally( output7, "", output6, "", 4 );
		imshow("Chamfer matching", output8);
		c = waitKey(1000);  // This makes the image appear on screen
		bicycle_video >> current_frame;
	}
	c = cvWaitKey();
	cvDestroyAllWindows();

	// Cascade of Haar classifiers (most often shown for face detection).
    VideoCapture camera;
	camera.open(1);
	camera.set(CV_CAP_PROP_FRAME_WIDTH, 320);
	camera.set(CV_CAP_PROP_FRAME_HEIGHT, 240);
    if( camera.isOpened() )
	{
		timer->reset();
		Mat current_frame;
		do {
			camera >> current_frame;
			if( current_frame.empty() )
				break;
			vector<Rect> faces;
			timer->ignoreTimeSinceLastRecorded();
			Mat gray;
			cvtColor( current_frame, gray, CV_BGR2GRAY );
			equalizeHist( gray, gray );
			cascade.detectMultiScale( gray, faces, 1.1, 2, CV_HAAR_SCALE_IMAGE, Size(30, 30) );
			timer->recordTime("Haar Classifier");
			for( int count = 0; count < (int)faces.size(); count++ )
				rectangle(current_frame, faces[count], cv::Scalar(255,0,0), 2);
			//timer->putTimes(current_frame);
			imshow( "Cascade of Haar Classifiers", current_frame );
			c = waitKey(10);  // This makes the image appear on screen
        } while (c == -1);
	}
示例#4
0
	ofVec2f findMaxLocation(Mat& mat) {
		double minVal, maxVal;
		cv::Point minLoc, maxLoc;
		minMaxLoc(mat, &minVal, &maxVal, &minLoc, &maxLoc);
		return ofVec2f(maxLoc.x, maxLoc.y);
	}
//变角度线扫描法——改进后的线扫描法
void findCircleParameter::revisedScanLineMethod(Mat imgOrg, Point2i& center, int& radius, int threshold, int N)
{
	Mat src, gray;
	src = imgOrg.clone();
	cvtColor(src, gray, CV_BGR2GRAY);

	vector<Point> points;
	vector<double> distance;

	Size imgSize = src.size();

	int x, y;
	double theta = 0;

	for (int n = 0; n < 2 * N; n++, theta = PI*n / (2 * N))
	{
		//if (n == N||n==0) continue;
		int min1, min2;
		min1 = min2 = 255;
		int max1, max2;
		max1 = max2 = 0;
		int radius = 0;
		Point ptMax1(0, 0), ptMax2(0, 0);
		Point ptMin1(0, 0), ptMin2(0, 0);
		int flag = 0;

		double minVal, maxVal;

		if (0 == n)
		{
			for (int i = 0; i < imgSize.height; i++)
			{
				minMaxLoc(gray.row(i), &minVal, &maxVal, &ptMin1, &ptMax1);
				if ((maxVal - minVal)>threshold)
				{
					flag++;

					ptMax1.y = i;
					//cout << "horizontal top:" << endl;
					//cout << "ptMax1=(" << ptMax1.x << ", " << ptMax1.y << ")" << endl;
					points.push_back(ptMax1);
					goto top_label;
				}
			}
		top_label:

#ifdef _SHOW_POINTS_
			circle(src, ptMax1, 5, Scalar(0, 255, 255), -1);
			imshow("src", src);
			waitKey();
#endif

			for (int i = imgSize.height - 1; i >= 0; i--)
			{
				minMaxLoc(gray.row(i), &minVal, &maxVal, &ptMin2, &ptMax2);
				if ((maxVal - minVal) > threshold)
				{
					flag++;

					ptMax2.y = i;
					//cout << "horizontal bottom:" << endl;
					//cout << "ptMax2=(" << ptMax2.x << ", " << ptMax2.y << ")" << endl;

					//src.row(i) = Scalar(0, 0, 255);
					//src.row(i + 1) = Scalar(0, 0, 255);

					points.push_back(ptMax2);
					goto bottom_label;
				}
			}
		bottom_label:

#ifdef _SHOW_POINTS_
			circle(src, ptMax2, 5, Scalar(0, 255, 255), -1);
			line(src, ptMax1, ptMax2, Scalar(192, 192, 0), 2);
			imshow("src", src);
			waitKey();
#endif
			if (flag == 2)
			{
				distance.push_back(sqrt(pow(ptMax1.x - ptMax2.x, 2) + pow(ptMax1.y - ptMax2.y, 2)));
			}
			else if (flag == 1)
			{
				points.pop_back();
			}
		}
		else if (0 < n&&n < N)
		{
			for (int i = 0; i < imgSize.width; i++)
			{
				for (int j = 0; j <= i; j++)
				{
					x = j;
					y = -tan(theta)*(x - i);

					Point ptCur(x, y);
					if (!ptCur.inside(Rect(0, 0, imgSize.width, imgSize.height)))
					{
						continue;
					}

					uchar I = gray.at<uchar>(ptCur);

					if (I > max1)
					{
						max1 = I;
						ptMax1 = ptCur;
					}
					if (I < min1)
					{
						min1 = I;
					}

					if (abs(max1 - min1) > threshold)
					{
						flag++;
						//cout << "jump outer1" << endl;
						//cout << "ptMax1=(" << ptMax1.x << ", " << ptMax1.y << ")" << endl;
						points.push_back(ptMax1);

						/*						Point start, end;
						for (int k = 0; k <= i; k++)
						{
						x = k;
						y = -tan(theta)*(x - i);
						if (k == 0)
						{
						start = Point(x, y);
						}
						else if (k == i)
						{
						end = Point(x, y);
						}


						}
						line(src, start, end, Scalar(0, 0, 255), 2);*/

						goto outer1;
					}
				}
			}
		outer1:

#ifdef _SHOW_POINTS_
			circle(src, ptMax1, 5, Scalar(0, 255, 255), -1);
			imshow("src", src);
			waitKey();
#endif

			for (int i = imgSize.width - 1; i >= 0; i--)
			{
				for (int j = i; j < imgSize.width; j++)
				{
					x = j;
					y = imgSize.height - 1 - tan(theta)*(x - i);

					Point ptCur(x, y);

					if (!ptCur.inside(Rect(0, 0, imgSize.width, imgSize.height)))
					{
						continue;
					}
					uchar I = gray.at<uchar>(ptCur);

					if (I > max2)
					{
						max2 = I;
						ptMax2 = ptCur;
					}
					if (I < min2)
					{
						min2 = I;
					}

					if (abs(max2 - min2) > threshold)
					{
						flag++;
						//cout << "jump outer2" << endl;
						//cout << "ptMax2=(" << ptMax2.x << ", " << ptMax2.y << ")" << endl;
						points.push_back(ptMax2);

						//Point start, end;
						//for (int k = i; k < imgSize.width; k++)
						//{
						//	x = k;
						//	y = imgSize.height - 1 - tan(theta)*(x - i);
						//	if (k == i)
						//	{
						//		start = Point(x, y);
						//	}
						//	else if (k == imgSize.width-1)
						//	{
						//		end = Point(x, y);
						//	}


						//}
						//line(src, start, end, Scalar(0, 0, 255), 2);

						goto outer2;
					}
				}
			}
		outer2:
			;

#ifdef _SHOW_POINTS_
			circle(src, ptMax2, 5, Scalar(0, 255, 255), -1);
			line(src, ptMax1, ptMax2, Scalar(192, 192, 0), 2);
			imshow("src", src);
			waitKey();
#endif
			if (flag == 2)
			{
				distance.push_back(sqrt(pow(ptMax1.x - ptMax2.x, 2) + pow(ptMax1.y - ptMax2.y, 2)));
			}
			else if (flag == 1)
			{
				points.pop_back();
			}

		}
		else if (N == n)
		{
			for (int i = 0; i < imgSize.width; i++)
			{
				minMaxLoc(gray.col(i), &minVal, &maxVal, &ptMin1, &ptMax1);
				if ((maxVal - minVal)>threshold)
				{
					flag++;
					ptMax1.x = i;
					//cout << "vertical left:" << endl;
					//cout << "ptMax1=(" << ptMax1.x << ", " << ptMax1.y << ")" << endl;

					//src.col(i) = Scalar(0, 0, 255);
					//src.col(i - 1) = Scalar(0, 0, 255);
					points.push_back(ptMax1);
					goto left_label;
				}
			}
		left_label:

#ifdef _SHOW_POINTS_
			circle(src, ptMax1, 5, Scalar(0, 255, 255), -1);
			imshow("src", src);
			waitKey();
#endif

			for (int i = gray.cols - 1; i >= 0; i--)
			{
				minMaxLoc(gray.col(i), &minVal, &maxVal, &ptMin2, &ptMax2);
				if ((maxVal - minVal) > threshold)
				{
					flag++;
					ptMax2.x = i;
					//cout << "vertical right:" << endl;
					//cout << "ptMax1=(" << ptMax2.x << ", " << ptMax2.y << ")" << endl;
					points.push_back(ptMax2);

					//src.col(i) = Scalar(0, 0, 255);
					//src.col(i + 1) = Scalar(0, 0, 255);

					goto right_label;
				}
			}

		right_label:

#ifdef _SHOW_POINTS_
			circle(src, ptMax2, 5, Scalar(0, 255, 255), -1);
			line(src, ptMax1, ptMax2, Scalar(192, 192, 0), 2);
			imshow("src", src);
			waitKey();
#endif
			if (flag == 2)
			{
				distance.push_back(sqrt(pow(ptMax1.x - ptMax2.x, 2) + pow(ptMax1.y - ptMax2.y, 2)));
			}
			else if (flag == 1)
			{
				points.pop_back();
			}

		}
		else if (N < n&&n < 2 * N)
		{
			for (int i = 0; i < imgSize.width; i++)
			{
				for (int j = 0; j <= i; j++)
				{
					x = j;
					y = imgSize.height - 1 - tan(theta)*(x - i);

					Point ptCur(x, y);
					if (!ptCur.inside(Rect(0, 0, imgSize.width, imgSize.height)))
					{
						continue;
					}
					uchar I = gray.at<uchar>(ptCur);

					if (I > max1)
					{
						max1 = I;
						ptMax1 = ptCur;
					}
					if (I < min1)
					{
						min1 = I;
					}

					if (abs(max1 - min1) > threshold)
					{
						flag++;
						//cout << "jump outer3" << endl;
						//cout << "ptMax1=(" << ptMax1.x << ", " << ptMax1.y << ")" << endl;
						points.push_back(ptMax1);

						//Point start, end;
						//for (int k = 0; k <= i; k++)
						//{
						//	x = k;
						//	y = imgSize.height - 1 - tan(theta)*(x - i);

						//	if (k == 0)
						//	{
						//		start = Point(x, y);
						//	}
						//	else if (k == i)
						//	{
						//		end = Point(x, y);
						//	}
						//}
						//line(src, start, end, Scalar(0, 0, 255), 2);

						goto outer3;
					}
				}
			}
		outer3:

#ifdef _SHOW_POINTS_
			circle(src, ptMax1, 5, Scalar(0, 255, 255), -1);
			imshow("src", src);
			waitKey();
#endif

			for (int i = imgSize.width - 1 / 2; i >= 0; i--)
			{
				for (int j = i; j < imgSize.width; j++)
				{
					x = j;
					y = -tan(theta)*(x - i);

					Point ptCur(x, y);
					if (!ptCur.inside(Rect(0, 0, imgSize.width, imgSize.height)))
					{
						continue;
					}
					uchar I = gray.at<uchar>(ptCur);

					if (I > max2)
					{
						max2 = I;
						ptMax2 = ptCur;
					}
					if (I < min2)
					{
						min2 = I;
					}

					if (abs(max2 - min2) > threshold)
					{
						flag++;
						//cout << "jump outer4" << endl;
						//cout << "ptMax2=(" << ptMax2.x << ", " << ptMax2.y << ")" << endl;
						points.push_back(ptMax2);

						/*			Point start, end;
						for (int k = i; k < imgSize.width; k++)
						{
						x = k;
						y = -tan(theta)*(x - i);
						if (k == i)
						{
						start = Point(x, y);
						}
						else if (k == imgSize.width - 1)
						{
						end = Point(x, y);
						}


						}
						line(src, start, end, Scalar(0, 0, 255), 2);*/

						goto outer4;
					}
				}
			}
		outer4:

			;
#ifdef _SHOW_POINTS_
			circle(src, ptMax2, 5, Scalar(0, 255, 255), -1);
			line(src, ptMax1, ptMax2, Scalar(192, 192, 0), 2);
			imshow("src", src);
			waitKey();
#endif
			if (flag == 2)
			{
				distance.push_back(sqrt(pow(ptMax1.x - ptMax2.x, 2) + pow(ptMax1.y - ptMax2.y, 2)));
			}
			else if (flag == 1)
			{
				points.pop_back();
			}

		}
		else
		{
			cout << "The value of n is error!" << endl;
			break;
		}
	}


	//vector<Point>::iterator itero = points.begin();
	//ofstream of("points.txt", ios::trunc | ios::out);
	//while (itero != points.end())
	//{
	//	of << (*itero).x << ", " << (*itero).y << endl;
	//	itero++;
	//}
	//of.close(); 


	//find out validate points
	double mean = 0;
	vector<double>::iterator iter = distance.begin();
	while (iter != distance.end())
	{
		mean += *iter;
		iter++;
	}
	mean /= distance.size();

	vector<Point> validPoints;
	for (int i = 0; i < distance.size(); i++)
	{
		if (distance.at(i) < mean)
		{
			validPoints.push_back(points.at(2 * i));
			validPoints.push_back(points.at(2 * i + 1));
		}
	}

	//figure out the center and radius of the circle with Kasa method

	if (!CircleFitByKasa(validPoints, center, radius))
	{
		cout << "Revisied LineScan Method Failed, Because the Circle Fit Method failed!" << endl;
		return;
	}

	//#ifdef _DEBUG_
	cout << "Use the Revised ScanLine Method:" << endl
		<< "\tThe center is (" << center.x << ", "
		<< center.y << ")" << endl
		<< "\tThe radius is " << radius << endl;

	circle(src, center, radius, Scalar(0, 0, 255), src.cols / 300);
	circle(src, center, 5, Scalar(0, 255, 255), -1);

	//namedWindow("Revised ScanLine Method Result", CV_WINDOW_AUTOSIZE);
	//imshow("Revised ScanLine Method Result", src);
	imshow(win_name, src);
	//imwrite("Revised_Scan_ret.tiff", src);
	//waitKey();
	//#endif

}
示例#6
0
bool Scraper::FindBestBMP(const searchType type, HBITMAP hBmp, const double threshold, MATCHPOINTS* match, char* matchedBMP)
{
    // Convert HBITMAP to Mat
    unique_ptr<Gdiplus::Bitmap> pBitmap;
    pBitmap.reset(Gdiplus::Bitmap::FromHBITMAP(hBmp, NULL));
    Mat img = CGdiPlus::CopyBmpToMat(pBitmap.get());
    pBitmap.reset();

    cvtColor( img, img, CV_BGRA2BGR );

    // Find right image group
    imageType iType =
        type==searchTownHall ? townHall :
        type==searchLootCart ? lootCart :
        type==searchClashIcon ? clashIcon :
        type==searchPlayStoreOpenButton ? playStoreOpenButton :
        type==searchGoldStorage ? goldStorage :
        type==searchElixStorage ? elixStorage :
        type==searchDarkStorage ? darkStorage : (imageType) 0;

    int iTypeIndex = -1;
    for (int i = 0; i < (int) imageGroups.size(); i++)
        if (imageGroups[i].iType == iType)
            iTypeIndex = i;
    if (iTypeIndex == -1)
        return false;

    // Scan through each Mat in this image group
    double bestMaxVal = 0;
    Point bestMaxLoc(0, 0);
    string bestNeedlePath("");

    for (int i = 0; i < (int) imageGroups[iTypeIndex].mats.size(); i++)
    {
        Mat result = FindMatch(img, imageGroups[iTypeIndex].mats[i]);

        // Localize the best match with minMaxLoc
        double minVal, maxVal;
        Point minLoc, maxLoc;
        minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc);

        bool beachSideOfSWLine = BeachSideOfSWLine((westPoint.x+maxLoc.x), (northPoint.y-10+maxLoc.y));

        if (maxVal >= threshold && maxVal > bestMaxVal && (type!=searchTownHall || !beachSideOfSWLine))
        {
            bestMaxVal = maxVal;
            bestMaxLoc = maxLoc;
            bestNeedlePath = imageGroups[iTypeIndex].imagePaths[i];
        }
    }

    if (bestMaxVal > 0)
    {
        match->val = bestMaxVal;
        match->x = bestMaxLoc.x;
        match->y = bestMaxLoc.y;
        sprintf_s(matchedBMP, MAXSTRING, "%s", bestNeedlePath.c_str());
        return true;
    }

    return false;
}
示例#7
0
void *image_show( void *)        /*analiza imagem*/
{
    Mat frameCopy;
    Mat frameAnalize;
    Mat result;
    mouseInfo.event=-1;
    while(1)
    {
        pthread_mutex_lock(&in_frame);
        frameCopy=frame;
        pthread_mutex_unlock(&in_frame);

        pthread_mutex_lock(&in_mouseInfo);
        if(mouseInfo.x > 100 && mouseInfo.y >100 && mouseInfo.event==EVENT_LBUTTONDOWN)
        {
            Cerro;
            printf("Change! \n");
            Rect myDim(mouseInfo.x-25,mouseInfo.y-25, 50, 50);
            frameAnalize = frameCopy(myDim).clone();     
            frameAnalize.copyTo(frameAnalize);
        }
        else if(mouseInfo.event == -1)
        {
            Rect myDim(100,100, 50, 50);
            frameAnalize = frameCopy(myDim);     
            frameAnalize.copyTo(frameAnalize);
            mouseInfo.event=-2;
        }
        pthread_mutex_unlock(&in_mouseInfo);

        /// Create the result matrix
        int result_cols =  frameCopy.cols - frameAnalize.cols + 1;
        int result_rows = frameCopy.rows - frameAnalize.rows + 1;
        result.create( result_cols, result_rows, CV_32FC1 );

        /// Do the Matching and Normalize
        int match_method=1; //1-5
        matchTemplate( frameCopy, frameAnalize, result, match_method );
        normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() );

        /// Localizing the best match with minMaxLoc
        double minVal; double maxVal; Point minLoc; Point maxLoc;
        Point matchLoc;
        minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() );

        /// For SQDIFF and SQDIFF_NORMED, the best matches are lower values. For all the other methods, the higher the better
        if( match_method  == CV_TM_SQDIFF || match_method == CV_TM_SQDIFF_NORMED )
            { matchLoc = minLoc; }
        else
            { matchLoc = maxLoc; }
        
        /// Show me what you got
        rectangle( frameCopy, matchLoc, Point( matchLoc.x + frameAnalize.cols , matchLoc.y + frameAnalize.rows ), Scalar::all(0), 2, 8, 0 );
        rectangle( result, matchLoc, Point( matchLoc.x + frameAnalize.cols , matchLoc.y + frameAnalize.rows ), Scalar::all(0), 2, 8, 0 );

        /// make a dif with the original and the matched
        Rect myDim2(matchLoc.x,matchLoc.y,50 , 50);
        Mat frameAnalizado = frameCopy(myDim2).clone(); 
        Mat subt = frameAnalize - frameAnalizado;

        /// Make a simple text to debug
        char str[256];
        sprintf(str, "x:%d/y:%d", matchLoc.x, matchLoc.y);
        putText(frameCopy, str, cvPoint(30,30), FONT_HERSHEY_COMPLEX_SMALL, 0.8, cvScalar(200,200,250), 1, CV_AA);

        sprintf(str, "maxVal:%.8f/minVal:%.8f", maxVal, minVal);
        putText(frameCopy, str, cvPoint(30,60), FONT_HERSHEY_COMPLEX_SMALL, 0.6, cvScalar(200,200,250), 1, CV_AA);

        /// Show de imgs
        imshow("image_show",frameCopy);
        namedWindow("image_show", CV_WINDOW_NORMAL); waitKey(30);
        imshow("analize",frameAnalize);
        namedWindow("analize", CV_WINDOW_NORMAL); waitKey(30);
        imshow("result",result);
        namedWindow("result", CV_WINDOW_NORMAL); waitKey(30);
        imshow("analizado",frameAnalizado);
        namedWindow("analizado", CV_WINDOW_NORMAL); waitKey(30);
        imshow("sub",subt);
        namedWindow("sub", CV_WINDOW_NORMAL); waitKey(30);

        usleep(10);
        
    }
    Cerro; printf("Image_show Down !\n");
    return NULL;
}
示例#8
0
    void CV_BilateralFilterTest::reference_bilateral_filter(const Mat &src, Mat &dst, int d,
        double sigma_color, double sigma_space, int borderType)
    {
        int cn = src.channels();
        int i, j, k, maxk, radius;
        double minValSrc = -1, maxValSrc = 1;
        const int kExpNumBinsPerChannel = 1 << 12;
        int kExpNumBins = 0;
        float lastExpVal = 1.f;
        float len, scale_index;
        Size size = src.size();

        dst.create(size, src.type());

        CV_Assert( (src.type() == CV_32FC1 || src.type() == CV_32FC3) &&
            src.type() == dst.type() && src.size() == dst.size() &&
            src.data != dst.data );

        if( sigma_color <= 0 )
            sigma_color = 1;
        if( sigma_space <= 0 )
            sigma_space = 1;

        double gauss_color_coeff = -0.5/(sigma_color*sigma_color);
        double gauss_space_coeff = -0.5/(sigma_space*sigma_space);

        if( d <= 0 )
            radius = cvRound(sigma_space*1.5);
        else
            radius = d/2;
        radius = MAX(radius, 1);
        d = radius*2 + 1;
        // compute the min/max range for the input image (even if multichannel)

        minMaxLoc( src.reshape(1), &minValSrc, &maxValSrc );
        if(std::abs(minValSrc - maxValSrc) < FLT_EPSILON)
        {
            src.copyTo(dst);
            return;
        }

        // temporary copy of the image with borders for easy processing
        Mat temp;
        copyMakeBorder( src, temp, radius, radius, radius, radius, borderType );
        patchNaNs(temp);

        // allocate lookup tables
        vector<float> _space_weight(d*d);
        vector<int> _space_ofs(d*d);
        float* space_weight = &_space_weight[0];
        int* space_ofs = &_space_ofs[0];

        // assign a length which is slightly more than needed
        len = (float)(maxValSrc - minValSrc) * cn;
        kExpNumBins = kExpNumBinsPerChannel * cn;
        vector<float> _expLUT(kExpNumBins+2);
        float* expLUT = &_expLUT[0];

        scale_index = kExpNumBins/len;

        // initialize the exp LUT
        for( i = 0; i < kExpNumBins+2; i++ )
        {
            if( lastExpVal > 0.f )
            {
                double val =  i / scale_index;
                expLUT[i] = (float)std::exp(val * val * gauss_color_coeff);
                lastExpVal = expLUT[i];
            }
            else
                expLUT[i] = 0.f;
        }

        // initialize space-related bilateral filter coefficients
        for( i = -radius, maxk = 0; i <= radius; i++ )
            for( j = -radius; j <= radius; j++ )
            {
                double r = std::sqrt((double)i*i + (double)j*j);
                if( r > radius )
                    continue;
                space_weight[maxk] = (float)std::exp(r*r*gauss_space_coeff);
                space_ofs[maxk++] = (int)(i*(temp.step/sizeof(float)) + j*cn);
            }

        for( i = 0; i < size.height; i++ )
        {
            const float* sptr = (const float*)(temp.data + (i+radius)*temp.step) + radius*cn;
            float* dptr = (float*)(dst.data + i*dst.step);

            if( cn == 1 )
            {
                for( j = 0; j < size.width; j++ )
                {
                    float sum = 0, wsum = 0;
                    float val0 = sptr[j];
                    for( k = 0; k < maxk; k++ )
                    {
                        float val = sptr[j + space_ofs[k]];
                        float alpha = (float)(std::abs(val - val0)*scale_index);
                        int idx = cvFloor(alpha);
                        alpha -= idx;
                        float w = space_weight[k]*(expLUT[idx] + alpha*(expLUT[idx+1] - expLUT[idx]));
                        sum += val*w;
                        wsum += w;
                    }
                    dptr[j] = (float)(sum/wsum);
                }
            }
            else
            {
                assert( cn == 3 );
                for( j = 0; j < size.width*3; j += 3 )
                {
                    float sum_b = 0, sum_g = 0, sum_r = 0, wsum = 0;
                    float b0 = sptr[j], g0 = sptr[j+1], r0 = sptr[j+2];
                    for( k = 0; k < maxk; k++ )
                    {
                        const float* sptr_k = sptr + j + space_ofs[k];
                        float b = sptr_k[0], g = sptr_k[1], r = sptr_k[2];
                        float alpha = (float)((std::abs(b - b0) +
                            std::abs(g - g0) + std::abs(r - r0))*scale_index);
                        int idx = cvFloor(alpha);
                        alpha -= idx;
                        float w = space_weight[k]*(expLUT[idx] + alpha*(expLUT[idx+1] - expLUT[idx]));
                        sum_b += b*w; sum_g += g*w; sum_r += r*w;
                        wsum += w;
                    }
                    wsum = 1.f/wsum;
                    b0 = sum_b*wsum;
                    g0 = sum_g*wsum;
                    r0 = sum_r*wsum;
                    dptr[j] = b0; dptr[j+1] = g0; dptr[j+2] = r0;
                }
            }
        }
    }
示例#9
0
bool ObjPatchMatcher::Match(const Mat& cimg, const Mat& dmap_raw, Mat& mask_map) {

	/*
	 * precompute feature maps
	 */
	// gradient
	Mat gray_img, gray_img_float, edge_map;
	cvtColor(cimg, gray_img, CV_BGR2GRAY);
	gray_img.convertTo(gray_img_float, CV_32F, 1.f/255);
	Canny(gray_img, edge_map, 10, 50);
	cv::imshow("edge", edge_map);
	cv::imshow("color", cimg);
	cv::waitKey(10);

	Mat grad_x, grad_y, grad_mag;
	Sobel(gray_img_float, grad_x, CV_32F, 1, 0);
	Sobel(gray_img_float, grad_y, CV_32F, 0, 1);
	magnitude(grad_x, grad_y, grad_mag);

	// depth
	Mat dmap_float, pts3d, normal_map;
	if( use_depth ) {
		Feature3D feat3d;
		dmap_raw.convertTo(dmap_float, CV_32F);
		Mat cmp_mask;
		compare(dmap_float, 800, cmp_mask, CMP_LT);
		dmap_float.setTo(800, cmp_mask);
		compare(dmap_float, 7000, cmp_mask, CMP_GT);
		dmap_float.setTo(7000, cmp_mask);
		dmap_float = (dmap_float-800)/(7000-800);

		feat3d.ComputeKinect3DMap(dmap_float, pts3d, false);
		feat3d.ComputeNormalMap(pts3d, normal_map);
	}

	/*
	 *	start searching
	 */
	// init searcher
	//searcher.Build(patch_data, BruteForce_L2);	// opencv bfmatcher has size limit: maximum 2^31
	LSHCoder lsh_coder;
	if(use_code) {
		lsh_coder.Load();
	}
	
	Mat score_map = Mat::zeros(edge_map.rows, edge_map.cols, CV_32F);
	Mat mask_vote_map = Mat::zeros(cimg.rows, cimg.cols, CV_32F);
	mask_map = Mat::zeros(cimg.rows, cimg.cols, CV_32F);
	Mat mask_count = Mat::zeros(cimg.rows, cimg.cols, CV_32S);	// number of mask overlapped on each pixel
	Mat feat;
	int topK = 40;
	int total_cnt = countNonZero(edge_map);
	vector<VisualObject> query_patches;
	query_patches.reserve(total_cnt);

	cout<<"Start match..."<<endl;
	
	float max_dist = 0;
	int cnt = 0;
	char str[30];
	double start_t = getTickCount();
//#pragma omp parallel for
	for(int r=patch_size.height/2; r<gray_img.rows-patch_size.height/2; r+=3) {
		for(int c=patch_size.width/2; c<gray_img.cols-patch_size.width/2; c+=3) {

			/*int rand_r = rand()%gray_img.rows;
			int rand_c = rand()%gray_img.cols;
			if(rand_r < patch_size.height/2 || rand_r > gray_img.rows-patch_size.height/2 ||
				rand_c < patch_size.width/2 || rand_c > gray_img.cols-patch_size.width/2) continue;*/
			int rand_r = r, rand_c = c;

			if(edge_map.at<uchar>(rand_r, rand_c) > 0) 
			{
				cnt++;
				destroyAllWindows();

				Rect box(rand_c-patch_size.width/2, rand_r-patch_size.height/2, patch_size.width, patch_size.height);
				MatFeatureSet featset;
				gray_img_float(box).copyTo(featset["gray"]);
				//grad_mag(box).copyTo(featset["gradient"]);
				if(use_depth)
				{ 
					normal_map(box).copyTo(featset["normal"]);
					dmap_float(box).copyTo(featset["depth"]);
				}
				ComputePatchFeat(featset, feat);
				vector<DMatch> matches;
				if(use_code) 
				{
					BinaryCodes codes;
					HashKey key_val;
					lsh_coder.ComputeCodes(feat, codes);
					HashingTools<HashKeyType>::CodesToKey(codes, key_val);
					MatchCode(key_val, topK, matches);
				}
				else
				{
					MatchPatch(feat, topK, matches);
				}
				
				if(matches[0].distance < 0 || matches[0].distance > 1000) {
					cout<<"match dist: "<<matches[0].distance<<endl;
					double minv, maxv;
					cout<<norm(feat, patch_data.row(matches[0].trainIdx), NORM_L2)<<endl;
					minMaxLoc(feat, &minv, &maxv);
					cout<<minv<<" "<<maxv<<endl;
					cout<<feat<<endl<<endl;
					minMaxLoc(patch_data.row(matches[0].trainIdx), &minv, &maxv);
					cout<<minv<<" "<<maxv<<endl;
					cout<<patch_data.row(matches[0].trainIdx)<<endl;
					imshow("cimg", cimg);
					waitKey(0);
				}
				vector<vector<Mat>> pixel_mask_vals(patch_size.height, vector<Mat>(patch_size.width, Mat::zeros(1, topK, CV_32F)));
				VisualObject cur_query;
				cur_query.visual_data.bbox = box;
				cur_query.visual_data.mask = Mat::zeros(patch_size.height, patch_size.width, CV_32F);
				for(size_t i=0; i<topK; i++) { 
					score_map.at<float>(rand_r,rand_c) += matches[i].distance;
					cur_query.visual_data.mask += patch_meta.objects[matches[i].trainIdx].visual_data.mask;
					for(int mr=0; mr<patch_size.height; mr++) for(int mc=0; mc<patch_size.width; mc++) {
						pixel_mask_vals[mr][mc].at<float>(i) = 
							patch_meta.objects[matches[i].trainIdx].visual_data.mask.at<float>(mr, mc);
					}
				}
				score_map.at<float>(rand_r,rand_c) /= topK;
				cur_query.visual_data.mask /= topK;			// average returned mask
				
				// compute mask quality
				Scalar mean_, std_;
				/*ofstream out("pixel_mask_std_100.txt", ios::app);
				for(int mr=0; mr<patch_size.height; mr++) for(int mc=0; mc<patch_size.width; mc++) {
				meanStdDev(pixel_mask_vals[mr][mc], mean_, std_);
				out<<std_.val[0]<<" ";
				}
				out<<endl;*/
				meanStdDev(cur_query.visual_data.mask, mean_, std_);
				cur_query.visual_data.scores.push_back(mean_.val[0]);
				cur_query.visual_data.scores.push_back(std_.val[0]);

				Mat align_mask = Mat::zeros(cimg.rows, cimg.cols, CV_8U);
				int gt_mask_id = patch_meta.objects[matches[0].trainIdx].meta_data.category_id;
				if(gt_mask_id != -1) {
					Mat nn_mask = gt_obj_masks[gt_mask_id];
					//imshow("gt mask", nn_mask*255);
					//waitKey(10);
					Rect gt_box = patch_meta.objects[matches[0].trainIdx].visual_data.bbox;
					Rect align_box = AlignBox(box, gt_box, cimg.cols, cimg.rows);
					vector<ImgWin> boxes; boxes.push_back(align_box);
					//ImgVisualizer::DrawWinsOnImg("alignbox", cimg, boxes);
					//waitKey(10);
					Rect target_box = Rect(box.x-(gt_box.x-align_box.x), box.y-(gt_box.y-align_box.y), align_box.width, align_box.height);
					cout<<target_box<<endl;
					nn_mask(align_box).copyTo(align_mask(target_box));
				}
				align_mask.convertTo(align_mask, CV_32F);
				mask_map += align_mask * matches[0].distance;	//*score_map.at<float>(r,c);
				//mask_count(box) = mask_count(box) + 1;

				//cout<<score_map.at<float>(r,c)<<endl;
				max_dist = MAX(max_dist, matches[0].distance);
				query_patches.push_back(cur_query);

				// vote object regions
				/*Point3f line_ori;
				int obj_pt_sign;
				ComputeDominantLine(cur_query.visual_desc.mask, box.tl(), line_ori, obj_pt_sign);
				for(int rr=0; rr<cimg.rows; rr++) for(int cc=0; cc<cimg.cols; cc++) {
				float line_val = line_ori.x*cc+line_ori.y*rr+line_ori.z;
				if((line_val>0?1:-1)==obj_pt_sign) mask_vote_map.at<float>(rr, cc)++;
				}*/

#ifdef VERBOSE

				// current patch
				Mat disp, patch_gray, patch_grad, patch_normal, patch_depth;
				disp = cimg.clone();
				rectangle(disp, box, CV_RGB(255,0,0), 2);
				resize(gray_img(box), patch_gray, Size(50,50));
				resize(grad_mag(box), patch_grad, Size(50,50));
				Mat cur_mask;
				resize(cur_query.visual_desc.mask, cur_mask, Size(50,50));
				if(use_depth) 
				{
					resize(normal_map(box), patch_normal, Size(50,50));

					normalize(dmap_float(box), patch_depth, 1, 0, NORM_MINMAX);
					patch_depth.convertTo(patch_depth, CV_8U, 255);
					//dmap_float(box).convertTo(patch_depth, CV_8U, 255);
					resize(patch_depth, patch_depth, Size(50,50));
				}

				Mat onormal;
				sprintf_s(str, "query_gray_%d.jpg", cnt);
				imshow(str, patch_gray);
				imwrite(str, patch_gray);

				/*sprintf_s(str, "query_grad_%d.jpg", cnt);
				ImgVisualizer::DrawFloatImg(str, patch_grad, onormal, true);
				imwrite(str, onormal);*/
				
				sprintf_s(str, "query_depth_%d.jpg", cnt);
				imshow(str, patch_depth);
				imwrite(str, patch_depth);
				
				sprintf_s(str, "query_normal_%d.jpg", cnt);
				ImgVisualizer::DrawNormals(str, patch_normal, onormal, true);
				imwrite(str, onormal);

				sprintf_s(str, "query_box_%d.jpg", cnt);
				imshow(str, disp);
				imwrite(str, disp);

				//imshow("align mask", align_mask*255);

				cur_mask.convertTo(cur_mask, CV_8U, 255);
				sprintf_s(str, "query_tmask_%d.jpg", cnt);
				imshow(str, cur_mask);
				imwrite(str, cur_mask);

				// show match results
				vector<Mat> res_imgs(topK);
				vector<Mat> res_gradients(topK);
				vector<Mat> res_normals(topK);
				vector<Mat> res_depth(topK);
				vector<Mat> db_boxes(topK);
				vector<Mat> res_masks(topK);
				for(size_t i=0; i<topK; i++) {
					VisualObject& cur_obj = patch_meta.objects[matches[i].trainIdx];
					// mask
					cur_obj.visual_desc.mask.convertTo(res_masks[i], CV_8U, 255);
					// gray
					cur_obj.visual_desc.extra_features["gray"].convertTo(res_imgs[i], CV_8U, 255);
					// gradient
					//ImgVisualizer::DrawFloatImg("", cur_obj.visual_desc.extra_features["gradient"], res_gradients[i], false);
					// 3D
					if(use_depth) 
					{
						// normal
						tools::ImgVisualizer::DrawNormals("", cur_obj.visual_desc.extra_features["normal"], res_normals[i]);
						// depth
						normalize(cur_obj.visual_desc.extra_features["depth"], res_depth[i], 1, 0, NORM_MINMAX);
						res_depth[i].convertTo(res_depth[i], CV_8U, 255);
						//cur_obj.visual_desc.extra_features["depth"].convertTo(res_depth[i], CV_8U, 255);
					}
					// box on image
					db_boxes[i] = imread(patch_meta.objects[matches[i].trainIdx].imgpath);
					resize(db_boxes[i], db_boxes[i], Size(cimg.cols, cimg.rows));
					rectangle(db_boxes[i], patch_meta.objects[matches[i].trainIdx].visual_desc.box, CV_RGB(255,0,0), 2);
				}
				Mat out_img;
				sprintf_s(str, "res_gray_%d.jpg", cnt);
				ImgVisualizer::DrawImgCollection(str, res_imgs, topK, Size(50,50), out_img);
				imwrite(str, out_img);
				
				sprintf_s(str, "res_normal_%d.jpg", cnt);
				ImgVisualizer::DrawImgCollection(str, res_normals, topK, Size(50,50), out_img);
				imwrite(str, out_img);

				sprintf_s(str, "res_depth_%d.jpg", cnt);
				ImgVisualizer::DrawImgCollection(str, res_depth, topK, Size(50,50), out_img);
				imwrite(str, out_img);

				/*sprintf_s(str, "res_gradient_%d.jpg", cnt);
				tools::ImgVisualizer::DrawImgCollection(str, res_gradients, topK, Size(50,50), out_img);
				imwrite(str, out_img);*/

				sprintf_s(str, "res_mask_%d.jpg", cnt);
				tools::ImgVisualizer::DrawImgCollection(str, res_masks, topK, Size(50,50), out_img);
				imwrite(str, out_img);

				sprintf_s(str, "res_box_%d.jpg", cnt);
				tools::ImgVisualizer::DrawImgCollection(str, db_boxes, topK/2, Size(200, 200), out_img);
				imwrite(str, out_img);

				waitKey(0);
#endif

				cout<<total_cnt--<<endl;
			}
		}
	}
	cout<<"match done. Time cost: "<<(getTickCount()-start_t)/getTickFrequency()<<"s."<<endl;

	//score_map(Rect(patch_size.width/2, patch_size.height/2, score_map.cols-patch_size.width/2, score_map.rows-patch_size.height/2)).copyTo(score_map);
	//score_map.setTo(max_dist, 255-edge_map);
	normalize(score_map, score_map, 1, 0, NORM_MINMAX);
	score_map = 1-score_map;
	//tools::ImgVisualizer::DrawFloatImg("bmap", score_map);

	mask_map /= max_dist;
	cout<<max_dist<<endl;
	normalize(mask_map, mask_map, 1, 0, NORM_MINMAX);
	//tools::ImgVisualizer::DrawFloatImg("maskmap", mask_map);

	//normalize(mask_vote_map, mask_vote_map, 1, 0, NORM_MINMAX);
	//ImgVisualizer::DrawFloatImg("vote map", mask_vote_map);
	//waitKey(0);

	return true;

	// pick top weighted points to see if they are inside objects
	// try graph-cut for region proposal
	// among all retrieved mask patch, select most discriminative one and do graph-cut
	sort(query_patches.begin(), query_patches.end(), [](const VisualObject& a, const VisualObject& b) { 
		return a.visual_data.scores[1] > b.visual_data.scores[1]; });
	for(size_t i=0; i<query_patches.size(); i++) {
		Mat disp_img = cimg.clone();
		rectangle(disp_img, query_patches[i].visual_data.bbox, CV_RGB(255,0,0));
		imshow("max std box", disp_img);
		Mat big_mask;
		resize(query_patches[i].visual_data.mask, big_mask, Size(50,50));
		ImgVisualizer::DrawFloatImg("max std mask", big_mask);
		waitKey(0);
		// use mask to do graph-cut
		Mat fg_mask(cimg.rows, cimg.cols, CV_8U);
		fg_mask.setTo(cv::GC_PR_FGD);
		Mat th_mask;
		threshold(query_patches[i].visual_data.mask, th_mask, query_patches[i].visual_data.scores[0], 1, CV_THRESH_BINARY);
		th_mask.convertTo(th_mask, CV_8U);
		fg_mask(query_patches[i].visual_data.bbox).setTo(cv::GC_FGD, th_mask);
		th_mask = 1-th_mask;
		fg_mask(query_patches[i].visual_data.bbox).setTo(cv::GC_BGD, th_mask);
		cv::grabCut(cimg, fg_mask, Rect(0,0,1,1), Mat(), Mat(), 3, cv::GC_INIT_WITH_MASK);
		fg_mask = fg_mask & 1;
		disp_img.setTo(Vec3b(0,0,0));
		cimg.copyTo(disp_img, fg_mask);
		cv::imshow("cut", disp_img);
		cv::waitKey(0);
	}


	float ths[] = {0.9f, 0.8f, 0.7f, 0.6f, 0.5f, 0.4f, 0.3f, 0.2f};
	for(size_t i=0; i<8; i++) {
		Mat th_mask;
		threshold(mask_map, th_mask, ths[i], 1, CV_THRESH_BINARY);
		char str[30];
		sprintf_s(str, "%f", ths[i]);
		ImgVisualizer::DrawFloatImg(str, th_mask);
		waitKey(0);
	}

	return true;
}
void cv::goodFeaturesToTrack( InputArray _image, OutputArray _corners,
                              int maxCorners, double qualityLevel, double minDistance,
                              InputArray _mask, int blockSize,
                              bool useHarrisDetector, double harrisK )
{
    Mat image = _image.getMat(), mask = _mask.getMat();
    
    CV_Assert( qualityLevel > 0 && minDistance >= 0 && maxCorners >= 0 );
    CV_Assert( mask.empty() || (mask.type() == CV_8UC1 && mask.size() == image.size()) );

    Mat eig, tmp;
    if( useHarrisDetector )
        cornerHarris( image, eig, blockSize, 3, harrisK );
    else
        cornerMinEigenVal( image, eig, blockSize, 3 );

    double maxVal = 0;
    minMaxLoc( eig, 0, &maxVal, 0, 0, mask );
    threshold( eig, eig, maxVal*qualityLevel, 0, THRESH_TOZERO );
    dilate( eig, tmp, Mat());

    Size imgsize = image.size();

    vector<const float*> tmpCorners;

    // collect list of pointers to features - put them into temporary image
    for( int y = 1; y < imgsize.height - 1; y++ )
    {
        const float* eig_data = (const float*)eig.ptr(y);
        const float* tmp_data = (const float*)tmp.ptr(y);
        const uchar* mask_data = mask.data ? mask.ptr(y) : 0;

        for( int x = 1; x < imgsize.width - 1; x++ )
        {
            float val = eig_data[x];
            if( val != 0 && val == tmp_data[x] && (!mask_data || mask_data[x]) )
                tmpCorners.push_back(eig_data + x);
        }
    }

    sort( tmpCorners, greaterThanPtr<float>() );
    vector<Point2f> corners;
    size_t i, j, total = tmpCorners.size(), ncorners = 0;

    if(minDistance >= 1)
    {
         // Partition the image into larger grids
        int w = image.cols;
        int h = image.rows;

        const int cell_size = cvRound(minDistance);
        const int grid_width = (w + cell_size - 1) / cell_size;
        const int grid_height = (h + cell_size - 1) / cell_size;

        std::vector<std::vector<Point2f> > grid(grid_width*grid_height);

        minDistance *= minDistance;

        for( i = 0; i < total; i++ )
        {
            int ofs = (int)((const uchar*)tmpCorners[i] - eig.data);
            int y = (int)(ofs / eig.step);
            int x = (int)((ofs - y*eig.step)/sizeof(float));

	        bool good = true;

            int x_cell = x / cell_size;
            int y_cell = y / cell_size;

            int x1 = x_cell - 1;
            int y1 = y_cell - 1;
            int x2 = x_cell + 1;
            int y2 = y_cell + 1;

            // boundary check
            x1 = std::max(0, x1);
            y1 = std::max(0, y1);
            x2 = std::min(grid_width-1, x2);
            y2 = std::min(grid_height-1, y2);

            for( int yy = y1; yy <= y2; yy++ )
            {
                for( int xx = x1; xx <= x2; xx++ )
                {   
                    vector <Point2f> &m = grid[yy*grid_width + xx];

                    if( m.size() )
                    {
                        for(j = 0; j < m.size(); j++)
                        {
                            float dx = x - m[j].x;
                            float dy = y - m[j].y;

                            if( dx*dx + dy*dy < minDistance )
                            {
                                good = false;
                                goto break_out;
                            }
                        }
                    }                
                }
            }

            break_out:

            if(good)
            {
                // printf("%d: %d %d -> %d %d, %d, %d -- %d %d %d %d, %d %d, c=%d\n",
                //    i,x, y, x_cell, y_cell, (int)minDistance, cell_size,x1,y1,x2,y2, grid_width,grid_height,c);
                grid[y_cell*grid_width + x_cell].push_back(Point2f((float)x, (float)y));

                corners.push_back(Point2f((float)x, (float)y));
                ++ncorners;

                if( maxCorners > 0 && (int)ncorners == maxCorners )
                    break;
            }
        }
    }
    else
    {
        for( i = 0; i < total; i++ )
        {
            int ofs = (int)((const uchar*)tmpCorners[i] - eig.data);
            int y = (int)(ofs / eig.step);
            int x = (int)((ofs - y*eig.step)/sizeof(float));

            corners.push_back(Point2f((float)x, (float)y));
            ++ncorners;
            if( maxCorners > 0 && (int)ncorners == maxCorners )
                break;
        }
    }
    
    Mat(corners).convertTo(_corners, _corners.fixedType() ? _corners.type() : CV_32F);

    /*
    for( i = 0; i < total; i++ )
    {
        int ofs = (int)((const uchar*)tmpCorners[i] - eig.data);
        int y = (int)(ofs / eig.step);
        int x = (int)((ofs - y*eig.step)/sizeof(float));

        if( minDistance > 0 )
        {
            for( j = 0; j < ncorners; j++ )
            {
                float dx = x - corners[j].x;
                float dy = y - corners[j].y;
                if( dx*dx + dy*dy < minDistance )
                    break;
            }
            if( j < ncorners )
                continue;
        }

        corners.push_back(Point2f((float)x, (float)y));
        ++ncorners;
        if( maxCorners > 0 && (int)ncorners == maxCorners )
            break;
    }
*/
}
示例#11
0
	bool CameraGigeSdkIc::grabSingleImage(Frame &frame, int camID){

		// Retrieve a list with the video capture devices connected to the computer.
		DShowLib::Grabber::tVidCapDevListPtr pVidCapDevList = m_pGrabber->getAvailableVideoCaptureDevices();
		
		if(pVidCapDevList == 0 || pVidCapDevList->empty()){

			cout << "No device available." << endl;
			return false;

		}else{

			// Print available devices.
			int numCam = -1;
			for(int i = 0; i < pVidCapDevList->size(); i++){
				
				cout << "(" << i << ") " << pVidCapDevList->at(i).c_str() << endl;

				if(camID == i){
					numCam = i; 
					break;
				}

			}

			if(numCam == -1){

				return false;

			}else{

				// Open the selected video capture device.
				m_pGrabber->openDev(pVidCapDevList->at(numCam));

				/*cout << "Available video formats : " << endl;

				DShowLib::Grabber::tVidFmtDescListPtr DecriptionList;

				DecriptionList = m_pGrabber->getAvailableVideoFormatDescs();

				for( DShowLib::Grabber::tVidFmtDescList::iterator pDescription = DecriptionList->begin(); pDescription != DecriptionList->end(); pDescription++ )
				{
					printf("%s\n", (*pDescription)->toString().c_str());
				}*/
				
				DShowLib::tFrameHandlerSinkPtr pSink;

				cout << "Current bits per pixel : " << m_pGrabber->getVideoFormat().getBitsPerPixel() << endl;

				

				switch(frame.getBitDepth()){
					
					case MONO_8 :

						m_pGrabber->setVideoFormat("Y8 (1280x960-1280x960)");

						// Set the image buffer format to eY800. eY800 means monochrome, 8 bits (1 byte) per pixel.
						// Let the sink create a matching MemBufferCollection with 1 buffer.
						pSink = DShowLib::FrameHandlerSink::create( DShowLib::eY800, 1 );

						break;

					case MONO_12 :
						
						m_pGrabber->setVideoFormat("Y16 (1280x960-1280x960)");

						// Disable overlay.
						// http://www.theimagingsourceforums.com/archive/index.php/t-319880.html
						m_pGrabber->setOverlayBitmapPathPosition(DShowLib::ePP_NONE);

						// Set the image buffer format to eY16. eY16 means monochrome, 16 bits (2 byte) per pixel.
						// Let the sink create a matching MemBufferCollection with 1 buffer.
						pSink = DShowLib::FrameHandlerSink::create( DShowLib::eY16, 1 );

						break;
						
					default:
												
						return false;

						break;
				}

				cout << "New video format : " << m_pGrabber->getVideoFormat().getBitsPerPixel() << endl;
 
				// Get properties.
				_DSHOWLIB_NAMESPACE::tIVCDPropertyItemsPtr pItems = m_pGrabber->getAvailableVCDProperties();

				// Set Exposure time.
				int exposure = frame.getExposure();
								
				long eMin  = getPropertyRangeMin(DShowLib::VCDID_Exposure, pItems);
				long eMax  = getPropertyRangeMax(DShowLib::VCDID_Exposure, pItems);
				long e = getPropertyValue(DShowLib::VCDID_Exposure, pItems);

				cout << "Previous exposure time value : " << e << endl;

				if(exposure <= eMax && exposure >= eMin){

					setPropertyValue(DShowLib::VCDID_Exposure, (long)exposure, pItems);
					cout << "New exposure time value : " << getPropertyValue(DShowLib::VCDID_Exposure, pItems) << endl;

				}else{

					cout << "Fail to set exposure. Available range value is " << eMin << " to " << eMax << endl;
					return false;
				}

				// Set Gain (db)
				int gain = frame.getGain();
								
				long gMin  = getPropertyRangeMin(DShowLib::VCDID_Gain, pItems);
				long gMax  = getPropertyRangeMax(DShowLib::VCDID_Gain, pItems);
				long g = getPropertyValue(DShowLib::VCDID_Gain, pItems);

				cout << "Previous gain value : " << g << endl;

				if(gain <= gMax && gain >= gMin){

					setPropertyValue(DShowLib::VCDID_Gain, (long)gain, pItems);
					cout << "New gain value : " << getPropertyValue(DShowLib::VCDID_Gain, pItems) << endl;

				}else{

					cout << "Fail to set gain. Available range value is " << gMin << " to " << gMax << endl;
					return false;
				}

				
				// Set the sink.
				m_pGrabber->setSinkType(pSink);
				
				// We use snap mode.
				pSink->setSnapMode(true);

		

				// Prepare the live mode, to get the output size if the sink.
				if(!m_pGrabber->prepareLive(false)){

					std::cerr << "Could not render the VideoFormat into a eY800 sink.";
					return false;
				}

				// Retrieve the output type and dimension of the handler sink.
				// The dimension of the sink could be different from the VideoFormat, when
				// you use filters.
				DShowLib::FrameTypeInfo info;
				pSink->getOutputFrameType(info);
				cout << info.getBitsPerPixel() << endl;

				Mat newImg;
				DShowLib::Grabber::tMemBufferCollectionPtr pCollection;

				switch(info.getBitsPerPixel()){
					
					case 8 :

						{

							newImg = Mat(info.dim.cy, info.dim.cx, CV_8UC1, Scalar(0));
							BYTE* pBuf[1];
							// Allocate image buffers of the above calculate buffer size.
							pBuf[0] = new BYTE[info.buffersize];

							// Create a new MemBuffer collection that uses our own image buffers.
							pCollection = DShowLib::MemBufferCollection::create( info, 1, pBuf );
							if( pCollection == 0 || !pSink->setMemBufferCollection(pCollection)){

								std::cerr << "Could not set the new MemBufferCollection, because types do not match.";
								return false;

							}

							m_pGrabber->startLive(false);

							pSink->snapImages(1);
					
							memcpy(newImg.ptr(), pBuf[0], info.buffersize);

						}

						break;

					case 16 :

						{

							newImg = Mat(info.dim.cy, info.dim.cx, CV_16UC1, Scalar(0));
							BYTE * pBuf[1];
							// Allocate image buffers of the above calculate buffer size.
							pBuf[0] = new BYTE[info.buffersize];

							// Create a new MemBuffer collection that uses our own image buffers.
							pCollection = DShowLib::MemBufferCollection::create(info, 1, pBuf);
							if(pCollection == 0 || !pSink->setMemBufferCollection(pCollection)){

								std::cerr << "Could not set the new MemBufferCollection, because types do not match.";
								return false;

							}

							m_pGrabber->startLive(false);

							pSink->snapImages(1);

							memcpy(newImg.ptr(), pBuf[0], info.buffersize);

						}

						break;
						
					default:
												
						return false;

						break;
				}

				m_pGrabber->stopLive();

				m_pGrabber->closeDev();

				//Timestamping.
				string acquisitionDate = TimeDate::localDateTime(microsec_clock::universal_time(),"%Y:%m:%d:%H:%M:%S");
				boost::posix_time::ptime time = boost::posix_time::microsec_clock::universal_time();
				string acqDateInMicrosec = to_iso_extended_string(time);

                frame = Frame(newImg, 0, 0, acquisitionDate);
                frame.setAcqDateMicro(acqDateInMicrosec);
                frame.setFPS(0);

				//cout << "save " << endl;
				//pCollection->save( "yio*.bmp" );

				double minVal, maxVal;
				minMaxLoc(newImg, &minVal, &maxVal);

				cout << "minVal :" << minVal << endl;
				cout << "maxVal :" << maxVal << endl;
				
				unsigned short * ptr;

				double t = (double)getTickCount();

				for(int i = 0; i < newImg.rows; i++){

					ptr = newImg.ptr<unsigned short>(i);

					for(int j = 0; j < newImg.cols; j++){

						ptr[j] = ptr[j] >> 4;

					}
				}	

				t = (((double)getTickCount() - t )/getTickFrequency())*1000;

				cout << "time decalage : " << t << endl;
				
				minMaxLoc(newImg, &minVal, &maxVal);

				cout << "minVal :" << minVal << endl;
				cout << "maxVal :" << maxVal << endl;

			}
		}

		return true;
	}
示例#12
0
文件: dip4.cpp 项目: hoijui/DIP
static Mat inverseAndWiener(Mat& s, Mat& p, double snr, bool inverse) {

	const bool wiener = !inverse;

	// Pad input image to avoid ringing artifacts along image borders.
	int bH = p.cols;
	int bV = p.rows;
	Mat sBorder;
	copyMakeBorder(s, sBorder, bV, bV, bH, bH, BORDER_REPLICATE);

	// Allocate some memory like it is going out of style.
	Mat pBigShifted = Mat::zeros(sBorder.size(), CV_32F);
	Mat P = Mat::zeros(sBorder.size(), CV_32F);
	Mat S = Mat::zeros(sBorder.size(), CV_32F);
	Mat OApprox = Mat::zeros(sBorder.size(), CV_32F);
	Mat oApprox = Mat::zeros(sBorder.size(), CV_32F);

	// Shift kernel.
	const int pHalf = p.rows / 2;
	circShiftXXX(p, pBigShifted, -pHalf, -pHalf);

	// Transform shifted kernel and degrated input image into frequency domain.
	// Note: DFT_COMPLEX_OUTPUT means that we want the complex result to be stored
	//       in a two-channel matrix as opposed to the default compressed output.
	dft(pBigShifted, P, DFT_COMPLEX_OUTPUT);
	dft(sBorder, S, DFT_COMPLEX_OUTPUT);

	if (inverse) {
		const double epsilon = 0.05f;

		// Remove frequencies whose magnitude is below epsilon * max(freqKernel magnitude).
		double maxMagnitude;
		minMaxLoc(abs(P), 0, &maxMagnitude);

		const double threshold =  maxMagnitude * epsilon;
		for (int ri = 0; ri < P.rows; ri++) {
			for (int ci = 0; ci < P.cols; ci++) {
				if (norm(P.at<Vec2f>(ri, ci)) < threshold) {
					P.at<Vec2f>(ri, ci) = threshold;
				}
			}
		}
	}

	// OpenCV only provides a multiplication operation for complex matrices, so we need
	// to calculate the inverse (1/H) of our filter spectrum first. Since it is complex
	// we need to compute 1/H = H*/(HH*) = H*/(Re(H)^2+Im(H)^2), where H* -> complex conjugate of H.

	// Multiply spectrum of the degrated image with the complex conjugate of the frequency spectrum
	// of the filter.
	const bool conjFreqKernel = true;
	mulSpectrums(S, P, OApprox, DFT_COMPLEX_OUTPUT, conjFreqKernel); // I * H*

	// Split kernel spectrum into real and imaginary parts.
	Mat PChannels[] = {Mat::zeros(sBorder.size(), CV_32F), Mat::zeros(sBorder.size(), CV_32F)};
	split(P, PChannels); // 0:real, 1:imaginary

	// Calculate squared magnitude (Re(H)^2 + Im(H)^2) of filter spectrum.
	Mat freqKernelSqMagnitude = Mat::zeros(sBorder.rows, sBorder.cols, CV_32F);
	magnitude(PChannels[0], PChannels[1], freqKernelSqMagnitude); // freqKernelSqMagnitude = magnitude
	pow(PChannels[0], 2, freqKernelSqMagnitude); // freqKernelSqMagnitude = magnitude^2 = Re(H)^2 + Im(H)^2

	if (wiener) {
		// Add 1 / SNR^2 to the squared filter kernel magnitude.
		freqKernelSqMagnitude += 1 / pow(snr, 2.0);
	}

	// Split frequency spectrum of degradedPadded image into real and imaginary parts.
	Mat OApproxChannels[] = {Mat::zeros(sBorder.size(), CV_32FC1), Mat::zeros(sBorder.size(), CV_32F)};
	split(OApprox, OApproxChannels);

	// Divide each plane by the squared magnitude of the kernel frequency spectrum.
	// What we have done up to this point: (I * H*) / (Re(H)^2 + Im(H)^2) = I/H
	divide(OApproxChannels[0], freqKernelSqMagnitude, OApproxChannels[0]); // Re(I) / (Re(H)^2 + Im(H)^2)
	divide(OApproxChannels[1], freqKernelSqMagnitude, OApproxChannels[1]); // Im(I) / (Re(H)^2 + Im(H)^2)

	// Merge real and imaginary parts of the image frequency spectrum.
	merge(OApproxChannels, 2, OApprox);

	// Inverse DFT.
	// Note: DFT_REAL_OUTPUT means that we want the output to be a one-channel matrix again.
	dft(OApprox, oApprox, DFT_INVERSE | DFT_SCALE | DFT_REAL_OUTPUT);

	// Crop output image to original size.
	oApprox = oApprox(Rect(bH, bV, oApprox.cols - (bH * 2), oApprox.rows - (bV * 2)));

	return oApprox;
}
示例#13
0
/** @function doHarris */
int Panorama::doHarris()
{

    Mat R; Mat Rtemp; // Corner Response function
    Mat Ix, Iy, Ixy, Ix2, Iy2; // the second moment eigenvalues function
    
    double maxValtemp, minValtemp;
    double minVal; double maxVal; 
    int sigma = 3; // Gaussian sigma
    float k = 0.04; // the alpha of Response function
    int aperture_size =3, block_size = 3; double scale =  1.0; // parameters of sobel first order derivative.
    char* window = "Harris."; // the name of Harris result

    /////////////////////////////////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////////////////////////
            
    cout << "Processing Harris Corner Detector..." << endl;
    /* Initialize the corner response function and the temp mat */
    R = Mat::zeros( srcGray.size(), CV_32FC1 );
    Rtemp = Mat::zeros( srcGray.size(), CV_32FC1 );
    
    /* Use Sobel function to calculate the first order derivative of both x and y */
    Sobel( srcGray, Ix, CV_32F, 1, 0, aperture_size, scale, 0, BORDER_DEFAULT );
    Sobel( srcGray, Iy, CV_32F, 0, 1, aperture_size, scale, 0, BORDER_DEFAULT );
    
    /* Calculate the Gaussian Derivative */
    GaussianBlur(Iy, Iy, Size(block_size, block_size), sigma, 0 ,BORDER_DEFAULT);
    GaussianBlur(Ix, Ix, Size(block_size, block_size), sigma, 0 ,BORDER_DEFAULT);
    
    /* Calculate the square of each intensity */
    pow(Ix,2,Ix2);
    pow(Iy,2,Iy2);
    
    /* Calculate the Gaussian Derivative */
    GaussianBlur(Iy2, Iy2, Size(block_size, block_size), sigma, 0 ,BORDER_DEFAULT);
    GaussianBlur(Ix2, Ix2, Size(block_size, block_size), sigma, 0 ,BORDER_DEFAULT);
    
    /* Calculate the Corner Response function */
    for( int j = 0; j < srcGray.rows; j++ )
    { for( int i = 0; i < srcGray.cols; i++ )
    {
        float lambda_1 = Ix2.at<float>( j, i, 0);
        float lambda_2 = Iy2.at<float>( j, i, 0);
        Rtemp.at<float>(j, i, 0) = lambda_1 * lambda_2 - k * pow( ( lambda_1 + lambda_2 ), 2 );
    }
    }
    
    minMaxLoc( Rtemp, &minValtemp, &maxValtemp, 0, 0, Mat() );
    
    /* Normalize Corner Response function as the maxium value is 1 */
    for( int j = 0; j < srcGray.rows; j++ )
    { for( int i = 0; i < srcGray.cols; i++ )
    {  
        R.at<float>(j, i) =  1 / maxValtemp * Rtemp.at<float>(j, i, 0);
    }
    }

    /* Find local maxima of response function (nonmaximum suppression)*/
    minMaxLoc( R, &minVal, &maxVal, 0, 0, Mat() );
    
    /* Create Window  */
    namedWindow( window, CV_WINDOW_AUTOSIZE );
    int currentLevel = 5;
    int maxLevel = 100;
    
    
    double threshold = ( maxVal - minVal ) * currentLevel/maxLevel ;
    
    for( int j = 0; j < srcGray.rows; j++ )
    { 
        for( int i = 0; i < srcGray.cols; i++ )
        {   
            if( R.at<float>(j,i) >  threshold)
            {
                circle( srcCopy, Point(i,j), 4, Scalar(255,255,255), 0, 0, 0 ); 
            
            }
        
        }
    }
    imshow( window, srcCopy );
    /*
    delete &minVal; delete &maxVal;
    delete &maxValtemp; delete &minValtemp; 
    delete &R; delete &Rtemp;
    delete &Ix; delete &Iy; delete &Ix2; delete &Iy2; delete &Ixy;
    */
    return(0);
}
示例#14
0
bool Scraper::FindAllBMPs(const searchType type, HBITMAP hBmp, const double threshold, const int maxMatch, vector<MATCHPOINTS> &matches)
{
    // Convert HBITMAP to Mat
    unique_ptr<Gdiplus::Bitmap> pBitmap;
    pBitmap.reset(Gdiplus::Bitmap::FromHBITMAP(hBmp, NULL));
    Mat img = CGdiPlus::CopyBmpToMat(pBitmap.get());
    pBitmap.reset();

    cvtColor( img, img, CV_BGRA2BGR );

    // Find right image group
    imageType iType =
        type==searchGoldStorage ? goldStorage :
        type==searchElixStorage ? elixStorage :
        type==searchDarkStorage ? darkStorage :
        type==searchLootCollector ? collector :
        type==searchLootBubble ? lootBubble :
        type==searchDonateButton ? donateButton : (imageType) 0;

    int iTypeIndex = -1;
    for (int i = 0; i < (int) imageGroups.size(); i++)
        if (imageGroups[i].iType == iType)
            iTypeIndex = i;
    if (iTypeIndex == -1)
        return false;

    // Scan through each Mat in this image group
    int count = 0;

    for (int i = 0; i < (int) imageGroups[iTypeIndex].mats.size(); i++)
    {
        // Get matches for this image
        Mat result( FindMatch(img, imageGroups[iTypeIndex].mats[i]) );

        // Parse through matches in result set
        while (count < maxMatch)
        {
            double minVal, maxVal;
            Point minLoc, maxLoc;
            minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc);

            // Fill haystack with pure green so we don't match this same location
            rectangle(img, maxLoc, cv::Point(maxLoc.x + imageGroups[iTypeIndex].mats[i].cols, maxLoc.y + imageGroups[iTypeIndex].mats[i].rows), CV_RGB(0,255,0), 2);

            // Fill results array with lo vals, so we don't match this same location
            floodFill(result, maxLoc, 0, 0, Scalar(0.1), Scalar(1.0));

            if (maxVal >= threshold && maxVal > 0)
            {
                // Check if this point is within 10 pixels of an existing match to avoid dupes
                bool alreadyFound = false;

                for (int k=0; k<count; k++)
                {
                    if (DistanceBetweenTwoPoints((double) maxLoc.x, (double) maxLoc.y, (double) matches.at(k).x, (double) matches.at(k).y) < 10.0)
                    {
                        alreadyFound = true;
                        break;
                    }
                }

                // Add matched location to the vector
                if (alreadyFound == false)
                {
                    MATCHPOINTS match;
                    match.val = maxVal;
                    match.x = maxLoc.x;
                    match.y = maxLoc.y;
                    matches.push_back(match);
                    count++;
                }
            }
            else
            {
                break;
            }
        }

        if (count >= maxMatch)
            break;
    }

    return true;
}
示例#15
0
void ImageProcessor::process(MultispectralImage frame)
{
	MultispectralImage frame8Bit;
	QList<imgDesc> results;

	quint8 i;

	Mat filterMask;
	Mat maskedFCImage;
	double maxVal = 0;
	double maxTemp = 0.0;

	Mat temp;
	double spread;

	Mat motionMask;

	errorOccurred = false;

	lockConfig.lockForRead();

	//main processing tasks
	//*********************

	//subtract dark image, if enabled
	if(myConfig.calibration.subtractDark && !frame.getDarkSubtracted())
	{
		for(i = 1; i < frame.getChannelCount(); i++)
		{
			//subtract dark image from current image
			Mat tmp;
			cv::subtract(frame.getImageByChannelNumber(i),
						 frame.getDarkImage(),
						 tmp);

			//set result as new channel image
			frame.setChannelImage(frame.getWavebands().at(i), tmp);
		}

		frame.setDarkSubtracted(true);
	}

	//perform skin detection by using quotient filters, if enabled
	if(myConfig.detectSkinByQuotient && (myConfig.quotientFilters.size() > 0))
	{
		//clear result list
		skinDetectionResults.clear();

		//signal processing of all filters
		emit doSkinDetection(frame);
	}

	//if image depth is more than 8bit, image has to be resampled to be displayed
	if(frame.getDepth() > 8)
	{
		//if automatic contrast is enabled, find the brightest spot in all channels
		if(myConfig.contrastAutomatic)
		{
			//iterate through all bands (except dark) to find maximum value
			for(i = 1; i < frame.getChannelCount(); i++)
			{
				minMaxLoc(frame.getImageByChannelNumber(i), NULL, &maxTemp);
				if ( maxTemp > maxVal )
				{
					maxVal = maxTemp;
				}
			}

			//subtract contrast dark offset from maximum
			maxVal -= myConfig.contrastOffset;

			//slowly increase or decrease contrast value
			if((maxVal / myConfig.contrastValue) < 220)
			{
				myConfig.contrastValue -= (myConfig.contrastValue - (maxVal / 255)) / 10;
			}
			else if((maxVal / myConfig.contrastValue) > 250)
			{
				myConfig.contrastValue += ((maxVal / 255) - myConfig.contrastValue) / 10;
			}
		}

		//calculate spread factor
		spread = 1.0 / (double)myConfig.contrastValue;

		//configure GUI image object
		frame8Bit.setSize(frame.getWidth(), frame.getHeight());
		frame8Bit.setDepth(8);

		//scale down every band
		for (i = 0; i < frame.getChannelCount(); i++)
		{
			//subtract contrast offset, if enabled
			Mat tempOffset;
			if(myConfig.contrastOffset > 0)
			{
				subtract(frame.getImageByChannelNumber(i),
						 Scalar(myConfig.contrastOffset),
						 tempOffset);
			}
			else
			{
				tempOffset = frame.getImageByChannelNumber(i);
			}

			//convert to 8 bit using spread factor
			tempOffset.convertTo(temp, 8, spread );
			frame8Bit.setChannelImage(frame.getWavebands().at(i), temp.clone());
		}
	}
	else
	{
		frame8Bit = frame;
	}

	//detect edges
	if(myConfig.edgeDetection)
	{
		QMapIterator<qint16, Mat> it(frame8Bit.getImages());
		while(it.hasNext())
		{
			it.next();

			Mat edges = doEdgeDetection(it.value(), myConfig.edgeThreshold);

			struct imgDesc edgeResult;
			edgeResult.desc = QString("Edges %1nm").arg(it.key());
			edgeResult.img = edges;
			results.append(edgeResult);
		}
	}

	//Estimate distance (in separate thread)
	if (myConfig.estimateDistance)
	{
		//make edge mask on selected image
		Mat edges;
		if(autoSelectCannyImage) //automatically select sharpest band image for edge detection
		{
			Canny(frame8Bit.getImageByChannelNumber(lastSharpestBand), edges, cannyLowThresh, cannyHighThresh);
		}
		else //use band image selected by the user (in GUI)
		{
			Canny(frame8Bit.getImageByChannelNumber(cannyImage), edges, cannyLowThresh, cannyHighThresh);
		}

		//emit signals to distance estimation thread
		distEstimationResults.clear();
		emit setDistEstimParams((int)myConfig.sharpMetric, edges, myConfig.sharpnessNbrhdSize, medianKernel);
		emit doDistanceEstimation(frame8Bit);

		//wait for thread to finish
		while (!errorOccurred && distEstimationResults.size() < 1) //frame8Bit.getChannelCount()-1)
		{
			QCoreApplication::processEvents();
		}
		if(errorOccurred)
		{
			emit errorProcessing(ImageSourceException("Error in task: estimateDistanceByChromAberr."));
			return;
		}

		//append distance estimation result to results in order to display them
		if(!distEstimationResults.empty())
		{
			//get 8 bit image from 1st list entry (at position 0)
			results.append(distEstimationResults.at(0));
		}
	}

	//wait for threads to finish:
	//***************************

	//wait until all threads are finished, get results and delete them

	if(myConfig.detectSkinByQuotient && (myConfig.quotientFilters.size() > 0))
	{
		maskedFCImage = Mat::zeros(frame8Bit.getDarkImage().rows,
								   frame8Bit.getDarkImage().cols, CV_8UC3);

		//wait until all threads are finished and get results
		while(!errorOccurred &&
			  (myConfig.quotientFilters.size() > skinDetectionResults.size()))
		{
			QCoreApplication::processEvents(QEventLoop::AllEvents);
		}
		if(errorOccurred)
		{
			emit errorProcessing(ImageSourceException("Error in task: detectSkinByQuotients."));
			return;
		}
		//multiply (cut) the filter masks
		filterMask = skinDetectionResults.at(0);
		for(i = 1; i < skinDetectionResults.size(); i++ )
		{
			multiply(filterMask, skinDetectionResults.at(i),
					 filterMask, 1.0);
		}

		//remove positive pixels with motion artifacts
		if(myConfig.suppressMotion && (lastFrame.getChannelCount() == frame.getChannelCount()))
		{
			motionMask = Mat::ones(maskedFCImage.rows, maskedFCImage.cols, CV_8UC1);

			for(i= 0; i < frame.getChannelCount(); i++)
			{
				Mat diffF, threshF, thresh;
				Mat curF, prevF;

				//get frame channels and convert to float
				frame.getImageByChannelNumber(i).convertTo(curF, CV_32F);
				lastFrame.getImageByChannelNumber(i).convertTo(prevF, CV_32F);

				//calculate absolute difference between current and previous frame
				absdiff(curF, prevF, diffF);

				//threshold the absolute difference
				threshold(diffF, threshF, myConfig.motionThreshold, 1.0, THRESH_BINARY_INV);

				//convert to 8 bit unsigned
				threshF.convertTo(thresh, CV_8U);

				//update motion mask with new thresholded difference mask
				multiply(motionMask, thresh, motionMask);
			}

			//now multiply motion mask with filter mask to remove positive filter results
			//where there was motion detected
			multiply(motionMask, filterMask, filterMask);

			//add motion mask to results
			struct imgDesc motionResult;
			motionResult.desc = "Motion";
			threshold(motionMask, motionResult.img, 0, 255, THRESH_BINARY_INV) ;
			results.append(motionResult);
		}

		//Morph result:
		if(myConfig.morphResult)
		{
			Mat element(4,4,CV_8U,Scalar(1));
			morphologyEx(filterMask, filterMask, MORPH_OPEN, element);
		}

		//set mask on top of (8bit) false colour image
		bitwise_or(maskedFCImage,
				   frame8Bit.getFalseColorImage(myConfig.falseColorChannels),
				   maskedFCImage, filterMask);

		if(myConfig.showMaskContours)
		{
			vector<vector<Point> > contours;
			CvScalar green = CV_RGB(0,255,0);
			//CvScalar blue = CV_RGB(0,0,255);

			findContours(filterMask, contours,
						 CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);

			drawContours(maskedFCImage, contours, -1, green, 2, 8);
		}

		struct imgDesc skinMask;
		struct imgDesc skinResult;

		skinMask.desc = "QF Mask";
		threshold(filterMask, skinMask.img, 0, 255, THRESH_BINARY) ;
		results.append(skinMask);

		skinResult.desc = "Masked FC Image";
		skinResult.img = maskedFCImage;
		results.append(skinResult);
	}

	lockConfig.unlock();

	emit finishedProcessing(frame, frame8Bit, results);

	lastFrame = frame;
}
示例#16
0
/******** STCTracker: calculate the confidence map and find the max position *******/
void STCTracker::tracking(const Mat frame, Rect &trackBox,Rect &boxRegion,int FrameNum)
{
	Mat gray;
	cvtColor(frame, gray, CV_RGB2GRAY);

	// normalized by subtracting the average intensity of that region
	Scalar average = mean(gray(cxtRegion));
	Mat context;
	gray(cxtRegion).convertTo(context, CV_64FC1, 1.0, - average[0]);

	// multiplies a Hamming window to reduce the frequency effect of image boundary
	context = context.mul(hammingWin);

	// step 1: Get context prior probability
	//cout<<"context "<<context.rows<<" "<<context.cols<<endl;
	getCxtPriorPosteriorModel(context);

	// step 2-1: Execute 2D DFT for prior probability
	Mat priorFourier;
	Mat planes1[] = {cxtPriorPro, Mat::zeros(cxtPriorPro.size(), CV_64F)};
    merge(planes1, 2, priorFourier);
	dft(priorFourier, priorFourier);

	// step 2-2: Execute 2D DFT for conditional probability
	Mat STCModelFourier;
	Mat planes2[] = {STCModel, Mat::zeros(STCModel.size(), CV_64F)};
    merge(planes2, 2, STCModelFourier);
	dft(STCModelFourier, STCModelFourier);

	// step 3: Calculate the multiplication
	Mat postFourier;
	complexOperation(STCModelFourier, priorFourier, postFourier, 0);

	// step 4: Execute 2D inverse DFT for posterior probability namely confidence map
	Mat confidenceMap;
	dft(postFourier, confidenceMap, DFT_INVERSE | DFT_REAL_OUTPUT| DFT_SCALE);

	// step 5: Find the max position
	Point point;
	double  maxVal;
	minMaxLoc(confidenceMap, 0, &maxVal, 0, &point);
	maxValue.push_back(maxVal);

		/***********update scale by Eq.(15)**********/
	if (FrameNum%(num+2)==0)
	{   
		double scale_curr=0.0;

		for (int k=0;k<num;k++)
		{
			scale_curr+=sqrt(maxValue[FrameNum-k-2]/maxValue[FrameNum-k-3]);
		}

		scale=(1-lambda)*scale+lambda*(scale_curr/num);

		sigma=sigma*scale;

	}
	// step 6-1: update center, trackBox and context region
	center.x = cxtRegion.x + point.x;
	center.y = cxtRegion.y + point.y;
	trackBox.x = center.x - 0.5 * trackBox.width;
	trackBox.y = center.y - 0.5 * trackBox.height;
	trackBox &= Rect(0, 0, frame.cols, frame.rows);
	//boundary
	cxtRegion.x = center.x - cxtRegion.width * 0.5;
	if (cxtRegion.x<0)
	{
		cxtRegion.x=0;
	}
	cxtRegion.y = center.y - cxtRegion.height * 0.5;
	if (cxtRegion.y<0)
	{
		cxtRegion.y=0;
	}
	if (cxtRegion.x+cxtRegion.width>frame.cols)
	{
		cxtRegion.x=frame.cols-cxtRegion.width;
	}
	if (cxtRegion.y+cxtRegion.height>frame.rows)
	{
		cxtRegion.y=frame.rows-cxtRegion.height;
	}
	
	
	//cout<<"cxtRegionXY"<<cxtRegion.x<<" "<<cxtRegion.y<<endl;
	//cout<<"cxtRegion"<<cxtRegion.height<<" "<<cxtRegion.width<<endl;
	//cout<<"frame"<<frame.rows<<" "<<frame.cols<<endl;

	//cxtRegion &= Rect(0, 0, frame.cols, frame.rows);
	//cout<<"cxtRegionXY"<<cxtRegion.x<<" "<<cxtRegion.y<<endl;
	//cout<<"cxtRegion"<<cxtRegion.height<<" "<<cxtRegion.width<<endl;

	
	boxRegion=cxtRegion;
	// step 7: learn Spatio-Temporal context model from this frame for tracking next frame
	average = mean(gray(cxtRegion));
	//cout<<"cxtRegion"<<cxtRegion.height<<" "<<cxtRegion.width<<endl;

	gray(cxtRegion).convertTo(context, CV_64FC1, 1.0, - average[0]);
	
	//cout<<"hamm"<<hammingWin.rows<<" "<<hammingWin.cols<<endl;

	context = context.mul(hammingWin);
	learnSTCModel(context);
}
/* Normalize values in vector between a and b. In-place. */
void normalize(vector<double>& vec, double a, double b) {
    double minv, maxv;
    minMaxLoc(vec, &minv, &maxv);
    transform(vec.begin(), vec.end(), vec.begin(),
              [=](double d){return a + ((d - minv) * (b - a)  / (maxv - minv));});
}
 void NiblackSauvolaWolfJolion (Mat &im, Mat &output, NiblackVersion version,
                                int winx, int winy, double k, double dR) {
     
     
     double m, s, max_s;
     double th=0;
     double min_I, max_I;
     int wxh	= winx/2;
     int wyh	= winy/2;
     int x_firstth= wxh;
     int x_lastth = im.cols-wxh-1;
     int y_lastth = im.rows-wyh-1;
     int y_firstth= wyh;
     
     // Create local statistics and store them in a double matrices
     Mat map_m = Mat::zeros (im.rows, im.cols, CV_32F);
     Mat map_s = Mat::zeros (im.rows, im.cols, CV_32F);
     max_s = calcLocalStats (im, map_m, map_s, winx, winy);
     
     minMaxLoc(im, &min_I, &max_I);
     
     Mat thsurf (im.rows, im.cols, CV_32F);
     
     // Create the threshold surface, including border processing
     // ----------------------------------------------------
     
     for	(int j = y_firstth ; j<=y_lastth; j++) {
         
         // NORMAL, NON-BORDER AREA IN THE MIDDLE OF THE WINDOW:
         for	(int i=0 ; i <= im.cols-winx; i++) {
             
             m  = map_m.fget(i+wxh, j);
             s  = map_s.fget(i+wxh, j);
             
             // Calculate the threshold
             switch (version) {
                     
                 case NIBLACK:
                     th = m + k*s;
                     break;
                     
                 case SAUVOLA:
                     th = m * (1 + k*(s/dR-1));
                     break;
                     
                 case WOLFJOLION:
                     th = m + k * (s/max_s-1) * (m-min_I);
                     break;
                     
                 default:
                     exit (1);
             }
             
             thsurf.fset(i+wxh,j,th);
             
             if (i==0) {
                 // LEFT BORDER
                 for (int i=0; i<=x_firstth; ++i)
                     thsurf.fset(i,j,th);
                 
                 // LEFT-UPPER CORNER
                 if (j==y_firstth)
                     for (int u=0; u<y_firstth; ++u)
                         for (int i=0; i<=x_firstth; ++i)
                             thsurf.fset(i,u,th);
                 
                 // LEFT-LOWER CORNER
                 if (j==y_lastth)
                     for (int u=y_lastth+1; u<im.rows; ++u)
                         for (int i=0; i<=x_firstth; ++i)
                             thsurf.fset(i,u,th);
             }
             
             // UPPER BORDER
             if (j==y_firstth)
                 for (int u=0; u<y_firstth; ++u)
                     thsurf.fset(i+wxh,u,th);
             
             // LOWER BORDER
             if (j==y_lastth)
                 for (int u=y_lastth+1; u<im.rows; ++u)
                     thsurf.fset(i+wxh,u,th);
         }
         
         // RIGHT BORDER
         for (int i=x_lastth; i<im.cols; ++i)
             thsurf.fset(i,j,th);
         
         // RIGHT-UPPER CORNER
         if (j==y_firstth)
             for (int u=0; u<y_firstth; ++u)
                 for (int i=x_lastth; i<im.cols; ++i)
                     thsurf.fset(i,u,th);
         
         // RIGHT-LOWER CORNER
         if (j==y_lastth)
             for (int u=y_lastth+1; u<im.rows; ++u)
                 for (int i=x_lastth; i<im.cols; ++i)
                     thsurf.fset(i,u,th);
     }
     
     for	(int y=0; y<im.rows; ++y)
         for	(int x=0; x<im.cols; ++x)
         {
             if (im.uget(x,y) >= thsurf.fget(x,y))
             {
                 output.uset(x,y,255);
             }
             else
             {
                 output.uset(x,y,0);
             }
         }
 }