Example #1
0
double calcLocalStats (Mat &im, Mat &map_m, Mat &map_s, int winx, int winy) {

	double m,s,max_s, sum, sum_sq, foo;
	int wxh	= winx/2;
	int wyh	= winy/2;
	int x_firstth= wxh;
	int y_lastth = im.rows-wyh-1;
	int y_firstth= wyh;
	double winarea = winx*winy;

	max_s = 0;
	for	(int j = y_firstth ; j<=y_lastth; j++)
	{
		// Calculate the initial window at the beginning of the line
		sum = sum_sq = 0;
		for	(int wy=0 ; wy<winy; wy++)
			for	(int wx=0 ; wx<winx; wx++) {
				foo = im.uget(wx,j-wyh+wy);
				sum    += foo;
				sum_sq += foo*foo;
			}
		m  = sum / winarea;
		s  = sqrt ((sum_sq - (sum*sum)/winarea)/winarea);
		if (s > max_s)
			max_s = s;
		map_m.fset(x_firstth, j, m);
		map_s.fset(x_firstth, j, s);

		// Shift the window, add and remove	new/old values to the histogram
		for	(int i=1 ; i <= im.cols-winx; i++) {

			// Remove the left old column and add the right new column
			for (int wy=0; wy<winy; ++wy) {
				foo = im.uget(i-1,j-wyh+wy);
				sum    -= foo;
				sum_sq -= foo*foo;
				foo = im.uget(i+winx-1,j-wyh+wy);
				sum    += foo;
				sum_sq += foo*foo;
			}
			m  = sum / winarea;
			s  = sqrt ((sum_sq - (sum*sum)/winarea)/winarea);
			if (s > max_s)
				max_s = s;
			map_m.fset(i+wxh, j, m);
			map_s.fset(i+wxh, j, s);
		}
	}

	return max_s;
}
double calcLocalStats (Mat &im, Mat &map_m, Mat &map_s, int winx, int winy) {    
    Mat im_sum, im_sum_sq;
    cv::integral(im,im_sum,im_sum_sq,CV_64F);

	double m,s,max_s,sum,sum_sq;	
	int wxh	= winx/2;
	int wyh	= winy/2;
	int x_firstth= wxh;
	int y_lastth = im.rows-wyh-1;
	int y_firstth= wyh;
	double winarea = winx*winy;

	max_s = 0;
	for	(int j = y_firstth ; j<=y_lastth; j++){   
		sum = sum_sq = 0;

        sum = im_sum.at<double>(j-wyh+winy,winx) - im_sum.at<double>(j-wyh,winx) - im_sum.at<double>(j-wyh+winy,0) + im_sum.at<double>(j-wyh,0);
        sum_sq = im_sum_sq.at<double>(j-wyh+winy,winx) - im_sum_sq.at<double>(j-wyh,winx) - im_sum_sq.at<double>(j-wyh+winy,0) + im_sum_sq.at<double>(j-wyh,0);

		m  = sum / winarea;
		s  = sqrt ((sum_sq - m*sum)/winarea);
		if (s > max_s) max_s = s;

		map_m.fset(x_firstth, j, m);
		map_s.fset(x_firstth, j, s);

		// Shift the window, add and remove	new/old values to the histogram
		for	(int i=1 ; i <= im.cols-winx; i++) {

			// Remove the left old column and add the right new column
			sum -= im_sum.at<double>(j-wyh+winy,i) - im_sum.at<double>(j-wyh,i) - im_sum.at<double>(j-wyh+winy,i-1) + im_sum.at<double>(j-wyh,i-1);
			sum += im_sum.at<double>(j-wyh+winy,i+winx) - im_sum.at<double>(j-wyh,i+winx) - im_sum.at<double>(j-wyh+winy,i+winx-1) + im_sum.at<double>(j-wyh,i+winx-1);

			sum_sq -= im_sum_sq.at<double>(j-wyh+winy,i) - im_sum_sq.at<double>(j-wyh,i) - im_sum_sq.at<double>(j-wyh+winy,i-1) + im_sum_sq.at<double>(j-wyh,i-1);
			sum_sq += im_sum_sq.at<double>(j-wyh+winy,i+winx) - im_sum_sq.at<double>(j-wyh,i+winx) - im_sum_sq.at<double>(j-wyh+winy,i+winx-1) + im_sum_sq.at<double>(j-wyh,i+winx-1);

			m  = sum / winarea;
			s  = sqrt ((sum_sq - m*sum)/winarea);
			if (s > max_s) max_s = s;

			map_m.fset(i+wxh, j, m);
			map_s.fset(i+wxh, j, s);
		}
	}

	return max_s;
}
Example #3
0
void Wolf (Mat im, Mat output, int winx, int winy, double k, double dR) {
	 // __android_log_write(ANDROID_LOG_INFO, "MOTOTAG", "0.1------------------");

	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;
	int mx, my;

	// 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);
	//  __android_log_write(ANDROID_LOG_INFO, "MOTOTAG", "1------------------");
	max_s = calcLocalStats (im, map_m, map_s, winx, winy);
	//  __android_log_write(ANDROID_LOG_INFO, "MOTOTAG", "2------------------");
	minMaxLoc(im, &min_I, &max_I);

	Mat thsurf (im.rows, im.cols, CV_32F);

	// Create the threshold surface, including border processing
	// ----------------------------------------------------
	//__android_log_write(ANDROID_LOG_INFO, "MOTOTAG", "3------------------");
	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);

     		th = m + k * (s/max_s-1) * (m-min_I);

    		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);
	}
	 //__android_log_write(ANDROID_LOG_INFO, "MOTOTAG", "4------------------");

	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);
    	}
    }
	// __android_log_write(ANDROID_LOG_INFO, "MOTOTAG", "5------------------");

}
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;
	int mx, my;

	// 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:
    				cerr << "Unknown threshold type in ImageThresholder::surfaceNiblackImproved()\n";
    				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);
	}
	cerr << "surface created" << endl;
	
	
	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);
    	}
    }
}
Example #5
0
void NiblackSauvolaWolfJolion (Mat im, Mat output, NiblackVersion version,
                               int winx, int winy, float k)
{
  float dR = BINARIZEWOLF_DEFAULTDR;

  float m, s, max_s;
  float 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 float 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++)
  {
    float* mapm_rowdata = map_m.ptr<float>(j);
    float* maps_rowdata = map_s.ptr<float>(j);
    float* thsurf_rowdata = thsurf.ptr<float>(j);
    
    // NORMAL, NON-BORDER AREA IN THE MIDDLE OF THE WINDOW:
    for	(int i=0 ; i <= im.cols-winx; i++)
    {
      m  = mapm_rowdata[i+wxh];
      s  = maps_rowdata[i+wxh];

      // 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:
        cerr << "Unknown threshold type in ImageThresholder::surfaceNiblackImproved()\n";
        exit (1);
      }

      thsurf_rowdata[i+wxh] = th;

      if (i==0)
      {
        // LEFT BORDER
        for (int i=0; i<=x_firstth; ++i)
          thsurf_rowdata[i] = th;

        // LEFT-UPPER CORNER
        if (j==y_firstth)
          for (int u=0; u<y_firstth; ++u)
	  {
	    float* thsurf_subrowdata = thsurf.ptr<float>(u);
            for (int i=0; i<=x_firstth; ++i)
              thsurf_subrowdata[i] = th;
	  }

        // LEFT-LOWER CORNER
        if (j==y_lastth)
          for (int u=y_lastth+1; u<im.rows; ++u)
	  {
	    float* thsurf_subrowdata = thsurf.ptr<float>(u);
            for (int i=0; i<=x_firstth; ++i)
              thsurf_subrowdata[i] = 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_rowdata[i] = th;

    // RIGHT-UPPER CORNER
    if (j==y_firstth)
      for (int u=0; u<y_firstth; ++u)
      {
	float* thsurf_subrowdata = thsurf.ptr<float>(u);
        for (int i=x_lastth; i<im.cols; ++i)
          thsurf_subrowdata[i] = th;
      }

    // RIGHT-LOWER CORNER
    if (j==y_lastth)
      for (int u=y_lastth+1; u<im.rows; ++u)
      {
	float* thsurf_subrowdata = thsurf.ptr<float>(u);
        for (int i=x_lastth; i<im.cols; ++i)
          thsurf_subrowdata[i] = th;
      }
  }

  for	(int y=0; y<im.rows; ++y)
  {
    uchar* outputdatarow = output.ptr<uchar>(y);
    uchar* imdatarow = im.ptr<uchar>(y);
    float* thsurfdatarow = thsurf.ptr<float>(y);
  
    for	(int x=0; x<im.cols; ++x)
    {
      if (imdatarow[x] >= thsurfdatarow[x])
	outputdatarow[x]=255;
      else
	outputdatarow[x]=0;
    }
  }
}