Example #1
0
cv::Mat ParImageToIplImage(DImage& img)
{
	int width = img.width();
	int height = img.height();
	int nChannels = img.nchannels();

	if(width <= 0 || height <= 0 || nChannels != 1)
		return cv::Mat();

	BaseType*& pData = img.data();
	cv::Mat image = cv::Mat(height, width, CV_MAKETYPE(8, 1));
	for(int i = 0;i < height;i++)
	{
		for(int j = 0;j < width;j++)
		{
			image.ptr<uchar>(i)[j] = pData[i*width + j] * 255;
		}
	}
	return image;
}
Example #2
0
void OpticalFlow::estGaussianMixture(const DImage& Im1,const DImage& Im2,GaussianMixture& para,double prior)
{
	int nIterations = 3, nChannels = Im1.nchannels();
	DImage weight1(Im1),weight2(Im1);
	double *total1,*total2;
	total1 = new double[nChannels];
	total2 = new double[nChannels];
	for(int count = 0; count<nIterations; count++)
	{
		double temp;
		memset(total1,0,sizeof(double)*nChannels);
		memset(total2,0,sizeof(double)*nChannels);

		// E step
		for(int i = 0;i<weight1.npixels();i++)
			for(int k=0;k<nChannels;k++)
			{
				int offset = i*weight1.nchannels()+k;
				temp = Im1[offset]-Im2[offset];
				temp *= temp;
				weight1[offset] = para.Gaussian(temp,0,k)*para.alpha[k];
				weight2[offset] = para.Gaussian(temp,1,k)*(1-para.alpha[k]);
				temp = weight1[offset]+weight2[offset];
				weight1[offset]/=temp;
				weight2[offset]/=temp;
				total1[k] += weight1[offset];
				total2[k] += weight2[offset];
			}

		// M step
		para.reset();


		for(int i = 0;i<weight1.npixels();i++)
			for(int k =0;k<nChannels;k++)
			{
				int offset = i*weight1.nchannels()+k;
				temp = Im1[offset]-Im2[offset];
				temp *= temp;
				para.sigma[k]+= weight1[offset]*temp;
				para.beta[k] += weight2[offset]*temp;
			}

		for(int k =0;k<nChannels;k++)
		{
			para.alpha[k] = total1[k]/(total1[k]+total2[k])*(1-prior)+0.95*prior; // regularize alpha
			para.sigma[k] = sqrt(para.sigma[k]/total1[k]);
			para.beta[k]   = sqrt(para.beta[k]/total2[k])*(1-prior)+0.3*prior; // regularize beta
		}
		para.square();
		count = count;
	}
}
Example #3
0
DPlane DColorCluster::apply_clustering(const DImage &input)
{
    DPlane result(input.rows(), input.cols());
    
    for(int i=0; i<input.rows(); i++)
        for(int j=0; j<input.cols(); j++)
        {
            int closest_cluster=0;
            double min_dist=1000000000;
            DTriple sample(input[0][i][j], input[1][i][j], input[2][i][j]);
            for(int c=0; c<clusters.size(); c++)
                if(clusters[c].distance_to(sample) < min_dist)
                {
                    min_dist = clusters[c].distance_to(sample);
                    closest_cluster = c;
                }
            result[i][j] = closest_cluster+1;
        }    
    
    return result;
}
Example #4
0
void GaussianPyramid::ConstructPyramidLevels(const DImage &image, double ratio, int _nLevels)
{
	// the ratio cannot be arbitrary numbers
	if(ratio>0.98 || ratio<0.4)
		ratio=0.75;
	nLevels = _nLevels;
	if(ImPyramid!=NULL)
		delete []ImPyramid;
	ImPyramid=new DImage[nLevels];
	ImPyramid[0].copyData(image);
	double baseSigma=(1/ratio-1);
	int n=log(0.25)/log(ratio);
	double nSigma=baseSigma*n;
	for(int i=1;i<nLevels;i++)
	{
		DImage foo;
		if(i<=n)
		{
			double sigma=baseSigma*i;
			image.GaussianSmoothing(foo,sigma,sigma*3);
			foo.imresize(ImPyramid[i],pow(ratio,i));
		}
		else
		{
			ImPyramid[i-n].GaussianSmoothing(foo,nSigma,nSigma*3);
			double rate=(double)pow(ratio,i)*image.width()/foo.width();
			foo.imresize(ImPyramid[i],rate);
		}
	}
}
Example #5
0
void WritePPMImage(const DImage &img, const char *filename)
{
  FILE *fp = fopen(filename, "wb");
  char temp[1024];

  // write magic number
  fprintf(fp, "P6\n");

  // write dimensions
  fprintf(fp, "%d %d\n", img.cols(), img.rows());
  
  // write max pixel value
  fprintf(fp, "255\n");

  for(int i=0; i<img.rows(); i++)
    for(int j=0; j<img.cols(); j++)
      for(int k=0; k<3; k++)
	fputc(int(img[k][i][j]), fp);

  fclose(fp);

  return;
}
Example #6
0
/**Each row of img is projected onto the vertical axis.  Resulting
   data length will be equal to the height of img.  The profile is a summation
   of the grayscale values in each row.  If fNormalize is true, then each value
   is divided by img.width() so it is the average grayscale value for the row
   instead of the sum.

   If fNormalize is true, the resulting profile values are divided by the image
   width.
 */
void DProfile::getImageVerticalProfile(const DImage &img, bool fNormalize){
  int w, h;

  w = img.width();
  h = img.height();
  // allocate the rgProf array
  if(NULL == rgProf){
    rgProf = (double*)malloc(h * sizeof(double));
    D_CHECKPTR(rgProf);
    len = h;
  }
  else{
    if(len != h){
      rgProf = (double*)realloc(rgProf,h*sizeof(double));
      D_CHECKPTR(rgProf);
      len = h;
    }
  }
  switch(img.getImageType()){
    case DImage::DImage_u8:
      {
	D_uint8 *pu8;
	pu8=img.dataPointer_u8();
	for(int y = 0, idx=0; y < h; ++y){
	  rgProf[y] = 0.;
	  for(int x = 0; x < w; ++x, ++idx){
	    rgProf[y] += pu8[idx];
	  }
	  if(fNormalize)
	    rgProf[y] /= w;
	}
      }
      break;
    case DImage::DImage_flt_multi:
      {
	float *pflt;
	if(img.numChannels() > 1){
	  fprintf(stderr,"DProfile::getImageVerticalProfile() floats only "
		  "supported with a single channel\n");
	  abort();
	}
	pflt=img.dataPointer_flt(0);
	for(int y = 0, idx=0; y < h; ++y){
	  rgProf[y] = 0.;
	  for(int x = 0; x < w; ++x, ++idx){
	    rgProf[y] += pflt[idx];
	  }
	  if(fNormalize)
	    rgProf[y] /= w;
	}
      }
      break;
    default:
      fprintf(stderr, "Not yet implemented!\n");
      abort();
  }//end switch(img.getImageType())
}
Example #7
0
//--------------------------------------------------------------------------------------
// function to perfomr coarse to fine optical flow estimation
//--------------------------------------------------------------------------------------
void OpticalFlow::Coarse2FineFlow(DImage &vx, DImage &vy, DImage &warpI2,const DImage &Im1, const DImage &Im2, double alpha, double ratio, int minWidth,
                                  int nOuterFPIterations, int nInnerFPIterations, int nCGIterations)
{
    // first build the pyramid of the two images
    GaussianPyramid GPyramid1;
    GaussianPyramid GPyramid2;
    if(IsDisplay)
        cout<<"Constructing pyramid...";
    GPyramid1.ConstructPyramid(Im1,ratio,minWidth);
    GPyramid2.ConstructPyramid(Im2,ratio,minWidth);
    if(IsDisplay)
        cout<<"done!"<<endl;

    // now iterate from the top level to the bottom
    DImage Image1,Image2,WarpImage2;

    for(int k=GPyramid1.nlevels()-1; k>=0; k--)
    {
        if(IsDisplay)
            cout<<"Pyramid level "<<k;
        int width=GPyramid1.Image(k).width();
        int height=GPyramid1.Image(k).height();
        im2feature(Image1,GPyramid1.Image(k));
        im2feature(Image2,GPyramid2.Image(k));

        if(k==GPyramid1.nlevels()-1) // if at the top level
        {
            vx.allocate(width,height);
            vy.allocate(width,height);
            //warpI2.copyData(Image2);
            WarpImage2.copyData(Image2);
        }
        else
        {

            vx.imresize(width,height);
            vx.Multiplywith(1/ratio);
            vy.imresize(width,height);
            vy.Multiplywith(1/ratio);
            //warpFL(warpI2,GPyramid1.Image(k),GPyramid2.Image(k),vx,vy);
            warpFL(WarpImage2,Image1,Image2,vx,vy);
        }
        //SmoothFlowPDE(GPyramid1.Image(k),GPyramid2.Image(k),warpI2,vx,vy,alpha,nOuterFPIterations,nInnerFPIterations,nCGIterations);
        //SmoothFlowPDE(Image1,Image2,WarpImage2,vx,vy,alpha*pow((1/ratio),k),nOuterFPIterations,nInnerFPIterations,nCGIterations);
        SmoothFlowPDE(Image1,Image2,WarpImage2,vx,vy,alpha,nOuterFPIterations,nInnerFPIterations,nCGIterations);
        if(IsDisplay)
            cout<<endl;
    }
    warpFL(warpI2,Im1,Im2,vx,vy);
}
bool OpticalFlow::showFlow(const DImage& flow,const char* filename)
{
	if(flow.nchannels()!=1)
	{
		cout<<"The flow must be a single channel image!"<<endl;
		return false;
	}
	Image<unsigned char> foo;
	foo.allocate(flow.width(),flow.height());
	double Max = flow.max();
	double Min = flow.min();
	for(int i = 0;i<flow.npixels(); i++)
		foo[i] = (flow[i]-Min)/(Max-Min)*255;
	foo.imwrite(filename);
}
Example #9
0
//--------------------------------------------------------------------------------------------------------
//  function to compute dx, dy and dt for motion estimation
//--------------------------------------------------------------------------------------------------------
void OpticalFlow::getDxs(DImage &imdx, DImage &imdy, DImage &imdt, const DImage &im1, const DImage &im2)
{
    // Im1 and Im2 are the smoothed version of im1 and im2
    DImage Im1,Im2;
    double gfilter[5]= {0.05,0.2,0.5,0.2,0.05};
    im1.imfilter_hv(Im1,gfilter,2,gfilter,2);
    im2.imfilter_hv(Im2,gfilter,2,gfilter,2);

    //Im1.copyData(im1);
    //Im2.copyData(im2);

    Im2.dx(imdx,true);
    Im2.dy(imdy,true);
    imdt.Subtract(Im2,Im1);
    imdx.setDerivative();
    imdy.setDerivative();
    imdt.setDerivative();
}
Example #10
0
void OpticalFlow::warpFL(DImage &warpIm2, const DImage &Im1, const DImage &Im2, const DImage &Flow)
{
	if(warpIm2.matchDimension(Im2)==false)
		warpIm2.allocate(Im2.width(),Im2.height(),Im2.nchannels());
	ImageProcessing::warpImageFlow(warpIm2.data(),Im1.data(),Im2.data(),Flow.data(),Im2.width(),Im2.height(),Im2.nchannels());
}
Example #11
0
//------------------------------------------------------------------------------------------------
// multi-grid belie propagation
//------------------------------------------------------------------------------------------------
void BPFlow::generateCoarserLevel(BPFlow &bp)
{
	//------------------------------------------------------------------------------------------------
	// set the dimensions and parameters
	//------------------------------------------------------------------------------------------------
	bp.Width=Width/2;
	if(Width%2==1)
		bp.Width++;

	bp.Height=Height/2;
	if(Height%2==1)
		bp.Height++;

	bp.Area=bp.Width*bp.Height;
	bp.s=s;
	bp.d=d;

	DImage foo;
	Im_s.smoothing(foo);
	foo.imresize(bp.Im_s,bp.Width,bp.Height);
	Im_d.smoothing(foo);
	foo.imresize(bp.Im_d,bp.Width,bp.Height);

	bp.IsDisplay=IsDisplay;
	bp.nNeighbors=nNeighbors;

	//------------------------------------------------------------------------------------------------
	// allocate buffers
	//------------------------------------------------------------------------------------------------
	for(int i=0;i<2;i++)
	{
		bp.pOffset[i]=new int[bp.Area];
		bp.pWinSize[i]=new int[bp.Area];
		ReduceImage(bp.pOffset[i],Width,Height,pOffset[i]);
		ReduceImage(bp.pWinSize[i],Width,Height,pWinSize[i]);
		for(int j = 0;j<bp.Area;j++)
			bp.pWinSize[i][j] = __max(bp.pWinSize[i][j],1);
	}
	//------------------------------------------------------------------------------------------------
	// generate data term
	//------------------------------------------------------------------------------------------------
	bp.nTotalMatches=bp.AllocateBuffer(bp.pDataTerm,bp.ptrDataTerm,bp.pWinSize[0],bp.pWinSize[1]);
	for(int i=0;i<bp.Height;i++)
		for(int j=0;j<bp.Width;j++)
		{
			int offset=i*bp.Width+j;
			for(int ii=0;ii<2;ii++)
				for(int jj=0;jj<2;jj++)
				{
					int y=i*2+ii;
					int x=j*2+jj;
					if(y<Height && x<Width)
					{
						int nStates=(bp.pWinSize[0][offset]*2+1)*(bp.pWinSize[1][offset]*2+1);
						for(int k=0;k<nStates;k++)
							bp.pDataTerm[offset].data()[k]+=pDataTerm[y*Width+x].data()[k];
					}
				}
		}
	//------------------------------------------------------------------------------------------------
	// generate range term
	//------------------------------------------------------------------------------------------------
	bp.ComputeRangeTerm(gamma/2);
}
Example #12
0
/**The slant angle is assumed to be between 60 and -45 degrees (0 deg=vertical,
 * negative values are left-slanted, positive values right-slanted).
 * To determine slant: at each x-position, the longest runlength at each angle
 * is found and its squared value is added into the accumulator for that angle.
 * The histogram is smoothed, and the angle corresponding to the highest value 
 * in the histogram is the returned angle (in degrees).
 *
 * Runlengths of less than rlThresh pixels are ignored.
 *
 * The image should be black(0) and white(255).  The portion of the image
 * specified by x0,y0 - x1,y1 is considered to be the textline of interest.
 * If no coordinates are specified, then the entire image is used as the 
 * textline.
 *
 * If weight is not NULL, it will be the sum of max runlengths (not squared) at
 * all 120 angles.  Weights are used in determination of weighted average angle
 * for all textlines in getAllTextlinesSlantAngleDeg() before adjusting angles.
 *
 * If rgSlantHist is not NULL, the squared max RL values in the angle histogram
 * will be copied into the rgSlantHist array. It must already be allocated to
 * 120*sizeof(unsigned int).
 * 
 * if imgAngleHist is not NULL, then the image is set to w=120 and h=y1-y0+1.
 * It is a (grayscale) graphical representation of what is in rgSlantHist.
 */
double DSlantAngle::getTextlineSlantAngleDeg(DImage &imgBW,
					     int rlThresh,
					     int x0,int y0,int x1,int y1,
					     double *weight,
					     unsigned int *rgSlantHist,
					     DImage *imgAngleHist){
  int *rgLineSlantAngles;
  int lineH;
  int slantOffset, slantAngle, angle;
  unsigned int rgSlantSums[120];
  unsigned int rgSlantSumsTmp[120];
  int runlen, maxrl; /* maximum slant runlen */
  double slantDx;
  int w, h;
  D_uint8 *p8;
  double dblWeight = 0;
  
  w = imgBW.width();
  h = imgBW.height();
  p8 = imgBW.dataPointer_u8();
  if(-1 == x1)
    x1 = w-1;
  if(-1 == y1)
    y1 = h-1;
  
  lineH = y1-y0+1;

  /* estimate the predominant slant angle (0=vertical, +right, -left) */
  slantOffset = (int)(0.5+ (lineH / 2.0) / tan(DMath::degreesToRadians(30.)));
  for(int j = 0; j < 120; ++j){
    rgSlantSums[j] = 0;
    rgSlantSumsTmp[j] = 0;
  }
  for(angle = -45; angle <= 60; angle += 1){
    /* at each x-position, sum the maximum run length at that angle into the
       accumulator */
    if(0 == angle) /* vertical, so tangent is infinity */
      slantDx = 0.;
    else
      slantDx = -1.0 / tan(DMath::degreesToRadians(90-angle));
    //       for(j = slantOffset; j < (hdr.w-slantOffset); ++j){
    for(int j = x0; j <= x1; ++j){
      maxrl = 0;
      runlen = 0;
      for(int y = 0; y < lineH; ++y){
	int x;
	x = (int)(0.5+ j + y * slantDx);
	if( (x>=x0) && (x <= x1)){ /* make sure we are within bounds */
	  int idxtmp;
	  idxtmp = (y+y0)*w+x;
// 	    imgCoded[idxtmp*3] = 0;
	  if(0 == p8[idxtmp]){
	    ++runlen;
	    if(runlen > maxrl){
	      maxrl = runlen;
	    }
	  }
	  else
	    runlen = 0;
	} /* end if in bounds */
	else{
	  runlen = 0; /* ignore runs that go off edge of image */
	}
      }
      if(maxrl > rlThresh){
	rgSlantSums[angle+45] += maxrl*maxrl;
	dblWeight += maxrl;
      }
    } /* end for j */
  } /* end for angle */

  //smooth the histogram
  rgSlantSumsTmp[0] = (rgSlantSums[0] + rgSlantSums[1]) / 2;
  for(int aa = 1; aa < 119; ++aa){
    rgSlantSumsTmp[aa]=(rgSlantSums[aa-1]+rgSlantSums[aa]+rgSlantSums[aa+1])/3;
  }
  for(int aa = 0; aa < 120; ++aa){
    rgSlantSums[aa] = rgSlantSumsTmp[aa];
  }

  //use the histogram peak as the slant angle
  slantAngle = 0;
  for(angle = -45; angle <= 60; angle += 1){
    if(rgSlantSums[angle+45] > rgSlantSums[slantAngle+45]){
      slantAngle = angle;
    }
  } /* end for angle */

  if(NULL != weight)
    (*weight) = dblWeight;

  if(NULL != rgSlantHist){
    for(int aa = 0; aa < 120; ++aa){
      rgSlantHist[aa] = rgSlantSums[aa];
    }
  }

  if(NULL != imgAngleHist){//debug tool- return an image of the angle histogram
    //DProfile prof;
    int max = 0;
    int htmp;
    D_uint8 *p8ang;
    
    htmp = y1-y0+1;
    imgAngleHist->create(120,htmp,DImage::DImage_u8);
    imgAngleHist->clear();
    p8ang = imgAngleHist->dataPointer_u8();
    for(int i=0; i < 120; ++i){
      if(rgSlantSums[i] > max)
	max = rgSlantSums[i];
    }
    if(0==max)
      max = 1;
    // for(int y=0, idx=0; y < htmp; ++y){
    //   for(int x=0; x < 120; ++x, ++idx){
    // 	if((rgSlantSums[x]/(double)max) >= ((htmp-y)/(double)htmp))
    // 	  p8ang[idx] = 0xee;
    // 	else
    // 	  p8ang[idx] = 0x88;
    //   }
    // }
    // printf("htmp=%d\n", htmp);
    for(int x=0; x < 120; ++x){
      double pct;
      pct = 1.-rgSlantSums[x] / (double)max;
      imgAngleHist->drawLine(x,htmp-1,x,(int)(pct*(htmp-1)), 128);
    }


  }

  return (double)slantAngle;
}
Example #13
0
void* DSlantAngle::getSlant_thread_func(void *params){
  SLANT_THREAD_PARMS *pparms;
  int numThreads;
  int w, h;
  D_uint8 *p8;

  int runlen, maxrl; /* maximum slant runlen */
  double slantDx;
  int lineH;
  int slantOffset, slantAngle, angle;
  double dblWeight;
  DImage *pimg;
  int rlThresh;

  pparms = (SLANT_THREAD_PARMS*)params;
  
  numThreads = pparms->numThreads;
  pimg = pparms->pImgSrc;
  rlThresh = pparms->rlThresh;
  w = pimg->width();
  h = pimg->height();
  p8 = pimg->dataPointer_u8();
  for(int i=0; i < 120; ++i)
    pparms->rgSlantSums[i] = 0;
  for(int tl=pparms->threadNum; tl < (pparms->numTextlines); tl+=numThreads){
    int x0, y0, x1, y1;
    unsigned int rgSlantSums[120];
    x0 = pparms->rgRects[tl].x;
    y0 = pparms->rgRects[tl].y;
    x1 = pparms->rgRects[tl].x + pparms->rgRects[tl].w - 1;
    y1 = pparms->rgRects[tl].y + pparms->rgRects[tl].h - 1;
    lineH = y1-y0+1;
    memset(rgSlantSums, 0, sizeof(int)*120);
    dblWeight = 0.;
    
    for(angle = -45; angle <= 60; angle += 1){
      /* at each x-position, sum the maximum run length at that angle into the
	 accumulator */
      if(0 == angle) /* vertical, so tangent is infinity */
	slantDx = 0.;
      else
	slantDx = -1.0 / tan(DMath::degreesToRadians(90-angle));
      //       for(j = slantOffset; j < (hdr.w-slantOffset); ++j){
      for(int j = x0; j <= x1; ++j){
	maxrl = 0;
	runlen = 0;
	for(int y = 0; y < lineH; ++y){
	  int x;
	  x = (int)(0.5+ j + y * slantDx);
	  if( (x>=x0) && (x <= x1)){ /* make sure we are within bounds */
	    int idxtmp;
	    idxtmp = (y+y0)*w+x;
	    // 	    imgCoded[idxtmp*3] = 0;
	    if(0 == p8[idxtmp]){
	      ++runlen;
	      if(runlen > maxrl){
		maxrl = runlen;
	      }
	    }
	    else
	      runlen = 0;
	  } /* end if in bounds */
	  else{
	    runlen = 0; /* ignore runs that go off edge of image */
	  }
	}
	if(maxrl > rlThresh){
	  rgSlantSums[angle+45] += maxrl*maxrl;
	  dblWeight += maxrl;
	}
      } /* end for j */
    } /* end for angle */
    for(int i=0; i < 120; ++i)
      pparms->rgSlantSums[i] += rgSlantSums[i];
    if(NULL != (pparms->rgWeights)){
      pparms->rgWeights[tl] = dblWeight;
    }
    if(NULL != (pparms->rgAngles)){
      // need to independently figure out the angle for this particular textline
      unsigned int rgSlantSumsTmp[120];
      
      //smooth the histogram
      rgSlantSumsTmp[0] = (rgSlantSums[0] + rgSlantSums[1]) / 2;
      for(int aa = 1; aa < 119; ++aa){
	rgSlantSumsTmp[aa]=(rgSlantSums[aa-1]+rgSlantSums[aa]+rgSlantSums[aa+1])/3;
      }
      // for(int aa = 0; aa < 120; ++aa){
      // 	rgSlantSums[aa] = rgSlantSumsTmp[aa];
      // }
      
      //use the smoothed histogram peak as the slant angle
      slantAngle = 0;
      for(angle = -45; angle <= 60; angle += 1){
	if(rgSlantSumsTmp[angle+45] > rgSlantSumsTmp[slantAngle+45]){
	  slantAngle = angle;
	}
      } /* end for angle */
      pparms->rgAngles[tl] = slantAngle;
    }
  }

}
Example #14
0
/**Avg runlength in each column of img is projected onto the horizontal axis.
   Resulting data length will be equal to the width of img.
   If fNormalize is true, each profile value will be divided by image height,
   so the value is a fraction of the image height instead of a number of pixels.
 */
void DProfile::getHorizAvgRunlengthProfile(const DImage &img, D_uint32 rgbVal,
					   bool fNormalize){
  int w, h;
  unsigned int *rgRunlengths;
  unsigned int *rgNumRuns;

  w = img.width();
  h = img.height();
  // allocate the rgProf array
  if(NULL == rgProf){
    rgProf = (double*)malloc(w * sizeof(double));
    D_CHECKPTR(rgProf);
    len = w;
  }
  else{
    if(len != w){
      rgProf = (double*)realloc(rgProf,w*sizeof(double));
      D_CHECKPTR(rgProf);
      len = w;
    }
  }
  rgRunlengths = (unsigned int*)malloc(sizeof(unsigned int)*w);
  D_CHECKPTR(rgRunlengths);
  rgNumRuns = (unsigned int*)malloc(sizeof(unsigned int)*w);
  D_CHECKPTR(rgNumRuns);
  memset(rgRunlengths, 0, sizeof(unsigned int)*w);
  memset(rgNumRuns, 0, sizeof(unsigned int)*w);
  memset(rgProf, 0, sizeof(double) * w);
  switch(img.getImageType()){
    case DImage::DImage_u8:
      {
	D_uint8 *pu8;
	pu8=img.dataPointer_u8();
	for(int y = 0, idx=0; y < h; ++y){
	  for(int x = 0; x < w; ++x, ++idx){
	    if((D_uint8)rgbVal == pu8[idx]){//increment run length for this col
	      if(0 == rgRunlengths[x])
		++(rgNumRuns[x]);
	      ++(rgRunlengths[x]);
	      ++(rgProf[x]);
	    }
	    else{
	      rgRunlengths[x] = 0;
	    }
	  }
	}
	for(int x = 0; x < w; ++x){
	  //divide sum by number of runs to get avg
	  if(rgNumRuns[x] > 0)
	    rgProf[x] /= rgNumRuns[x];
	}
	if(fNormalize){
	  for(int x = 0; x < w; ++x){
	    rgProf[x] /= h;
	  }
	}
      }
      break;
    default:
      fprintf(stderr, "Not yet implemented!\n");
      abort();
  }//end switch(img.getImageType())
	
  free(rgRunlengths);
  free(rgNumRuns);
}
Example #15
0
void main_Regular(int idx)
{
	if(idx > 18 || idx < 0)
		return;
	int boarder_size = 16;
	int center_width = 256;
	int center_height = 256;
	int width = center_width+boarder_size*2;
	int height = center_height+boarder_size*2;
	bool cut_boarder = true;

	int data_index = idx;

	const static int BUF_LEN = 200;
	char out_flow_fold[BUF_LEN] = {0};
	char out_par_fold[BUF_LEN] = {0};
	int par_num = 0;
	int vort_num = 0;
	double max_vort = 1;
	double min_vort = 0.6;
	double max_vort_radius = 20;
	double min_vort_radius = 15;

	bool use_peroid_coord = false;
	
	double base_vel_u = 0;
	double base_vel_v = 0;
	int skip_frames = 0;
	int coarse_len = 16;

	ZQ_PIVMovingObject* mvobj = 0;

	DImage par_mask(width,height);


	switch(data_index)
	{
	case 0:
		strcpy_s(out_flow_fold, BUF_LEN,"flow0");
		strcpy_s(out_par_fold, BUF_LEN,"par0");
		srand(1000);
		par_num = 10000;
		vort_num = 40;
		max_vort = 1.8;
		min_vort = 1.2;
		max_vort_radius = 20;
		min_vort_radius = 20;
		use_peroid_coord = true;
	
		boarder_size = 64;
		width = center_width + 2*boarder_size;
		height = center_height + 2*boarder_size;

		coarse_len = 32;
		par_mask.allocate(width,height);
		for(int y = 0;y < height;y++)
		{
			for(int x = 0;x < width;x++)
			{
				if(x < coarse_len || x >= width - coarse_len)
					par_mask.data()[y*width+x] = 1;
			}
		}
		base_vel_u = 5;
		base_vel_v = 0;
		skip_frames = 20;
		break;

	case 1:
		strcpy_s(out_flow_fold, BUF_LEN,"flow1");
		strcpy_s(out_par_fold, BUF_LEN,"par1");
		srand(2000);
		par_num = 10000;
		vort_num = 40;
		max_vort = 1.6;
		min_vort = 0.8;
		max_vort_radius = 20;
		min_vort_radius = 20;
		use_peroid_coord = true;
		coarse_len = 48;
		par_mask.allocate(width,height);
		for(int y = 0;y < height;y++)
		{
			for(int x = 0;x < width;x++)
			{
				if(x >= width - coarse_len)
					par_mask.data()[y*width+x] = 1;
			}
		}
		base_vel_u = 5;
		base_vel_v = 0;
		skip_frames = 20;
		break;

	case 2:
		strcpy_s(out_flow_fold, BUF_LEN,"flow2");
		strcpy_s(out_par_fold, BUF_LEN,"par2");
		srand(2000);
		par_num = 10000;
		vort_num = 40;
		max_vort = 1.6;
		min_vort = 0.8;
		max_vort_radius = 20;
		min_vort_radius = 20;
		use_peroid_coord = true;
		coarse_len = 16;
		par_mask.allocate(width,height);
		for(int y = 0;y < height;y++)
		{
			for(int x = 0;x < width;x++)
			{
				int cy = y/coarse_len;
				int cx = x/coarse_len;

				if(cx%3 != 0)
					par_mask.data()[y*width+x] = 1;
			}
		}
		base_vel_u = 5;
		base_vel_v = 1;
		skip_frames = 20;
		break;

	case 3:
		strcpy_s(out_flow_fold, BUF_LEN,"flow3");
		strcpy_s(out_par_fold, BUF_LEN,"par3");
		srand(3000);
		par_num = 10000;
		vort_num = 40;
		max_vort = 1.6;
		min_vort = 0.8;
		max_vort_radius = 20;
		min_vort_radius = 20;
		use_peroid_coord = true;
		coarse_len = 16;
		par_mask.allocate(width,height);
		for(int y = 0;y < height;y++)
		{
			for(int x = 0;x < width;x++)
			{
				int cy = y/coarse_len;
				int cx = x/coarse_len;

				if(cx%2 == 0)
					par_mask.data()[y*width+x] = 1;
			}
		}
		base_vel_u = 5;
		base_vel_v = 1;
		skip_frames = 20;
		break;
	case 4:
		strcpy_s(out_flow_fold, BUF_LEN,"flow4");
		strcpy_s(out_par_fold, BUF_LEN,"par4");
		srand(4000);
		par_num = 10000;
		vort_num = 40;
		max_vort = 1.6;
		min_vort = 0.8;
		max_vort_radius = 20;
		min_vort_radius = 20;
		use_peroid_coord = true;
		coarse_len = 64;
		par_mask.allocate(width,height);
		for(int y = 0;y < height;y++)
		{
			for(int x = 0;x < width;x++)
			{
				int cy = y/coarse_len;
				int cx = x/coarse_len;

				if(cx%2 == 0)
					par_mask.data()[y*width+x] = 1;
			}
		}
		base_vel_u = 5;
		base_vel_v = 1;
		skip_frames = 20;
		break;
	case 5:
		strcpy_s(out_flow_fold, BUF_LEN,"flow5");
		strcpy_s(out_par_fold, BUF_LEN,"par5");
		srand(5000);
		par_num = 10000;
		vort_num = 40;
		max_vort = 1.6;
		min_vort = 0.8;
		max_vort_radius = 20;
		min_vort_radius = 20;
		use_peroid_coord = true;
		coarse_len = 32;
		par_mask.allocate(width,height);
		for(int y = 0;y < height;y++)
		{
			for(int x = 0;x < width;x++)
			{
				int cy = y/coarse_len;
				int cx = x/coarse_len;

				if(cx%2 == 0)
					par_mask.data()[y*width+x] = 1;
			}
		}
		base_vel_u = 5;
		base_vel_v = 1;
		skip_frames = 20;
		break;
	case 6:
		strcpy_s(out_flow_fold, BUF_LEN,"flow6");
		strcpy_s(out_par_fold, BUF_LEN,"par6");
		srand(6000);
		par_num = 10000;
		vort_num = 40;
		max_vort = 1.6;
		min_vort = 0.8;
		max_vort_radius = 20;
		min_vort_radius = 20;
		use_peroid_coord = true;
		coarse_len = 32;
		par_mask.allocate(width,height);
		for(int y = 0;y < height;y++)
		{
			for(int x = 0;x < width;x++)
			{
				int cy = y/coarse_len;
				int cx = x/coarse_len;

				if(cy%2 == 0)
					par_mask.data()[y*width+x] = 1;
			}
		}
		base_vel_u = 5;
		base_vel_v = 1;
		skip_frames = 20;
		break;
	case 7:
		strcpy_s(out_flow_fold, BUF_LEN,"flow7");
		strcpy_s(out_par_fold, BUF_LEN,"par7");
		srand(7000);
		par_num = 10000;
		vort_num = 20;
		max_vort = 1.8;
		min_vort = 1.2;
		max_vort_radius = 30;
		min_vort_radius = 20;
		use_peroid_coord = true;
		coarse_len = 64;
		par_mask.allocate(width,height);
		/*for(int y = 0;y < height;y++)
		{
			for(int x = 0;x < width;x++)
			{
				int cy = y/coarse_len;
				int cx = x/coarse_len;

				if((cy+cx)%2 == 0)
					par_mask.data()[y*width+x] = 1;
			}
		}*/
		base_vel_u = 5;
		base_vel_v = 1;
		skip_frames = 20;
		break;
	case 8:
		boarder_size = 16;
		center_width = 256;
		center_height = 256;
		width = center_width+boarder_size*2;
		height = center_height+boarder_size*2;
		cut_boarder = true;

		strcpy_s(out_flow_fold, BUF_LEN,"flow8");
		strcpy_s(out_par_fold, BUF_LEN,"par8");
		srand(9000);
		par_num = 10000;
		vort_num = 30;
		max_vort = 1.6;
		min_vort = 1.2;
		max_vort_radius = 30;
		min_vort_radius = 20;
		use_peroid_coord = true;

		mvobj = new ZQ_PIVMovingObject(48,48,ZQ_PIVMovingObject::ZQ_PIV_MOVOB_CIRCLE_STATIC,"wenli.di2");

		/*has_occupy = true;
		occupy = new bool[width*height];
		memset(occupy,0,sizeof(bool)*width*height);

		for(int y = 0;y < height;y++)
		{
			for(int x = 0;x < width;x++)
			{
				double dis = sqrt((y-height*0.5)*(y-height*0.5)+(x-width*0.5)*(x-width*0.5));
				if(dis < (height+width)*0.05)
					occupy[y*width+x] = true;
			}
		}*/

		coarse_len = 32;
		par_mask.allocate(width,height);
		/*for(int y = 0;y < height;y++)
		{
			for(int x = 0;x < width;x++)
			{

				if(occupy[y*width+x])
					par_mask.data()[y*width+x] = 1;
			}
		}*/
		base_vel_u = 4;
		base_vel_v = 0;
		skip_frames = 20;

		break;

	case 9:
		boarder_size = 16;
		center_width = 256;
		center_height = 256;
		width = center_width+boarder_size*2;
		height = center_height+boarder_size*2;
		cut_boarder = true;

		strcpy_s(out_flow_fold, BUF_LEN,"flow9");
		strcpy_s(out_par_fold, BUF_LEN,"par9");
		srand(8000);
		par_num = 10000;
		vort_num = 30;
		max_vort = 1.4;
		min_vort = 1.0;
		max_vort_radius = 30;
		min_vort_radius = 20;
		use_peroid_coord = true;

		mvobj = new ZQ_PIVMovingObject(48,48, ZQ_PIVMovingObject::ZQ_PIV_MOVOB_RECT_UPDOWN,"wenli.di2");
		

		coarse_len = 32;
		par_mask.allocate(width,height);
		
		base_vel_u = 4;
		base_vel_v = 0;
		skip_frames = 20;

		break;

	case 10:

		boarder_size = 16;
		center_width = 256;
		center_height = 256;
		width = center_width+boarder_size*2;
		height = center_height+boarder_size*2;
		cut_boarder = true;

		strcpy_s(out_flow_fold, BUF_LEN, "flow10");
		strcpy_s(out_par_fold, BUF_LEN, "par10");
		srand(10000);
		par_num = 10000;
		vort_num = 30;
		max_vort = 1.4;
		min_vort = 1.0;
		max_vort_radius = 30;
		min_vort_radius = 20;
		use_peroid_coord = true;

		mvobj = new ZQ_PIVMovingObject(48,48, ZQ_PIVMovingObject::ZQ_PIV_MOVOB_CIRCLE_CIRCULAR,"wenli.di2");


		coarse_len = 32;
		par_mask.allocate(width,height);

		base_vel_u = 0;
		base_vel_v = 0;
		skip_frames = 20;
		break;

	case 11:
		boarder_size = 16;
		center_width = 256;
		center_height = 256;
		width = center_width+boarder_size*2;
		height = center_height+boarder_size*2;
		cut_boarder = true;

		strcpy_s(out_flow_fold, BUF_LEN,"flow11");
		strcpy_s(out_par_fold, BUF_LEN, "par11");
		srand(11000);
		par_num = 5000;
		vort_num = 20;
		max_vort = 1.6;
		min_vort = 0.8;
		max_vort_radius = 20;
		min_vort_radius = 20;
		use_peroid_coord = true;
		par_mask.allocate(width,height);
		
		base_vel_u = 5;
		base_vel_v = 0;
		skip_frames = 20;
		break;
	case 12:
		boarder_size = 16;
		center_width = 256;
		center_height = 256;
		width = center_width+boarder_size*2;
		height = center_height+boarder_size*2;
		cut_boarder = true;

		strcpy_s(out_flow_fold, BUF_LEN,"flow12");
		strcpy_s(out_par_fold, BUF_LEN,"par12");
		srand(1240);
		par_num = 5000;
		vort_num = 30;
		max_vort = 2.5;
		min_vort = 1.6;
		max_vort_radius = 20;
		min_vort_radius = 10;
		use_peroid_coord = true;
		par_mask.allocate(width,height);

		base_vel_u = 0;
		base_vel_v = 0;
		skip_frames = 20;
		break;
	case 13:
		boarder_size = 16;
		center_width = 256;
		center_height = 256;
		width = center_width+boarder_size*2;
		height = center_height+boarder_size*2;
		cut_boarder = true;

		strcpy_s(out_flow_fold, BUF_LEN,"flow13");
		strcpy_s(out_par_fold, BUF_LEN,"par13");
		srand(1300);
		par_num = 5000;
		vort_num = 10;
		max_vort = 1.5;
		min_vort = 0.6;
		max_vort_radius = 20;
		min_vort_radius = 20;
		use_peroid_coord = true;
		par_mask.allocate(width,height);

		base_vel_u = 1;
		base_vel_v = 1;
		skip_frames = 10;
		break;

	case 14:
		boarder_size = 16;
		center_width = 256;
		center_height = 256;
		width = center_width+boarder_size*2;
		height = center_height+boarder_size*2;
		cut_boarder = true;

		strcpy_s(out_flow_fold, BUF_LEN, "flow14");
		strcpy_s(out_par_fold, BUF_LEN, "par14");
		srand(14000);
		par_num = 5000;
		vort_num = 10;
		max_vort = 1.0;
		min_vort = 0.8;
		max_vort_radius = 20;
		min_vort_radius = 10;
		use_peroid_coord = true;

		mvobj = new ZQ_PIVMovingObject(48,48, ZQ_PIVMovingObject::ZQ_PIV_MOVOB_CIRCLE_STATIC,"wenli.di2");
	
		par_mask.allocate(width,height);
		
		base_vel_u = 2;
		base_vel_v = 0;
		skip_frames = 20;

		break;

	case 15:
		boarder_size = 16;
		center_width = 256;
		center_height = 256;
		width = center_width+boarder_size*2;
		height = center_height+boarder_size*2;
		cut_boarder = true;

		strcpy_s(out_flow_fold, BUF_LEN,"flow15");
		strcpy_s(out_par_fold, BUF_LEN,"par15");
		srand(15000);
		par_num = 5000;
		vort_num = 20;
		max_vort = 1.0;
		min_vort = 0.8;
		max_vort_radius = 20;
		min_vort_radius = 10;
		use_peroid_coord = true;

		mvobj = new ZQ_PIVMovingObject(48,48, ZQ_PIVMovingObject::ZQ_PIV_MOVOB_RECT_STATIC,"wenli.di2");

		par_mask.allocate(width,height);

		base_vel_u = 5;
		base_vel_v = 0;
		skip_frames = 50;

		break;
	case 16:	// the same field as "case18" ,but more particles
		boarder_size = 16;
		center_width = 256;
		center_height = 256;
		width = center_width+boarder_size*2;
		height = center_height+boarder_size*2;
		cut_boarder = true;

		strcpy_s(out_flow_fold, BUF_LEN, "flow16");
		strcpy_s(out_par_fold, BUF_LEN,"par16");
		srand(11000);
		par_num = 20000;
		vort_num = 20;
		max_vort = 1.6;
		min_vort = 0.8;
		max_vort_radius = 20;
		min_vort_radius = 20;
		use_peroid_coord = true;
		par_mask.allocate(width,height);

		base_vel_u = 5;
		base_vel_v = 0;
		skip_frames = 20;
		break;

	case 17:	// the same field as "case18" ,but less particles
		boarder_size = 16;
		center_width = 256;
		center_height = 256;
		width = center_width+boarder_size*2;
		height = center_height+boarder_size*2;
		cut_boarder = true;

		strcpy_s(out_flow_fold, BUF_LEN, "flow17");
		strcpy_s(out_par_fold, BUF_LEN, "par17");
		srand(11000);
		par_num = 2000;
		vort_num = 20;
		max_vort = 1.6;
		min_vort = 0.8;
		max_vort_radius = 20;
		min_vort_radius = 20;
		use_peroid_coord = true;
		par_mask.allocate(width,height);

		base_vel_u = 5;
		base_vel_v = 0;
		skip_frames = 20;
		break;

	case 18:	// the same field as "case16" and "case17" 
		boarder_size = 16;
		center_width = 256;
		center_height = 256;
		width = center_width+boarder_size*2;
		height = center_height+boarder_size*2;
		cut_boarder = true;

		strcpy_s(out_flow_fold, BUF_LEN,"flow18");
		strcpy_s(out_par_fold, BUF_LEN,"par18");
		srand(11000);
		par_num = 5000;
		vort_num = 20;
		max_vort = 1.6;
		min_vort = 0.8;
		max_vort_radius = 20;
		min_vort_radius = 20;
		use_peroid_coord = true;
		par_mask.allocate(width,height);

		base_vel_u = 5;
		base_vel_v = 0;
		skip_frames = 20;
		break;
	}

	/*suggest values*/
	/*
	par_num = width*height/3;
	vort_num = 30;
	*/

	char cmdbuf[500];
	sprintf_s(cmdbuf,"if not exist \"%s\" mkdir \"%s\"",out_par_fold,out_par_fold);
	system(cmdbuf);
	sprintf_s(cmdbuf,"if not exist \"%s\" mkdir \"%s\"",out_flow_fold,out_flow_fold);
	system(cmdbuf);
	
	DImage vor_img(width-1,height-1);
	DImage macu_img(width+1,height);
	DImage macv_img(width,height+1);
	DImage u_img(width,height);
	DImage v_img(width,height);
	DImage par_img(width,height);

	BaseType*& vort_pData = vor_img.data();
	BaseType*& macu_pData = macu_img.data();
	BaseType*& macv_pData = macv_img.data();
	BaseType*& u_pData = u_img.data();
	BaseType*& v_pData = v_img.data();


	for(int vor_it = 0; vor_it < vort_num; vor_it++)
	{
		double intensity = (rand()%2-0.5)*2.0*(rand()%101/100.0*(max_vort-min_vort)+min_vort);
		double radius = rand()%101/100.0*(max_vort_radius-min_vort_radius)+min_vort_radius;
		double posx = rand()%width;
		double posy = rand()%height;
		ZQ_PIVSimulator::DrawOneParticle(vor_img,posx,posy,intensity,radius,true);
	}

	ZQ_PoissonSolver::ReconstructCurlField(width,height,vort_pData,macu_pData,macv_pData,100,false);
	ZQ_PoissonSolver::MACtoRegularGrid(width,height,macu_pData,macv_pData,u_pData,v_pData);

	if(use_peroid_coord)
	{
		ZQ_PoissonSolver::RegularGridtoMAC(width,height,u_pData,v_pData,macu_pData,macv_pData,true);

		ZQ_PoissonSolver::SolveOpenPoissonSOR_MACGrid(macu_pData,macv_pData,width,height,1000,false);

		ZQ_PoissonSolver::MACtoRegularGrid(width,height,macu_pData,macv_pData,u_pData,v_pData);
	}
	

	for(int i = 0;i < width*height;i++)
	{
		u_pData[i] += base_vel_u;
		v_pData[i] += base_vel_v;
	}


	ZQ_PIVSimulator piv_simu(width,height,mvobj);

	piv_simu.RandomInit(par_num,u_img,v_img,par_mask);


	int frame = 0;
	char buf[200];

	DImage flow;

	DImage cut_u_img(center_width,center_height),cut_v_img(center_width,center_height);
	DImage cut_par_img(center_width,center_height);

	for(int i = 0;i < skip_frames;i++)
	{
		printf("skip frame [%3d/%3d]...\n",i,skip_frames);
		piv_simu.RunOneFrame(1.0,use_peroid_coord,false);
	}

	do 
	{
		printf("frame [%3d] ...\n",frame);
		
		if(cut_boarder)
		{
			piv_simu.ExportVelocity(u_img,v_img);

			for(int h = 0; h < center_height;h++)
			{
				for(int w = 0;w < center_width;w++)
				{
					cut_u_img.data()[h*center_width+w] = u_img.data()[(h+boarder_size)*width+w+boarder_size];
					cut_v_img.data()[h*center_width+w] = v_img.data()[(h+boarder_size)*width+w+boarder_size];
				}
			}

			cv::Mat show_flow_img = ZQ_ImageIO::SaveFlowToColorImage(cut_u_img,cut_v_img,true,12,64,1);
			sprintf_s(buf,"%s\\flow_%d.png",out_flow_fold,frame);
			cv::imwrite(buf,show_flow_img);
			
			flow.assemble(cut_u_img,cut_v_img);
			sprintf_s(buf,"%s\\flow_%d.di2",out_flow_fold,frame);
			flow.saveImage(buf);

			par_img.reset();
			piv_simu.ExportParticleImage(par_img);

			for(int h = 0;h < center_height;h++)
			{
				for(int w = 0;w < center_width;w++)
				{

					cut_par_img.data()[h*center_width+w] = par_img.data()[(h+boarder_size)*width+w+boarder_size];
				}
			}

			cv::Mat show_par_img = ParImageToIplImage(cut_par_img);
			sprintf_s(buf,"%s\\par_%d.png",out_par_fold,frame);
			cv::imwrite(buf,show_par_img);
			cv::namedWindow("show");
			cv::imshow("show", show_par_img);
			cv::waitKey(10);
		}
		else
		{
			piv_simu.ExportVelocity(u_img,v_img);

			cv::Mat show_flow_img = ZQ_ImageIO::SaveFlowToColorImage(u_img,v_img,true,12,64,1);
			sprintf_s(buf,"%s\\flow_%d.png",out_flow_fold,frame);
			cv::imwrite(buf,show_flow_img);
			
			flow.assemble(u_img,v_img);
			sprintf_s(buf,"%s\\flow_%d.di2",out_flow_fold,frame);
			flow.saveImage(buf);

			par_img.reset();
			piv_simu.ExportParticleImage(par_img);

			cv::Mat show_par_img = ParImageToIplImage(par_img);
			sprintf_s(buf,"%s\\par_%d.png",out_par_fold,frame);
			cv::imwrite(buf,show_par_img);
			cv::namedWindow("show");
			cv::imshow("show", show_par_img);
			cv::waitKey(10);
		}
		
		piv_simu.RunOneFrame(1.0,use_peroid_coord,true);
		frame++;

	} while (frame < 400);

	if(mvobj)
		delete mvobj;
}
Example #16
0
//---------------------------------------------------------------------------------------
// function to convert image to feature image
//---------------------------------------------------------------------------------------
void OpticalFlow::im2feature(DImage &imfeature, const DImage &im)
{
	int width=im.width();
	int height=im.height();
	int nchannels=im.nchannels();
	if(nchannels==1)
	{
		imfeature.allocate(im.width(),im.height(),3);
		DImage imdx,imdy;
		im.dx(imdx,true);
		im.dy(imdy,true);
		_FlowPrecision* data=imfeature.data();
		for(int i=0;i<height;i++)
			for(int j=0;j<width;j++)
			{
				int offset=i*width+j;
				data[offset*3]=im.data()[offset];
				data[offset*3+1]=imdx.data()[offset];
				data[offset*3+2]=imdy.data()[offset];
			}
	}
	else if(nchannels==3)
	{
		DImage grayImage;
		im.desaturate(grayImage);

		imfeature.allocate(im.width(),im.height(),5);
		DImage imdx,imdy;
		grayImage.dx(imdx,true);
		grayImage.dy(imdy,true);
		_FlowPrecision* data=imfeature.data();
		for(int i=0;i<height;i++)
			for(int j=0;j<width;j++)
			{
				int offset=i*width+j;
				data[offset*5]=grayImage.data()[offset];
				data[offset*5+1]=imdx.data()[offset];
				data[offset*5+2]=imdy.data()[offset];
				data[offset*5+3]=im.data()[offset*3+1]-im.data()[offset*3];
				data[offset*5+4]=im.data()[offset*3+1]-im.data()[offset*3+2];
			}
	}
	else
		imfeature.copyData(im);
}
Example #17
0
//--------------------------------------------------------------------------------------------------------
// function to compute optical flow field using two fixed point iterations
// Input arguments:
//     Im1, Im2:						frame 1 and frame 2
//	warpIm2:						the warped frame 2 according to the current flow field u and v
//	u,v:									the current flow field, NOTICE that they are also output arguments
//	
//--------------------------------------------------------------------------------------------------------
void OpticalFlow::SmoothFlowSOR(const DImage &Im1, const DImage &Im2, DImage &warpIm2, DImage &u, DImage &v, 
																    double alpha, int nOuterFPIterations, int nInnerFPIterations, int nSORIterations)
{
	DImage mask,imdx,imdy,imdt;
	int imWidth,imHeight,nChannels,nPixels;
	imWidth=Im1.width();
	imHeight=Im1.height();
	nChannels=Im1.nchannels();
	nPixels=imWidth*imHeight;

	DImage du(imWidth,imHeight),dv(imWidth,imHeight);
	DImage uu(imWidth,imHeight),vv(imWidth,imHeight);
	DImage ux(imWidth,imHeight),uy(imWidth,imHeight);
	DImage vx(imWidth,imHeight),vy(imWidth,imHeight);
	DImage Phi_1st(imWidth,imHeight);
	DImage Psi_1st(imWidth,imHeight,nChannels);

	DImage imdxy,imdx2,imdy2,imdtdx,imdtdy;
	DImage ImDxy,ImDx2,ImDy2,ImDtDx,ImDtDy;
	DImage foo1,foo2;

	double prob1,prob2,prob11,prob22;

	double varepsilon_phi=pow(0.001,2);
	double varepsilon_psi=pow(0.001,2);

	//--------------------------------------------------------------------------
	// the outer fixed point iteration
	//--------------------------------------------------------------------------
	for(int count=0;count<nOuterFPIterations;count++)
	{
		// compute the gradient
		getDxs(imdx,imdy,imdt,Im1,warpIm2);

		// generate the mask to set the weight of the pxiels moving outside of the image boundary to be zero
		genInImageMask(mask,u,v);

		// set the derivative of the flow field to be zero
		du.reset();
		dv.reset();

		//--------------------------------------------------------------------------
		// the inner fixed point iteration
		//--------------------------------------------------------------------------
		for(int hh=0;hh<nInnerFPIterations;hh++)
		{
			// compute the derivatives of the current flow field
			if(hh==0)
			{
				uu.copyData(u);
				vv.copyData(v);
			}
			else
			{
				uu.Add(u,du);
				vv.Add(v,dv);
			}
			uu.dx(ux);
			uu.dy(uy);
			vv.dx(vx);
			vv.dy(vy);

			// compute the weight of phi
			Phi_1st.reset();
			_FlowPrecision* phiData=Phi_1st.data();
			double temp;
			const _FlowPrecision *uxData,*uyData,*vxData,*vyData;
			uxData=ux.data();
			uyData=uy.data();
			vxData=vx.data();
			vyData=vy.data();
			double power_alpha = 0.5;
			for(int i=0;i<nPixels;i++)
			{
				temp=uxData[i]*uxData[i]+uyData[i]*uyData[i]+vxData[i]*vxData[i]+vyData[i]*vyData[i];
				//phiData[i]=power_alpha*pow(temp+varepsilon_phi,power_alpha-1);
				phiData[i] = 0.5/sqrt(temp+varepsilon_phi);
				//phiData[i] = 1/(power_alpha+temp);
			}

			// compute the nonlinear term of psi
			Psi_1st.reset();
			_FlowPrecision* psiData=Psi_1st.data();
			const _FlowPrecision *imdxData,*imdyData,*imdtData;
			const _FlowPrecision *duData,*dvData;
			imdxData=imdx.data();
			imdyData=imdy.data();
			imdtData=imdt.data();
			duData=du.data();
			dvData=dv.data();
		
			double _a  = 10000, _b = 0.1;
			if(nChannels==1)
				for(int i=0;i<nPixels;i++)
				{
					temp=imdtData[i]+imdxData[i]*duData[i]+imdyData[i]*dvData[i];
					//if(temp*temp<0.04)
					// psiData[i]=1/(2*sqrt(temp*temp+varepsilon_psi));
					//psiData[i] = _a*_b/(1+_a*temp*temp);

					// the following code is for log Gaussian mixture probability model
					temp *= temp;
					switch(noiseModel)
					{
					case GMixture:
						prob1 = GMPara.Gaussian(temp,0,0)*GMPara.alpha[0];
						prob2 = GMPara.Gaussian(temp,1,0)*(1-GMPara.alpha[0]);
						prob11 = prob1/(2*GMPara.sigma_square[0]);
						prob22 = prob2/(2*GMPara.beta_square[0]);
						psiData[i] = (prob11+prob22)/(prob1+prob2);
						break;
					case Lap:
						if(LapPara[0]<1E-20)
							continue;
						//psiData[i]=1/(2*sqrt(temp+varepsilon_psi)*LapPara[0]);
                        psiData[i]=1/(2*sqrt(temp+varepsilon_psi));
						break;
					}
				}
			else
				for(int i=0;i<nPixels;i++)
					for(int k=0;k<nChannels;k++)
					{
						int offset=i*nChannels+k;
						temp=imdtData[offset]+imdxData[offset]*duData[i]+imdyData[offset]*dvData[i];
						//if(temp*temp<0.04)
						 // psiData[offset]=1/(2*sqrt(temp*temp+varepsilon_psi));
						//psiData[offset] =  _a*_b/(1+_a*temp*temp);
						temp *= temp;
						switch(noiseModel)
						{
						case GMixture:
							prob1 = GMPara.Gaussian(temp,0,k)*GMPara.alpha[k];
							prob2 = GMPara.Gaussian(temp,1,k)*(1-GMPara.alpha[k]);
							prob11 = prob1/(2*GMPara.sigma_square[k]);
							prob22 = prob2/(2*GMPara.beta_square[k]);
							psiData[offset] = (prob11+prob22)/(prob1+prob2);
							break;
						case Lap:
							if(LapPara[k]<1E-20)
								continue;
							//psiData[offset]=1/(2*sqrt(temp+varepsilon_psi)*LapPara[k]);
                            psiData[offset]=1/(2*sqrt(temp+varepsilon_psi));
							break;
						}
					}
			// prepare the components of the large linear system
			ImDxy.Multiply(Psi_1st,imdx,imdy);
			ImDx2.Multiply(Psi_1st,imdx,imdx);
			ImDy2.Multiply(Psi_1st,imdy,imdy);
			ImDtDx.Multiply(Psi_1st,imdx,imdt);
			ImDtDy.Multiply(Psi_1st,imdy,imdt);

			if(nChannels>1)
			{
				ImDxy.collapse(imdxy);
				ImDx2.collapse(imdx2);
				ImDy2.collapse(imdy2);
				ImDtDx.collapse(imdtdx);
				ImDtDy.collapse(imdtdy);
			}
			else
			{
				imdxy.copyData(ImDxy);
				imdx2.copyData(ImDx2);
				imdy2.copyData(ImDy2);
				imdtdx.copyData(ImDtDx);
				imdtdy.copyData(ImDtDy);
			}
			// laplacian filtering of the current flow field
		    Laplacian(foo1,u,Phi_1st);
			Laplacian(foo2,v,Phi_1st);

			for(int i=0;i<nPixels;i++)
			{
				imdtdx.data()[i] = -imdtdx.data()[i]-alpha*foo1.data()[i];
				imdtdy.data()[i] = -imdtdy.data()[i]-alpha*foo2.data()[i];
			}

			// here we start SOR

			// set omega
			double omega = 1.8;

			du.reset();
			dv.reset();

			for(int k = 0; k<nSORIterations; k++)
				for(int i = 0; i<imHeight; i++)
					for(int j = 0; j<imWidth; j++)
					{
						int offset = i * imWidth+j;
						double sigma1 = 0, sigma2 = 0, coeff = 0;
                        double _weight;

						
						if(j>0)
						{
                            _weight = phiData[offset-1];
							sigma1  += _weight*du.data()[offset-1];
							sigma2  += _weight*dv.data()[offset-1];
							coeff   += _weight;
						}
						if(j<imWidth-1)
						{
                            _weight = phiData[offset];
							sigma1 += _weight*du.data()[offset+1];
							sigma2 += _weight*dv.data()[offset+1];
							coeff   += _weight;
						}
						if(i>0)
						{
                            _weight = phiData[offset-imWidth];
							sigma1 += _weight*du.data()[offset-imWidth];
							sigma2 += _weight*dv.data()[offset-imWidth];
							coeff   += _weight;
						}
						if(i<imHeight-1)
						{
                            _weight = phiData[offset];
							sigma1  += _weight*du.data()[offset+imWidth];
							sigma2  += _weight*dv.data()[offset+imWidth];
							coeff   += _weight;
						}
						sigma1 *= -alpha;
						sigma2 *= -alpha;
						coeff *= alpha;
						 // compute du
						sigma1 += imdxy.data()[offset]*dv.data()[offset];
						du.data()[offset] = (1-omega)*du.data()[offset] + omega/(imdx2.data()[offset] + alpha*0.05 + coeff)*(imdtdx.data()[offset] - sigma1);
						// compute dv
						sigma2 += imdxy.data()[offset]*du.data()[offset];
						dv.data()[offset] = (1-omega)*dv.data()[offset] + omega/(imdy2.data()[offset] + alpha*0.05 + coeff)*(imdtdy.data()[offset] - sigma2);
					}
		}
		u.Add(du);
		v.Add(dv);
		if(interpolation == Bilinear)
			warpFL(warpIm2,Im1,Im2,u,v);
		else
		{
			Im2.warpImageBicubicRef(Im1,warpIm2,u,v);
			warpIm2.threshold();
		}

		//Im2.warpImageBicubicRef(Im1,warpIm2,BicubicCoeff,u,v);

		// estimate noise level
		switch(noiseModel)
		{
		case GMixture:
			estGaussianMixture(Im1,warpIm2,GMPara);
			break;
		case Lap:
			estLaplacianNoise(Im1,warpIm2,LapPara);
		}
	}

}
Example #18
0
// k clusters per channel = k^3 clusters
DPlane DColorCluster::do_clustering(DImage &input, int k, bool ignore_black) 
{
    int cluster_count = k*k*k;
    for(int i=0; i<cluster_count; i++)
      clusters.push_back(DRGBCluster());

    DPlane result(input.rows(), input.cols());
    
    int delta = 256/(k*2);

    for(int a=0, cl=0; a<k; a++)
        for(int b=0; b<k; b++)
            for(int c=0; c<k; c++, cl++)
                clusters[cl].set_mean(
                    DTriple((a+1)*delta, (b+1)*delta, (c+1)*delta));
               

    int changes=1000000000;

    bool done=false;

    while(!done) {
        changes=0;

    for(int i=0; i<input.rows(); i++)
        for(int j=0; j<input.cols(); j++)
        {
            if(ignore_black && input[0][i][j] == 0 && input[1][i][j] == 0 &&
               input[2][i][j] == 0)
            {
                result[i][j] = 0;
                continue;
            }
            int closest_cluster=0;
            double min_dist=1000000000;
            DTriple sample(input[0][i][j], input[1][i][j], input[2][i][j]);
            for(int c=0; c<cluster_count; c++)
                if(clusters[c].distance_to(sample) < min_dist)
                {
                    min_dist = clusters[c].distance_to(sample);
                    closest_cluster = c;
                }
            clusters[closest_cluster].add_sample(sample);
            if(closest_cluster+1 != result[i][j]) 
            {
                result[i][j] = closest_cluster+1;
                changes++;
            }
        }

    if( changes < input.rows() * input.cols() * 0.001) 
        done=true;
    else
        for(int i=0; i<cluster_count; i++) 
        {
            clusters[i].update_mean();
            clusters[i].remove_all();
        }
    
    printf("there were %d changes\n",changes);
    }

    return result;
}
Example #19
0
///Max filter imgSrc with current settings and store result in imgDst
void DMaxFilter::filterImage_(DImage &imgDst, const DImage &imgSrc,
				 bool fAlreadyPadded, DProgress *pProg){
  DMaxFiltType filtType;
  DImage *pImgPad;
  int wKern, hKern;
  int numKernPxls;
  int wUnpad, hUnpad;
#ifndef D_NOTHREADS
  MAX_HUANG_8_THREAD_PARAMS_T rgParms[MAX_MAXFILT_THREADS];
  pthread_t rgThreadID[MAX_MAXFILT_THREADS];
#endif


  filtType = _maxFiltType;

  pImgPad = (DImage*)&imgSrc;
  if(!fAlreadyPadded){
    pImgPad = new DImage();
    imgSrc.padEdges_(*pImgPad, _radiusX, _radiusX, _radiusY, _radiusY,
		     DImage::DImagePadReplicate);
  }

  wUnpad = pImgPad->width()-(_radiusX*2);
  hUnpad = pImgPad->height()-(_radiusY*2);

  wKern = _radiusX * 2 + 1;
  hKern = _radiusY * 2 + 1;
  if(NULL == rgKern){
    rgKern = (unsigned char*)malloc(sizeof(unsigned char) * wKern * hKern);
    if(!rgKern){
      fprintf(stderr, "DMaxFilter::filterImage_() out of memory\n");
      exit(1);
    }
    rgRightEdge = (int*)malloc(sizeof(int)*hKern);
    if(!rgRightEdge){
      fprintf(stderr, "DMaxFilter::filterImage_() out of memory\n");
      exit(1);
    }
    if(DMaxFilt_circle == filtType){
      fill_circle_kern_offsets(_radiusX, _radiusY, rgKern,
			       rgRightEdge, &numKernPxls);
    }
    else{
      fill_square_kern_offsets(_radiusX, _radiusY, rgKern,
			       rgRightEdge, &numKernPxls);
    }
  }
  
  switch(imgSrc.getImageType()){
    case DImage::DImage_u8:
      {
	imgDst.create(wUnpad, hUnpad, DImage::DImage_u8, 1,
		      imgSrc.getAllocMethod());
#ifndef D_NOTHREADS
	for(int tnum = 1; tnum < _numThreads; ++tnum){
	  rgParms[tnum].pImgDst = &imgDst;
	  rgParms[tnum].pImgSrc = pImgPad;
	  rgParms[tnum].radiusX = _radiusX;
	  rgParms[tnum].radiusY = _radiusY;
	  rgParms[tnum].wKern = wKern;
	  rgParms[tnum].hKern = hKern;
	  rgParms[tnum].rgKern = rgKern;
	  rgParms[tnum].numKernPxls = numKernPxls;
	  rgParms[tnum].rgRightEdge = rgRightEdge;
	  rgParms[tnum].pProg = NULL;
	  rgParms[tnum].progStart = 0;
	  rgParms[tnum].progMax = 1;
	  rgParms[tnum].threadNumber = tnum;
	  rgParms[tnum].numThreads = _numThreads;

	  if(0 != pthread_create(&rgThreadID[tnum], NULL,
				 DMaxFilter::DMaxFilter_Huang8threadWrap,
				 &rgParms[tnum])){
	    fprintf(stderr, "DMaxFilter::filterImage_() failed to spawn "
		    "thread #%d. Exiting.\n", tnum);
	    exit(1);
	  }
	}
#endif
	maxFiltHuang_u8(imgDst, *pImgPad, _radiusX, _radiusY,
			wKern, hKern, rgKern, numKernPxls,
			rgRightEdge, pProg, 0, hUnpad+1, 0, _numThreads);
#ifndef D_NOTHREADS
	for(int tnum = 1; tnum < _numThreads; ++tnum){
	  if(pthread_join(rgThreadID[tnum],NULL))
	    fprintf(stderr, "DMaxFilter::filterImage_() failed to join "
		    "thread %d\n", tnum);
	}
#endif
	if(NULL != pProg){
	  pProg->reportStatus(hUnpad+1, 0, hUnpad+1);//report progress complete
	}	  
      }
      break;
    case DImage::DImage_RGB:
      {
	DImage imgR, imgG, imgB;
	DImage imgRDst, imgGDst, imgBDst;

	imgRDst.create(wUnpad, hUnpad, DImage::DImage_u8, 1,
		       imgSrc.getAllocMethod());
	imgGDst.create(wUnpad, hUnpad, DImage::DImage_u8, 1,
		       imgSrc.getAllocMethod());
	imgBDst.create(wUnpad, hUnpad, DImage::DImage_u8, 1,
		       imgSrc.getAllocMethod());

	pImgPad->splitRGB(imgR, imgG, imgB);

#ifndef D_NOTHREADS
	for(int tnum = 1; tnum < _numThreads; ++tnum){
	  rgParms[tnum].pImgDst = &imgRDst;
	  rgParms[tnum].pImgSrc = &imgR;
	  rgParms[tnum].radiusX = _radiusX;
	  rgParms[tnum].radiusY = _radiusY;
	  rgParms[tnum].wKern = wKern;
	  rgParms[tnum].hKern = hKern;
	  rgParms[tnum].rgKern = rgKern;
	  rgParms[tnum].numKernPxls = numKernPxls;
	  rgParms[tnum].rgRightEdge = rgRightEdge;
	  rgParms[tnum].pProg = NULL;
	  rgParms[tnum].progStart = 0;
	  rgParms[tnum].progMax = 1;
	  rgParms[tnum].threadNumber = tnum;
	  rgParms[tnum].numThreads = _numThreads;

	  if(0 != pthread_create(&rgThreadID[tnum], NULL,
				 DMaxFilter::DMaxFilter_Huang8threadWrap,
				 &rgParms[tnum])){
	    fprintf(stderr, "DMaxFilter::filterImage_() failed to spawn "
		    "thread #%d. Exiting.\n",tnum);
	    exit(1);
	  }
	}
#endif
	maxFiltHuang_u8(imgRDst, imgR, _radiusX, _radiusY,
			wKern, hKern, rgKern, numKernPxls,
			rgRightEdge, pProg, 0, 3 * hUnpad);
#ifndef D_NOTHREADS
	for(int tnum = 1; tnum < _numThreads; ++tnum){
	  if(pthread_join(rgThreadID[tnum],NULL))
	    fprintf(stderr, "DMaxFilter::filterImage_() failed to join "
		    "thread %d\n", tnum);
	}
	for(int tnum = 1; tnum < _numThreads; ++tnum){
	  rgParms[tnum].pImgDst = &imgGDst;
	  rgParms[tnum].pImgSrc = &imgG;
	  if(0 != pthread_create(&rgThreadID[tnum], NULL,
				 DMaxFilter::DMaxFilter_Huang8threadWrap,
				 &rgParms[tnum])){
	    fprintf(stderr, "DMaxFilter::filterImage_() failed to spawn "
		    "thread #%d. Exiting.\n",tnum);
	    exit(1);
	  }
	}
#endif
	maxFiltHuang_u8(imgGDst, imgG, _radiusX, _radiusY,
			wKern, hKern, rgKern, numKernPxls,
			rgRightEdge, pProg, hUnpad, 3 * hUnpad);
#ifndef D_NOTHREADS
	for(int tnum = 1; tnum < _numThreads; ++tnum){
	  if(pthread_join(rgThreadID[tnum],NULL))
	    fprintf(stderr, "DMaxFilter::filterImage_() failed to join "
		    "thread %d\n", tnum);
	}

	for(int tnum = 1; tnum < _numThreads; ++tnum){
	  rgParms[tnum].pImgDst = &imgBDst;
	  rgParms[tnum].pImgSrc = &imgB;
	  if(0 != pthread_create(&rgThreadID[tnum], NULL,
				 DMaxFilter::DMaxFilter_Huang8threadWrap,
				 &rgParms[tnum])){
	    fprintf(stderr, "DMaxFilter::filterImage_() failed to spawn "
		    "thread #%d. Exiting.\n",tnum);
	    exit(1);
	  }
	}
#endif
	maxFiltHuang_u8(imgBDst, imgB, _radiusX, _radiusY,
			wKern, hKern, rgKern, numKernPxls,
			rgRightEdge, pProg, 2 * hUnpad, 3 * hUnpad+1);
#ifndef D_NOTHREADS
	for(int tnum = 1; tnum < _numThreads; ++tnum){
	  if(pthread_join(rgThreadID[tnum],NULL))
	    fprintf(stderr, "DMaxFilter::filterImage_() failed to join "
		    "thread %d\n", tnum);
	}
#endif
	if(NULL != pProg){
	  pProg->reportStatus(3*hUnpad+1,0,3*hUnpad+1);//report complete
	}	  
	imgDst.combineRGB(imgRDst, imgGDst, imgBDst);
      }
      break;
    case DImage::DImage_dbl_multi:
      {
	int w, h, wm1, hm1; // width, height of padded image
	double *pDst;
	double *pPad;
	double *rgWindowBuff;
	
	fprintf(stderr, "DMaxFilter::filterImage_() performing brute-force "
		"(slow) max filter on double image... NOT YET IMPLEMENTED!\n");
	exit(1);
	// w = pImgPad->width();
	// h = pImgPad->height();
	// wm1=w-1;
	// hm1 = h-1;
	// imgDst.create(wUnpad, hUnpad, DImage::DImage_dbl_multi,
	// 	      imgSrc.numChannels(), imgSrc.getAllocMethod());
	// rgWindowBuff = (double*)malloc(sizeof(double)*wKern*hKern);
	// D_CHECKPTR(rgWindowBuff);
	// for(int chan = 0; chan < imgSrc.numChannels(); ++chan){
	//   pDst = imgDst.dataPointer_dbl(chan);
	//   pPad = pImgPad->dataPointer_dbl(chan);
	//   for(int y = 0, idxDst = 0; y < hUnpad; ++y){
	//     int idxPad;
	//     idxPad = (y+_radiusY)*w+_radiusX;
	//     for(int x=0; x < wUnpad; ++x, ++idxDst, ++idxPad){
	//       int count;
	//       count = 0;
	//       for(int dy = -_radiusY; dy <= _radiusY; ++dy){
	// 	for(int dx = -_radiusX; dx <= _radiusX; ++dx){
	// 	  rgWindowBuff[count] = pPad[idxPad+(dy*w)+dx];
	// 	  ++count;
	// 	}
	//       }
	//       // find max
	//       qsort((void*)rgWindowBuff, count, sizeof(double),compareDoubles);
	//       pDst[idxDst] = rgWindowBuff[count / 2];
	//     }//end for(x...
	//   }//end for(y...
	// }//end for(chan...
	// free(rgWindowBuff);
      }//end block in case DImage_dbl_multi
      break;
    default:
      //TODO: finish implementing this
      fprintf(stderr, "DMaxFilter::filterImage_() not yet implemented for "
	      "some image types\n");
      exit(1);
      break;
  }
  if(!fAlreadyPadded){
    delete pImgPad;
    pImgPad = NULL;
  }

}
Example #20
0
/** imgDst will be 2*radius pixels less wide and high than imgSrc
 * because of the padding that is added before calling this function.
 * This function requires that imgDst.create() has already been called
 * with the proper w,h,imgType,etc.
 */
void DMaxFilter::maxFiltHuang_u8_square(DImage &imgDst,
					   const DImage &imgSrc,
					   int radiusX, int radiusY,
					   int wKern, int hKern,
					   D_uint8 *rgKern,
					   int numKernPxls,
					   DProgress *pProg,
					   int progStart, int progMax,
					   int threadNumber, int numThreads){
  int rgHist[256];
  int max;
  unsigned char valTmp;
  int idxDst;
  int idx3;
  D_uint8 *pTmp; // pointer to padded image data
  int wTmp, hTmp; // width, height of imgSrc
  int w, h; // width, height of imgDst
  D_uint8 *pDst;

  wTmp = imgSrc.width();
  hTmp = imgSrc.height();
  w = wTmp - radiusX*2;
  h = hTmp - radiusY*2;
  pDst = imgDst.dataPointer_u8();
  pTmp = imgSrc.dataPointer_u8();

  for(int y = threadNumber; y < h; y += numThreads){
    // update progress report and check if user cancelled the operation
    if((NULL != pProg) && (0 == (y & 0x0000003f))){
      if(0 != pProg->reportStatus(progStart + y, 0, progMax)){
	// the operation has been cancelled
	pProg->reportStatus(-1, 0, progMax); // report cancel acknowledged
	return;
      }
    }

    // position window at the beginning of a new row and fill the kernel, hist
    memset(rgHist, 0, sizeof(int)*256);
    for(int kr = 0, kidx =0; kr < hKern; ++kr){
      for(int kc = 0; kc < wKern; ++kc, ++kidx){
	if(rgKern[kidx]){ // pixel is part of the kernel mask
	  ++(rgHist[pTmp[(y+kr)*wTmp+kc]]);//add pixel val to histogram
	}
      }
    }
    // calculate max for first spot
    for(max = 255; (max > 0) && (0==rgHist[max]); --max){
      // do nothing
    }

    // put the max in the spot we're at
    idxDst = y*w;
    pDst[idxDst] = (unsigned char)max;
    
    // remove pixels from leftmost column
    idx3 = y*wTmp+radiusX;
    for(int ky = 0; ky < hKern; ++ky){
      valTmp = pTmp[idx3 - wKern];
      --(rgHist[valTmp]);
      if((valTmp==max)&&(0 == rgHist[valTmp])){//update the max
	for(;(max>0)&&(0==rgHist[max]); --max){
	  //do nothing
	}
      }
      idx3 += wTmp;
    }

    for(int x=1;  x < w;  ++x){
      ++idxDst;
      // add pixels from the right-hand side of kernel (after moving over one)
      idx3 = y*wTmp+x+radiusX;
      for(int ky = 0; ky < hKern; ++ky){
	valTmp = pTmp[idx3 + wKern];
	if(valTmp > max)//update the max
	  max = valTmp;
	++(rgHist[valTmp]);
	idx3 += wTmp;
      }
      
      // put the max value in the destination pixel
      pDst[idxDst] = (unsigned char)max;

      // remove pixels from leftmost column for next time through loop
      if(x < (w-1)){//don't need to remove left edge if going to a new row
	idx3 = y*wTmp+x+radiusX;
	for(int ky = 0; ky < hKern; ++ky){
	  valTmp = pTmp[idx3 - wKern];
	  --(rgHist[valTmp]);
	  if((valTmp==max)&&(0 == rgHist[valTmp])){//update the max
	    for(;(max>0)&&(0==rgHist[max]); --max){
	      //do nothing
	    }
	  }
	  idx3 += wTmp;
	} // end for(ky...
      } // end if

    } // end for (x=1; ...

  }// end for(y=0...
  // report progress
  if(NULL != pProg){
    pProg->reportStatus(progStart + h, 0, progMax);
  }
}
Example #21
0
BOOL CsMIShopDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
	if (!CDocument::OnOpenDocument(lpszPathName))
		return FALSE;

	// open CVoxel object
	
	m_pVoxel = new CVoxel<short>(lpszPathName);

	m_pDrawLayerZ = new cv::Mat[m_pVoxel->m_nZ];
	m_pDrawLayerY = new cv::Mat[m_pVoxel->m_nY];
	m_pDrawLayerX = new cv::Mat[m_pVoxel->m_nX];

	
	for (int i = 0; i < m_pVoxel->m_nZ; i++)
		m_pDrawLayerZ[i].create(m_pVoxel->m_nY,m_pVoxel->m_nX,CV_8UC1);
	for (int i = 0; i < m_pVoxel->m_nY; i++)
		m_pDrawLayerY[i].create(m_pVoxel->m_nX, m_pVoxel->m_nZ, CV_8UC1);
	for (int i = 0; i < m_pVoxel->m_nX; i++)
		m_pDrawLayerX[i].create(m_pVoxel->m_nZ,m_pVoxel->m_nY,CV_8UC1);

	
	m_iMaxValue = m_pVoxel->m_nMaxI;
	m_iMinValue = m_pVoxel->m_nMinI;

	//for(int z = 0; z < m_pVoxel->m_nZ; z++)
	//for(int y = 0; y < m_pVoxel->m_nY; y++)
	//for(int x = 0; x < m_pVoxel->m_nX; x++)
	//{
	//	if(m_pVoxel->m_pData[z*m_pVoxel->m_nY*m_pVoxel->m_nX + y*m_pVoxel->m_nX + x] > m_iMaxValue)
	//		m_iMaxValue = m_pVoxel->m_pData[z*m_pVoxel->m_nY*m_pVoxel->m_nX + y*m_pVoxel->m_nX + x];
	//	if (m_pVoxel->m_pData[z*m_pVoxel->m_nY*m_pVoxel->m_nX + y*m_pVoxel->m_nX + x] < m_iMinValue)
	//		m_iMinValue = m_pVoxel->m_pData[z*m_pVoxel->m_nY*m_pVoxel->m_nX + y*m_pVoxel->m_nX + x];
	//	
	//}

#if 0
	// TEST 3: to warp with thin-plate spline - layer separation
#endif 

#if 0
	// TEST 2: try to extract bone (which has no motion) 
	int imgw = m_pVoxel->m_nX;
	int imgh = m_pVoxel->m_nY;
	int nfrm = m_pVoxel->m_nZ;
	//		construct average image
	cv::Mat avg = cv::Mat::zeros(imgh, imgw, CV_32F);
	for ( int y = 0; y < m_pVoxel->m_nY; y++ ) {
		float *avgp = avg.ptr<float>(y);
		for ( int x = 0; x < m_pVoxel->m_nX; x++ ) {
			for ( int i = 0; i < m_pVoxel->m_nZ; i++ ) {
				avgp[x] += m_pVoxel->GetAt(x,y,i);
			}
		}
	}
	avg = avg/(float)nfrm;
	//		save average image
	cv::Mat avg_8u;
	avg.convertTo(avg_8u, CV_8U);
	cv::imwrite("avg_img.png", avg_8u);

	//		compute subtraction image for all frames
	for ( int i = 0; i < nfrm; i++ ) {
		cv::Mat frm_idx = m_pVoxel->VoxelZSlice2cvMat<short>(i);
		cv::Mat frm_idx_f;
		frm_idx.convertTo(frm_idx_f, CV_32F);
		cv::Mat frm_sub = cv::abs(frm_idx_f - avg);
		double minf, maxf;
		cv::minMaxIdx(frm_sub, &minf, &maxf);
		cv::Mat frm_sub_8u;
		frm_sub.convertTo(frm_sub_8u, CV_8U, 255.0/(maxf-minf), -minf);
		char path[MAX_PATH];
		sprintf(path, "frm_sub_%04d.png", i);
		cv::imwrite(path, frm_sub_8u);
	}
#endif

	// TEST 1: compare optical flow between consecutive and synchronized frames
	// 20140825 ****** OPTICAL FLOW FAILS TOTALLY FOR 2D+t CARDIAC X-RAY IMAGES ****** // 
#if 0
	//////////////////////////////////////////////////////////
	// 20140820 *** ASSUME VESSEL IMAGE HAS BEEN LOADED *** //
	// set the parameters
	//     para(1)--alpha (1), the regularization weight
	//     para(2)--ratio (0.5), the downsample ratio
	//     para(3)--minWidth (40), the width of the coarsest level
	//     para(4)--nOuterFPIterations (3), the number of outer fixed point iterations
	//     para(5)--nInnerFPIterations (1), the number of inner fixed point iterations
	//     para(6)--nSORIterations (20), the number of SOR iterations
	double alpha= 0.012;
	double ratio=0.75;
	int minWidth= 32;
	int nOuterFPIterations = 5;//5;
	int nInnerFPIterations = 1;//3;
	int nSORIterations= 20;//40;

	// compute optical flow between consecutive frames
	int n_src = 24;
	int n_dst = 36;
	DImage frm_src = m_pVoxel->VoxelZSlice2DImage(n_src);
	DImage frm_dst = m_pVoxel->VoxelZSlice2DImage(n_dst);
	DImage cvx,cvy,cwarpI2;
	OpticalFlow::Coarse2FineFlow(cvx,cvy,cwarpI2,frm_src,frm_dst,
		alpha,ratio,minWidth,nOuterFPIterations,nInnerFPIterations,nSORIterations);
	char str[MAX_PATH], str_dst[MAX_PATH];
	sprintf(str, "frm%04d.png", n_src);
	frm_src.imwrite(str);
	sprintf(str, "frm%04d.png", n_dst);
	frm_dst.imwrite(str);
	sprintf(str, "warp_%04d_%04d.png", n_src, n_dst);
	cwarpI2.imwrite(str);
	DImage vimgc = OptFlowVec2Color_DImage(&cvx, &cvy);
	sprintf(str, "motvec_%04d_%04d.png", n_src, n_dst);
	vimgc.imwrite(str);
	//DImage nimgc = OptFlowVecNorm2DImage(&cvx, &cvy, 0.5);
	DImage nimgc = OptFlowVecNorm2DImage(&cvx, &cvy);
	sprintf(str, "motnorm_%04d_%04d.png", n_src, n_dst);
	nimgc.imwrite(str);
#endif
	//////////////////////////////////////////////////////////

	return TRUE;
}
Example #22
0
/**This function calculates the vertical profile (the length of
 * profile will be the same as the height of the image).  However,
 * instead of projecting pixels straight across to the vertical axis,
 * the projection is taken using lines angled through the middle
 * (x=width/2) of the image.  Linear interpolation is used for
 * sampling the image pixel values since the y-position on the
 * projection lines will normally be "between" two pixels for any
 * given x-position.  The function is intended only for angles between
 * -45 and 45 degrees, since otherwise the slope will be too steep for
 * the assumption I am making (I am steping through the x-values and
 * calculating the y-values.  If the slope is steeper, I should do the
 * opposite.  As a "to-do," maybe we should just check the angle and
 * handle the two cases individually). */
void DProfile::getAngledVertProfile(const DImage &img, double ang,
				    int fNormalize){
  double m;
  int x;
  double y, val;
  int hm1;
  double xc;
  int numPixels;
  D_uint8 *pimg;
  int w, h;
  int initialOffset=0;
  int *rgYoffsets;
  double *rgBotWeights;
  int yTop;
  int yTopPrev=0;
  int imglen;

  if(DImage::DImage_u8 != img.getImageType()){
    fprintf(stderr,
	    "DProfile::getAngledVertProfile() currently only supports 8-bit "
	    "grayscale images\n");
    abort();
  }
  w=img.width();
  h=img.height();
  pimg = img.dataPointer_u8();

  if(NULL == rgProf){
    rgProf = (double*)malloc(h * sizeof(double));
    D_CHECKPTR(rgProf);
    len = h;
  }
  else{
    if(len != h){
      rgProf = (double*)realloc(rgProf,h*sizeof(double));
      D_CHECKPTR(rgProf);
      len = h;
    }
  }
//   memset(rgProf, 0, sizeof(double) * h);

  rgYoffsets = (int*)malloc(sizeof(int)*w);
  D_CHECKPTR(rgYoffsets);
  rgBotWeights = (double*)malloc(sizeof(double)*w);
  D_CHECKPTR(rgBotWeights);

  m = 1 * tan(DMath::degreesToRadians(ang)); /* dy per dx=1 */
  xc = w / 2.;

  // initialOffset is the y-offset of first pixel, rgYoffsets[i] for i=1...w-1
  // are the relative offsets from rgYoffsets[i-1] of the top pixel
  // rgBotWeights[i] is the interpolation weight of the bottom pixel, while
  // 1.-rgBotWeights[i] is the interpolation weight of the top pixel.
  for(x = 0; x < w; ++x){
    y = m * ((double)x - xc);
    yTop = (int)(floor(y));
    rgBotWeights[x] = y - (double)(yTop);
    if(0 == x){
      rgYoffsets[0] = 0;
      initialOffset = yTop;
    }
    else
      rgYoffsets[x] = (yTop - yTopPrev);
    yTopPrev = yTop;
  }

  hm1 = h - 1;
  imglen = w * hm1;

  for(int i = 0; i < h; ++i){ /* profile index */
    int idx;
    rgProf[i] = 0.;
    numPixels = 0;
    idx = w * (i + initialOffset);
    for(x = 0; x < w; ++x, ++idx){
      idx += (w*rgYoffsets[x]);// go to next row if needed
      if((idx <0) || (idx >= imglen)) // out of bounds
	continue;
      ++numPixels;
      val = rgBotWeights[x] * pimg[idx] + (1.-rgBotWeights[x]) * pimg[idx+w];
      rgProf[i] += val;
    }
    if((numPixels > 0) && fNormalize)
      rgProf[i] /= numPixels;
  }

  free(rgYoffsets);
  free(rgBotWeights);
}
Example #23
0
//--------------------------------------------------------------------------------------------------------
// function to compute optical flow field using two fixed point iterations
// Input arguments:
//     Im1, Im2:						frame 1 and frame 2
//	warpIm2:						the warped frame 2 according to the current flow field u and v
//	u,v:									the current flow field, NOTICE that they are also output arguments
//	
//--------------------------------------------------------------------------------------------------------
void OpticalFlow::SmoothFlowSOR(const DImage &Im1, const DImage &Im2, DImage &warpIm2, DImage &u, DImage &v, 
																    double alpha, int nOuterFPIterations, int nInnerFPIterations, int nSORIterations)
{
	// DImage mask,imdx,imdy,imdt;
	DImage imdx,imdy,imdt;
	int imWidth,imHeight,nChannels,nPixels;
	imWidth=Im1.width();
	imHeight=Im1.height();
	nChannels=Im1.nchannels();
	nPixels=imWidth*imHeight;

	DImage du(imWidth,imHeight),dv(imWidth,imHeight);
	DImage uu(imWidth,imHeight),vv(imWidth,imHeight);
	DImage ux(imWidth,imHeight),uy(imWidth,imHeight);
	DImage vx(imWidth,imHeight),vy(imWidth,imHeight);
	DImage Phi_1st(imWidth,imHeight);
	DImage Psi_1st(imWidth,imHeight,nChannels);

	DImage imdxy,imdx2,imdy2,imdtdx,imdtdy;
	DImage ImDxy,ImDx2,ImDy2,ImDtDx,ImDtDy;
	DImage foo1,foo2;

	double varepsilon_phi=pow(0.001,2);
	double varepsilon_psi=pow(0.001,2);

	//--------------------------------------------------------------------------
	// the outer fixed point iteration
	//--------------------------------------------------------------------------
	for(int count=0;count<nOuterFPIterations;count++)
	{
		// compute the gradient
		getDxs(imdx,imdy,imdt,Im1,warpIm2);

		// generate the mask to set the weight of the pxiels moving outside of the image boundary to be zero
		// genInImageMask(mask,u,v);

		// set the derivative of the flow field to be zero
		du.reset();
		dv.reset();

		//--------------------------------------------------------------------------
		// the inner fixed point iteration
		//--------------------------------------------------------------------------
		for(int hh=0;hh<nInnerFPIterations;hh++)
		{
			// compute the derivatives of the current flow field
			if(hh==0)
			{
				uu.copyData(u);
				vv.copyData(v);
			}
			else
			{
				uu.Add(u,du);
				vv.Add(v,dv);
			}
			uu.dx(ux);
			uu.dy(uy);
			vv.dx(vx);
			vv.dy(vy);

			// compute the weight of phi
			Phi_1st.reset();
			_FlowPrecision* phiData=Phi_1st.data();
			double temp;
			const _FlowPrecision *uxData,*uyData,*vxData,*vyData;
			uxData=ux.data();
			uyData=uy.data();
			vxData=vx.data();
			vyData=vy.data();
			for(int i=0;i<nPixels;i++)
			{
				temp=uxData[i]*uxData[i]+uyData[i]*uyData[i]+vxData[i]*vxData[i]+vyData[i]*vyData[i];
				phiData[i] = 0.5/sqrt(temp+varepsilon_phi);
			}


			// compute the nonlinear term of psi
			Psi_1st.reset();
			_FlowPrecision* psiData=Psi_1st.data();
			const _FlowPrecision *imdxData,*imdyData,*imdtData;
			const _FlowPrecision *duData,*dvData;
			imdxData=imdx.data();
			imdyData=imdy.data();
			imdtData=imdt.data();
			duData=du.data();
			dvData=dv.data();

			if(nChannels==1)
				for(int i=0;i<nPixels;i++)
				{
					temp=imdtData[i]+imdxData[i]*duData[i]+imdyData[i]*dvData[i];
                    temp *= temp;
                    psiData[i]=1/(2*sqrt(temp+varepsilon_psi));
				}
			else
				for(int i=0;i<nPixels;i++)
					for(int k=0;k<nChannels;k++)
					{
						int offset=i*nChannels+k;
						temp=imdtData[offset]+imdxData[offset]*duData[i]+imdyData[offset]*dvData[i];
						temp *= temp;
                        psiData[offset]=1/(2*sqrt(temp+varepsilon_psi));
					}



			// prepare the components of the large linear system
			ImDxy.Multiply(Psi_1st,imdx,imdy);
			ImDx2.Multiply(Psi_1st,imdx,imdx);
			ImDy2.Multiply(Psi_1st,imdy,imdy);
			ImDtDx.Multiply(Psi_1st,imdx,imdt);
			ImDtDy.Multiply(Psi_1st,imdy,imdt);


			if(nChannels>1)
			{
				ImDxy.collapse(imdxy);
				ImDx2.collapse(imdx2);
				ImDy2.collapse(imdy2);
				ImDtDx.collapse(imdtdx);
				ImDtDy.collapse(imdtdy);
			}
			else
			{
				imdxy.copyData(ImDxy);
				imdx2.copyData(ImDx2);
				imdy2.copyData(ImDy2);
				imdtdx.copyData(ImDtDx);
				imdtdy.copyData(ImDtDy);
			}
			// laplacian filtering of the current flow field
		    Laplacian(foo1,u,Phi_1st);
			Laplacian(foo2,v,Phi_1st);

			for(int i=0;i<nPixels;i++)
			{
				imdtdx.data()[i] = -imdtdx.data()[i]-alpha*foo1.data()[i];
				imdtdy.data()[i] = -imdtdy.data()[i]-alpha*foo2.data()[i];
			}


			// here we start SOR

			// set omega
			double omega = 1.8;

			du.reset();
			dv.reset();

			for(int k = 0; k<nSORIterations; k++)
				for(int i = 0; i<imHeight; i++)
					for(int j = 0; j<imWidth; j++)
					{
						int offset = i * imWidth+j;
						double sigma1 = 0, sigma2 = 0, coeff = 0;
                        double _weight;
						
						if(j>0)
						{
                            _weight = phiData[offset-1];
							sigma1  += _weight*du.data()[offset-1];
							sigma2  += _weight*dv.data()[offset-1];
							coeff   += _weight;
						}
						if(j<imWidth-1)
						{
                            _weight = phiData[offset];
							sigma1 += _weight*du.data()[offset+1];
							sigma2 += _weight*dv.data()[offset+1];
							coeff  += _weight;
						}
						if(i>0)
						{
                            _weight = phiData[offset-imWidth];
							sigma1 += _weight*du.data()[offset-imWidth];
							sigma2 += _weight*dv.data()[offset-imWidth];
							coeff   += _weight;
						}
						if(i<imHeight-1)
						{
                            _weight = phiData[offset];
							sigma1  += _weight*du.data()[offset+imWidth];
							sigma2  += _weight*dv.data()[offset+imWidth];
							coeff   += _weight;
						}
						sigma1 *= -alpha;
						sigma2 *= -alpha;
						coeff *= alpha;
						 // compute du
						sigma1 += imdxy.data()[offset]*dv.data()[offset];
						du.data()[offset] = (1-omega)*du.data()[offset] + omega/(imdx2.data()[offset] + /*alpha*0.05*/ + coeff)*(imdtdx.data()[offset] - sigma1);
						// compute dv
						sigma2 += imdxy.data()[offset]*du.data()[offset];
						dv.data()[offset] = (1-omega)*dv.data()[offset] + omega/(imdy2.data()[offset] + /*alpha*0.05*/ + coeff)*(imdtdy.data()[offset] - sigma2);
					}
		}




		u.Add(du);
		v.Add(dv);
		if(interpolation == Bilinear){
			warpFL(warpIm2,Im1,Im2,u,v);
        }
		else
		{
			Im2.warpImageBicubicRef(Im1,warpIm2,u,v);
			warpIm2.threshold();
		}
	}

}
Example #24
0
//--------------------------------------------------------------------------------------------------------
// function to compute optical flow field using two fixed point iterations
// Input arguments:
//     Im1, Im2:						frame 1 and frame 2
//	warpIm2:						the warped frame 2 according to the current flow field u and v
//	u,v:									the current flow field, NOTICE that they are also output arguments
//	
//--------------------------------------------------------------------------------------------------------
void OpticalFlow::SmoothFlowPDE(const DImage &Im1, const DImage &Im2, DImage &warpIm2, DImage &u, DImage &v, 
																    double alpha, int nOuterFPIterations, int nInnerFPIterations, int nCGIterations)
{
	DImage mask,imdx,imdy,imdt;
	int imWidth,imHeight,nChannels,nPixels;
	imWidth=Im1.width();
	imHeight=Im1.height();
	nChannels=Im1.nchannels();
	nPixels=imWidth*imHeight;

	DImage du(imWidth,imHeight),dv(imWidth,imHeight);
	DImage uu(imWidth,imHeight),vv(imWidth,imHeight);
	DImage ux(imWidth,imHeight),uy(imWidth,imHeight);
	DImage vx(imWidth,imHeight),vy(imWidth,imHeight);
	DImage Phi_1st(imWidth,imHeight);
	DImage Psi_1st(imWidth,imHeight,nChannels);

	DImage imdxy,imdx2,imdy2,imdtdx,imdtdy;
	DImage ImDxy,ImDx2,ImDy2,ImDtDx,ImDtDy;
	DImage A11,A12,A22,b1,b2;
	DImage foo1,foo2;

	// compute bicubic interpolation coeff
	//DImage BicubicCoeff;
	//Im2.warpImageBicubicCoeff(BicubicCoeff);
	double prob1,prob2,prob11,prob22;
	// variables for conjugate gradient
	DImage r1,r2,p1,p2,q1,q2;
	double* rou;
	rou=new double[nCGIterations];

	double varepsilon_phi=pow(0.001,2);
	double varepsilon_psi=pow(0.001,2);

	//--------------------------------------------------------------------------
	// the outer fixed point iteration
	//--------------------------------------------------------------------------
	for(int count=0;count<nOuterFPIterations;count++)
	{
		// compute the gradient
		getDxs(imdx,imdy,imdt,Im1,warpIm2);

		// generate the mask to set the weight of the pxiels moving outside of the image boundary to be zero
		genInImageMask(mask,u,v);

		// set the derivative of the flow field to be zero
		du.reset();
		dv.reset();

		//--------------------------------------------------------------------------
		// the inner fixed point iteration
		//--------------------------------------------------------------------------
		for(int hh=0;hh<nInnerFPIterations;hh++)
		{
			// compute the derivatives of the current flow field
			if(hh==0)
			{
				uu.copyData(u);
				vv.copyData(v);
			}
			else
			{
				uu.Add(u,du);
				vv.Add(v,dv);
			}
			uu.dx(ux);
			uu.dy(uy);
			vv.dx(vx);
			vv.dy(vy);

			// compute the weight of phi
			Phi_1st.reset();
			_FlowPrecision* phiData=Phi_1st.data();
			_FlowPrecision temp;
			const _FlowPrecision *uxData,*uyData,*vxData,*vyData;
			uxData=ux.data();
			uyData=uy.data();
			vxData=vx.data();
			vyData=vy.data();
			double power_alpha = 0.5;
			for(int i=0;i<nPixels;i++)
			{
				temp=uxData[i]*uxData[i]+uyData[i]*uyData[i]+vxData[i]*vxData[i]+vyData[i]*vyData[i];
				//phiData[i]=power_alpha*pow(temp+varepsilon_phi,power_alpha-1);
				phiData[i] = 0.5/sqrt(temp+varepsilon_phi);
				//phiData[i] = 1/(power_alpha+temp);
			}

			// compute the nonlinear term of psi
			Psi_1st.reset();
			_FlowPrecision* psiData=Psi_1st.data();
			const _FlowPrecision *imdxData,*imdyData,*imdtData;
			const _FlowPrecision *duData,*dvData;
			imdxData=imdx.data();
			imdyData=imdy.data();
			imdtData=imdt.data();
			duData=du.data();
			dvData=dv.data();
		
			double _a  = 10000, _b = 0.1;
			if(nChannels==1)
				for(int i=0;i<nPixels;i++)
				{
					temp=imdtData[i]+imdxData[i]*duData[i]+imdyData[i]*dvData[i];
					//if(temp*temp<0.04)
					// psiData[i]=1/(2*sqrt(temp*temp+varepsilon_psi));
					//psiData[i] = _a*_b/(1+_a*temp*temp);

					// the following code is for log Gaussian mixture probability model
					temp *= temp;
					switch(noiseModel)
					{
					case GMixture:
						prob1 = GMPara.Gaussian(temp,0,0)*GMPara.alpha[0];
						prob2 = GMPara.Gaussian(temp,1,0)*(1-GMPara.alpha[0]);
						prob11 = prob1/(2*GMPara.sigma_square[0]);
						prob22 = prob2/(2*GMPara.beta_square[0]);
						psiData[i] = (prob11+prob22)/(prob1+prob2);
						break;
					case Lap:
						if(LapPara[0]<1E-20)
							continue;
						psiData[i]=1/(2*sqrt(temp+varepsilon_psi)*LapPara[0]);
						break;
					}
				}
			else
				for(int i=0;i<nPixels;i++)
					for(int k=0;k<nChannels;k++)
					{
						int offset=i*nChannels+k;
						temp=imdtData[offset]+imdxData[offset]*duData[i]+imdyData[offset]*dvData[i];
						//if(temp*temp<0.04)
						 // psiData[offset]=1/(2*sqrt(temp*temp+varepsilon_psi));
						//psiData[offset] =  _a*_b/(1+_a*temp*temp);
						temp *= temp;
						switch(noiseModel)
						{
						case GMixture:
							prob1 = GMPara.Gaussian(temp,0,k)*GMPara.alpha[k];
							prob2 = GMPara.Gaussian(temp,1,k)*(1-GMPara.alpha[k]);
							prob11 = prob1/(2*GMPara.sigma_square[k]);
							prob22 = prob2/(2*GMPara.beta_square[k]);
							psiData[offset] = (prob11+prob22)/(prob1+prob2);
							break;
						case Lap:
							if(LapPara[k]<1E-20)
								continue;
							psiData[offset]=1/(2*sqrt(temp+varepsilon_psi)*LapPara[k]);
							break;
						}
					}

			// prepare the components of the large linear system
			ImDxy.Multiply(Psi_1st,imdx,imdy);
			ImDx2.Multiply(Psi_1st,imdx,imdx);
			ImDy2.Multiply(Psi_1st,imdy,imdy);
			ImDtDx.Multiply(Psi_1st,imdx,imdt);
			ImDtDy.Multiply(Psi_1st,imdy,imdt);

			if(nChannels>1)
			{
				ImDxy.collapse(imdxy);
				ImDx2.collapse(imdx2);
				ImDy2.collapse(imdy2);
				ImDtDx.collapse(imdtdx);
				ImDtDy.collapse(imdtdy);
			}
			else
			{
				imdxy.copyData(ImDxy);
				imdx2.copyData(ImDx2);
				imdy2.copyData(ImDy2);
				imdtdx.copyData(ImDtDx);
				imdtdy.copyData(ImDtDy);
			}

			// filtering
			//imdx2.smoothing(A11,3);
			//imdxy.smoothing(A12,3);
			//imdy2.smoothing(A22,3);
			A11.copyData(imdx2);
			A12.copyData(imdxy);
			A22.copyData(imdy2);

			// add epsilon to A11 and A22
			A11.Add(alpha*0.5);
			A22.Add(alpha*0.5);

			// form b
			//imdtdx.smoothing(b1,3);
			//imdtdy.smoothing(b2,3);
			b1.copyData(imdtdx);
			b2.copyData(imdtdy);

			// laplacian filtering of the current flow field
		    Laplacian(foo1,u,Phi_1st);
			Laplacian(foo2,v,Phi_1st);
			_FlowPrecision *b1Data,*b2Data;
			const _FlowPrecision *foo1Data,*foo2Data;
			b1Data=b1.data();
			b2Data=b2.data();
			foo1Data=foo1.data();
			foo2Data=foo2.data();

			for(int i=0;i<nPixels;i++)
			{
				b1Data[i]=-b1Data[i]-alpha*foo1Data[i];
				b2Data[i]=-b2Data[i]-alpha*foo2Data[i];
			}

			// for debug only, displaying the matrix coefficients
			//A11.imwrite("A11.bmp",ImageIO::normalized);
			//A12.imwrite("A12.bmp",ImageIO::normalized);
			//A22.imwrite("A22.bmp",ImageIO::normalized);
			//b1.imwrite("b1.bmp",ImageIO::normalized);
			//b2.imwrite("b2.bmp",ImageIO::normalized);

			//-----------------------------------------------------------------------
			// conjugate gradient algorithm
			//-----------------------------------------------------------------------
			r1.copyData(b1);
			r2.copyData(b2);
			du.reset();
			dv.reset();

			for(int k=0;k<nCGIterations;k++)
			{
				rou[k]=r1.norm2()+r2.norm2();
				//cout<<rou[k]<<endl;
				if(rou[k]<1E-10)
					break;
				if(k==0)
				{
					p1.copyData(r1);
					p2.copyData(r2);
				}
				else
				{
					double ratio=rou[k]/rou[k-1];
					p1.Add(r1,p1,ratio);
					p2.Add(r2,p2,ratio);
				}
				// go through the large linear system
				foo1.Multiply(A11,p1);
				foo2.Multiply(A12,p2);
				q1.Add(foo1,foo2);
				Laplacian(foo1,p1,Phi_1st);
				q1.Add(foo1,alpha);

				foo1.Multiply(A12,p1);
				foo2.Multiply(A22,p2);
				q2.Add(foo1,foo2);
				Laplacian(foo2,p2,Phi_1st);
				q2.Add(foo2,alpha);

				double beta;
				beta=rou[k]/(p1.innerproduct(q1)+p2.innerproduct(q2));
				
				du.Add(p1,beta);
				dv.Add(p2,beta);

				r1.Add(q1,-beta);
				r2.Add(q2,-beta);
			}
			//-----------------------------------------------------------------------
			// end of conjugate gradient algorithm
			//-----------------------------------------------------------------------
		}// end of inner fixed point iteration
		
		// the following procedure is merely for debugging
		//cout<<"du "<<du.norm2()<<" dv "<<dv.norm2()<<endl;
		// update the flow field
		u.Add(du,1);
		v.Add(dv,1);
		if(interpolation == Bilinear)
			warpFL(warpIm2,Im1,Im2,u,v);
		else
		{
			Im2.warpImageBicubicRef(Im1,warpIm2,u,v);
			warpIm2.threshold();
		}

		//Im2.warpImageBicubicRef(Im1,warpIm2,BicubicCoeff,u,v);

		// estimate noise level
		switch(noiseModel)
		{
		case GMixture:
			estGaussianMixture(Im1,warpIm2,GMPara);
			break;
		case Lap:
			estLaplacianNoise(Im1,warpIm2,LapPara);
		}

	}// end of outer fixed point iteration
	delete rou;
}
Example #25
0
//--------------------------------------------------------------------------------------
// function to perfomr coarse to fine optical flow estimation
//--------------------------------------------------------------------------------------
void OpticalFlow::Coarse2FineFlow(DImage &vx, DImage &vy, DImage &warpI2,const DImage &Im1, const DImage &Im2, double alpha, double ratio, int minWidth, 
																	 int nOuterFPIterations, int nInnerFPIterations, int nCGIterations)
{
    
	// first build the pyramid of the two images
	GaussianPyramid GPyramid1;
	GaussianPyramid GPyramid2;
	if(IsDisplay)
		cout<<"Constructing pyramid...";
	GPyramid1.ConstructPyramid(Im1,ratio,minWidth);
	GPyramid2.ConstructPyramid(Im2,ratio,minWidth);
	if(IsDisplay)
		cout<<"done!"<<endl;
	
	// now iterate from the top level to the bottom
	DImage Image1,Image2,WarpImage2;


	// initialize noise

    // cout << GPyramid1.nlevels()  << " pyramid levels\n";

	for(int k=GPyramid1.nlevels()-1;k>=0;k--)
	{
		if(IsDisplay)
			cout<<"Pyramid level "<<k+1;
		int width=GPyramid1.Image(k).width();
		int height=GPyramid1.Image(k).height();
		im2feature(Image1,GPyramid1.Image(k));
		im2feature(Image2,GPyramid2.Image(k));

        // cout << "\t- level " << k+1 << " size " << width <<"x" << height <<endl;

		if(k==GPyramid1.nlevels()-1) // if at the top level
		{
			vx.allocate(width,height);
			vy.allocate(width,height);
			WarpImage2.copyData(Image2);
		}
		else
		{

			vx.imresize(width,height);
			vx.Multiplywith(1/ratio);
			vy.imresize(width,height);
			vy.Multiplywith(1/ratio);
			if(interpolation == Bilinear)
				warpFL(WarpImage2,Image1,Image2,vx,vy);
			else
				Image2.warpImageBicubicRef(Image1,WarpImage2,vx,vy);
		}
		SmoothFlowSOR(Image1,Image2,WarpImage2,vx,vy,alpha,nOuterFPIterations+k,nInnerFPIterations,nCGIterations+k*3);

		//GMPara.display();
		if(IsDisplay)
			cout<<endl;
	}
	//warpFL(warpI2,Im1,Im2,vx,vy);
	Im2.warpImageBicubicRef(Im1,warpI2,vx,vy);
	warpI2.threshold();
}
Example #26
0
//--------------------------------------------------------------------------------------------------------
// function to compute optical flow field using two fixed point iterations
// Input arguments:
//     Im1, Im2:						frame 1 and frame 2
//	warpIm2:						the warped frame 2 according to the current flow field u and v
//	u,v:									the current flow field, NOTICE that they are also output arguments
//
//--------------------------------------------------------------------------------------------------------
void OpticalFlow::SmoothFlowPDE(const DImage &Im1, const DImage &Im2, DImage &warpIm2, DImage &u, DImage &v,
                                double alpha, int nOuterFPIterations, int nInnerFPIterations, int nCGIterations)
{
    DImage mask,imdx,imdy,imdt;
    int imWidth,imHeight,nChannels,nPixels;
    imWidth=Im1.width();
    imHeight=Im1.height();
    nChannels=Im1.nchannels();
    nPixels=imWidth*imHeight;

    DImage du(imWidth,imHeight),dv(imWidth,imHeight);
    DImage uu(imWidth,imHeight),vv(imWidth,imHeight);
    DImage ux(imWidth,imHeight),uy(imWidth,imHeight);
    DImage vx(imWidth,imHeight),vy(imWidth,imHeight);
    DImage Phi_1st(imWidth,imHeight);
    DImage Psi_1st(imWidth,imHeight,nChannels);

    DImage imdxy,imdx2,imdy2,imdtdx,imdtdy;
    DImage ImDxy,ImDx2,ImDy2,ImDtDx,ImDtDy;
    DImage A11,A12,A22,b1,b2;
    DImage foo1,foo2;

    // variables for conjugate gradient
    DImage r1,r2,p1,p2,q1,q2;
    double* rou;
    rou=new double[nCGIterations];

    double varepsilon_phi=pow(0.001,2);
    double varepsilon_psi=pow(0.001,2);

    //--------------------------------------------------------------------------
    // the outer fixed point iteration
    //--------------------------------------------------------------------------
    for(int count=0; count<nOuterFPIterations; count++)
    {
        // compute the gradient
        getDxs(imdx,imdy,imdt,Im1,warpIm2);

        // generate the mask to set the weight of the pxiels moving outside of the image boundary to be zero
        genInImageMask(mask,vx,vy);

        // set the derivative of the flow field to be zero
        du.reset();
        dv.reset();

        //--------------------------------------------------------------------------
        // the inner fixed point iteration
        //--------------------------------------------------------------------------
        for(int hh=0; hh<nInnerFPIterations; hh++)
        {
            // compute the derivatives of the current flow field
            if(hh==0)
            {
                uu.copyData(u);
                vv.copyData(v);
            }
            else
            {
                uu.Add(u,du);
                vv.Add(v,dv);
            }
            uu.dx(ux);
            uu.dy(uy);
            vv.dx(vx);
            vv.dy(vy);

            // compute the weight of phi
            Phi_1st.reset();
            double* phiData=Phi_1st.data();
            double temp;
            const double *uxData,*uyData,*vxData,*vyData;
            uxData=ux.data();
            uyData=uy.data();
            vxData=vx.data();
            vyData=vy.data();
            for(int i=0; i<nPixels; i++)
            {
                temp=uxData[i]*uxData[i]+uyData[i]*uyData[i]+vxData[i]*vxData[i]+vyData[i]*vyData[i];
                phiData[i]=1/(2*sqrt(temp+varepsilon_phi));
            }

            // compute the nonlinear term of psi
            Psi_1st.reset();
            double* psiData=Psi_1st.data();
            const double *imdxData,*imdyData,*imdtData;
            const double *duData,*dvData;
            imdxData=imdx.data();
            imdyData=imdy.data();
            imdtData=imdt.data();
            duData=du.data();
            dvData=dv.data();

            double _a  = 10000, _b = 0.1;
            if(nChannels==1)
            {
                for(int i=0; i<nPixels; i++)
                {
                    temp=imdtData[i]+imdxData[i]*duData[i]+imdyData[i]*dvData[i];
                    //if(temp*temp<0.04)
                    psiData[i]=1/(2*sqrt(temp*temp+varepsilon_psi));
                    //psiData[i] = _a*_b/(1+_a*temp*temp);
                }
            }
            else
            {
                for(int i=0; i<nPixels; i++)
                    for(int k=0; k<nChannels; k++)
                    {
                        int offset=i*nChannels+k;
                        temp=imdtData[offset]+imdxData[offset]*duData[i]+imdyData[offset]*dvData[i];
                        //if(temp*temp<0.04)
                        psiData[offset]=1/(2*sqrt(temp*temp+varepsilon_psi));
                        //psiData[offset] =  _a*_b/(1+_a*temp*temp);
                    }
            }

            // prepare the components of the large linear system
            ImDxy.Multiply(Psi_1st,imdx,imdy);
            ImDx2.Multiply(Psi_1st,imdx,imdx);
            ImDy2.Multiply(Psi_1st,imdy,imdy);
            ImDtDx.Multiply(Psi_1st,imdx,imdt);
            ImDtDy.Multiply(Psi_1st,imdy,imdt);

            if(nChannels>1)
            {
                ImDxy.collapse(imdxy);
                ImDx2.collapse(imdx2);
                ImDy2.collapse(imdy2);
                ImDtDx.collapse(imdtdx);
                ImDtDy.collapse(imdtdy);
            }
            else
            {
                imdxy.copyData(ImDxy);
                imdx2.copyData(ImDx2);
                imdy2.copyData(ImDy2);
                imdtdx.copyData(ImDtDx);
                imdtdy.copyData(ImDtDy);
            }

            // filtering
            imdx2.smoothing(A11,3);
            imdxy.smoothing(A12,3);
            imdy2.smoothing(A22,3);

            // add epsilon to A11 and A22
            A11.Add(alpha*0.1);
            A22.Add(alpha*0.1);

            // form b
            imdtdx.smoothing(b1,3);
            imdtdy.smoothing(b2,3);
            // laplacian filtering of the current flow field
            Laplacian(foo1,u,Phi_1st);
            Laplacian(foo2,v,Phi_1st);
            double *b1Data,*b2Data;
            const double *foo1Data,*foo2Data;
            b1Data=b1.data();
            b2Data=b2.data();
            foo1Data=foo1.data();
            foo2Data=foo2.data();

            for(int i=0; i<nPixels; i++)
            {
                b1Data[i]=-b1Data[i]-alpha*foo1Data[i];
                b2Data[i]=-b2Data[i]-alpha*foo2Data[i];
            }

            // for debug only, displaying the matrix coefficients
            //A11.imwrite("A11.bmp",ImageIO::normalized);
            //A12.imwrite("A12.bmp",ImageIO::normalized);
            //A22.imwrite("A22.bmp",ImageIO::normalized);
            //b1.imwrite("b1.bmp",ImageIO::normalized);
            //b2.imwrite("b2.bmp",ImageIO::normalized);

            //-----------------------------------------------------------------------
            // conjugate gradient algorithm
            //-----------------------------------------------------------------------
            r1.copyData(b1);
            r2.copyData(b2);
            du.reset();
            dv.reset();

            for(int k=0; k<nCGIterations; k++)
            {
                rou[k]=r1.norm2()+r2.norm2();
                //cout<<rou[k]<<endl;
                if(rou[k]<1E-10)
                    break;
                if(k==0)
                {
                    p1.copyData(r1);
                    p2.copyData(r2);
                }
                else
                {
                    double ratio=rou[k]/rou[k-1];
                    p1.Add(r1,p1,ratio);
                    p2.Add(r2,p2,ratio);
                }
                // go through the large linear system
                foo1.Multiply(A11,p1);
                foo2.Multiply(A12,p2);
                q1.Add(foo1,foo2);
                Laplacian(foo1,p1,Phi_1st);
                q1.Add(foo1,alpha);

                foo1.Multiply(A12,p1);
                foo2.Multiply(A22,p2);
                q2.Add(foo1,foo2);
                Laplacian(foo2,p2,Phi_1st);
                q2.Add(foo2,alpha);

                double beta;
                beta=rou[k]/(p1.innerproduct(q1)+p2.innerproduct(q2));

                du.Add(p1,beta);
                dv.Add(p2,beta);

                r1.Add(q1,-beta);
                r2.Add(q2,-beta);
            }
            //-----------------------------------------------------------------------
            // end of conjugate gradient algorithm
            //-----------------------------------------------------------------------
        }// end of inner fixed point iteration

        // the following procedure is merely for debugging
        //cout<<"du "<<du.norm2()<<" dv "<<dv.norm2()<<endl;
        // update the flow field
        u.Add(du,1);
        v.Add(dv,1);
        warpFL(warpIm2,Im1,Im2,u,v);
    }// end of outer fixed point iteration


    delete rou;
}
Example #27
0
//--------------------------------------------------------------------------------------------------------
// function to do sanity check: imdx*du+imdy*dy+imdt=0
//--------------------------------------------------------------------------------------------------------
void OpticalFlow::SanityCheck(const DImage &imdx, const DImage &imdy, const DImage &imdt, double du, double dv)
{
	if(imdx.matchDimension(imdy)==false || imdx.matchDimension(imdt)==false)
	{
		cout<<"The dimensions of the derivatives don't match!"<<endl;
		return;
	}
	const _FlowPrecision* pImDx,*pImDy,*pImDt;
	pImDx=imdx.data();
	pImDy=imdy.data();
	pImDt=imdt.data();
	double error=0;
	for(int i=0;i<imdx.height();i++)
		for(int j=0;j<imdx.width();j++)
			for(int k=0;k<imdx.nchannels();k++)
			{
				int offset=(i*imdx.width()+j)*imdx.nchannels()+k;
				double temp=pImDx[offset]*du+pImDy[offset]*dv+pImDt[offset];
				error+=fabs(temp);
			}
	error/=imdx.nelements();
	cout<<"The mean error of |dx*u+dy*v+dt| is "<<error<<endl;
}
Example #28
0
//--------------------------------------------------------------------------------------
// function to perfomr coarse to fine optical flow estimation
//--------------------------------------------------------------------------------------
void OpticalFlow::Coarse2FineFlow(DImage &vx, DImage &vy, DImage &warpI2,const DImage &Im1, const DImage &Im2, double alpha, double ratio, int minWidth, 
																	 int nOuterFPIterations, int nInnerFPIterations, int nCGIterations)
{
	// first build the pyramid of the two images
	GaussianPyramid GPyramid1;
	GaussianPyramid GPyramid2;
	if(IsDisplay)
		cout<<"Constructing pyramid...";
	GPyramid1.ConstructPyramid(Im1,ratio,minWidth);
	GPyramid2.ConstructPyramid(Im2,ratio,minWidth);
	if(IsDisplay)
		cout<<"done!"<<endl;
	
	// now iterate from the top level to the bottom
	DImage Image1,Image2,WarpImage2;
	//GaussianMixture GMPara(Im1.nchannels()+2);

	// initialize noise
	switch(noiseModel){
	case GMixture:
		GMPara.reset(Im1.nchannels()+2);
		break;
	case Lap:
		LapPara.allocate(Im1.nchannels()+2);
		for(int i = 0;i<LapPara.dim();i++)
			LapPara[i] = 0.02;
		break;
	}

	for(int k=GPyramid1.nlevels()-1;k>=0;k--)
	{
		if(IsDisplay)
			cout<<"Pyramid level "<<k;
		int width=GPyramid1.Image(k).width();
		int height=GPyramid1.Image(k).height();
		im2feature(Image1,GPyramid1.Image(k));
		im2feature(Image2,GPyramid2.Image(k));

		if(k==GPyramid1.nlevels()-1) // if at the top level
		{
			vx.allocate(width,height);
			vy.allocate(width,height);
			//warpI2.copyData(Image2);
			WarpImage2.copyData(Image2);
		}
		else
		{

			vx.imresize(width,height);
			vx.Multiplywith(1/ratio);
			vy.imresize(width,height);
			vy.Multiplywith(1/ratio);
			//warpFL(warpI2,GPyramid1.Image(k),GPyramid2.Image(k),vx,vy);
			if(interpolation == Bilinear)
				warpFL(WarpImage2,Image1,Image2,vx,vy);
			else
				Image2.warpImageBicubicRef(Image1,WarpImage2,vx,vy);
		}
		//SmoothFlowPDE(GPyramid1.Image(k),GPyramid2.Image(k),warpI2,vx,vy,alpha,nOuterFPIterations,nInnerFPIterations,nCGIterations);
		//SmoothFlowPDE(Image1,Image2,WarpImage2,vx,vy,alpha*pow((1/ratio),k),nOuterFPIterations,nInnerFPIterations,nCGIterations,GMPara);
		
		//SmoothFlowPDE(Image1,Image2,WarpImage2,vx,vy,alpha,nOuterFPIterations,nInnerFPIterations,nCGIterations);
		SmoothFlowSOR(Image1,Image2,WarpImage2,vx,vy,alpha,nOuterFPIterations+k,nInnerFPIterations,nCGIterations+k*3);

		//GMPara.display();
		if(IsDisplay)
			cout<<endl;
	}
	//warpFL(warpI2,Im1,Im2,vx,vy);
	Im2.warpImageBicubicRef(Im1,warpI2,vx,vy);
	warpI2.threshold();
}
Example #29
0
void 
mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {

	// check for proper number and size of arguments
	//errCheck(nrhs == 1,"Arguments:  filePath");
	//errCheck(nlhs == 1,"Outputs:  skew");
    std::string inDir = mxArrayToString(prhs[0]);
	std::string filePath = mxArrayToString(prhs[1]);
	std::string dirPath = mxArrayToString(prhs[2]);
	double slant = mxGetScalar(prhs[3]);
	
	bool VIZ=false;
	/*if (filePath.compare("wordimg_9")==0 || 
        filePath.compare("wordimg_78")==0 )
       VIZ=true;
	*/
	//DImage img(("tmp/"+filePath+".tif").c_str(),DImage::DFileFormat_tiff);
	Mat mat = imread(inDir+filePath, CV_LOAD_IMAGE_GRAYSCALE);
	//cout << "read image" <<endl;
	//TODO clean
	Mat initBin = Binarization::otsuBinarization(mat);
    if (VIZ)
        {Binarization::imshowB("otsu",initBin,255,0); waitKey();}
        
    Mat dilated = Binarization::dilate(initBin,3);//dilate the fg, shrinking the bg
    //cout << "dilated" <<endl;
    
    
    Mat dilatedFlip = dilated.clone();
    for (int r=0; r<dilatedFlip.rows; r++)
        for (int c=0; c<dilatedFlip.cols; c++)
        {
            if (dilatedFlip.at<unsigned char>(r,c)==1)
                dilatedFlip.at<unsigned char>(r,c)=0;
            else
                dilatedFlip.at<unsigned char>(r,c)=1;
        }
    
    Mat prime;
    Mat bg_estimation = Binarization::inpainting(mat,dilatedFlip,&prime);
    //cout << "inpainted" <<endl;
    if (VIZ)
        {imshow("bg_estimation",bg_estimation); waitKey();}
    double average, std;
    Binarization::extract_feat(prime, NULL, &average, &std);
    bg_estimation = Binarization::inpainting(mat,dilatedFlip,NULL,&average,&std);
    //cout << "found avg" <<endl;
    
	
	DImage img;
	convertMatToDImage(mat,&img);
	//cout << "converted" <<endl;
	int pad=255;
	img = img.shearedH(slant,pad,true);//fill corners with black
	//cout << "sheared" <<endl;
	
	
	convertDImageToMat(img,&mat);
	//cout << "converted back" <<endl;
    if (VIZ)
	    {imshow("sheared",mat); waitKey();}
    
    //fill corners
	Mat fillMaskFlipped(mat.rows,mat.cols,CV_8U,Scalar(1));
	for (int r=fillMaskFlipped.rows-1; r>=0; r--)
        for (int c=0; c<fillMaskFlipped.cols; c++)
        {
            int flag = (abs(mat.at<unsigned char>(r,c)-pad)<3 || 
                        abs(mat.at<unsigned char>(r+1,c-1)-pad)<3 ||
                        abs(mat.at<unsigned char>(r-1,c+1)-pad)<3)?0:1;
            fillMaskFlipped.at<unsigned char>(r,c)=flag;
            
        }
	
	
	/*
	int space=1;
	//for (int r=fillMaskFlipped.rows-1; r>fillMaskFlipped.rows-1-space; r--)
    //    for (int c=0; c<space; c++)
    //    {
    //        int flag = (abs(mat.at<unsigned char>(r,c)-pad)<3)?0:1;
    //        fillMaskFlipped.at<unsigned char>(r,c)=flag;
    //    }
        
    for (int r=fillMaskFlipped.rows-1; r>=0; r--)
        for (int c=0; c<space; c++)
        {
            int flag = (abs(mat.at<unsigned char>(r,c)-pad)<3)?0:1;
            fillMaskFlipped.at<unsigned char>(r,c)=flag;
        }
	
	for (int c=0; c<fillMaskFlipped.cols; c++)
	    for (int r=fillMaskFlipped.rows-1; r>fillMaskFlipped.rows-1-space; r--)
        {
            int flag = (abs(mat.at<unsigned char>(r,c)-pad)<3)?0:1;
            fillMaskFlipped.at<unsigned char>(r,c)=flag;
        }
        
    for (int c=0; c<fillMaskFlipped.cols-space; c++)
    {
        bool cont=false;
        for (int r=fillMaskFlipped.rows-1; r>=space; r--)
        {
            int flag = (abs(mat.at<unsigned char>(r,c)-pad)<3)?0:1;
            if (flag==0 && !cont)
                cont=true;
            fillMaskFlipped.at<unsigned char>(r-space,c+space)=flag;
            //if (r==fillMaskFlipped.rows-1 && flag==0)
            //{
            //    for (int rf=r-space-1; rf<=fillMaskFlipped.rows-1; rf++)
            //        fillMaskFlipped.at<unsigned char>(rf,c+space)=flag;
            //}
            //if (c==0 && flag==0)
            //{
            //    for (int cf=c+space-1; cf>=0; cf--)
            //        fillMaskFlipped.at<unsigned char>(r-space,cf)=flag;
            //}
        
        }
        if (!cont)
            break;
    }
    
    //for (int c=fillMaskFlipped.cols-1; c>fillMaskFlipped.cols-1-space; c--)
    //    for (int r=0; r<space; r++)
    //    {
    //        int flag = (abs(mat.at<unsigned char>(r,c)-pad)<3)?0:1;
    //        fillMaskFlipped.at<unsigned char>(r,c)=flag;
    //    }
    for (int c=fillMaskFlipped.cols-1; c>=0; c--)
        for (int r=0; r<space; r++)
        {
            int flag = (abs(mat.at<unsigned char>(r,c)-pad)<3)?0:1;
            fillMaskFlipped.at<unsigned char>(r,c)=flag;
        }
    for (int r=0; r<fillMaskFlipped.rows; r++)
        for (int c=fillMaskFlipped.cols-1; c>fillMaskFlipped.cols-1-space; c--)
        {
            int flag = (abs(mat.at<unsigned char>(r,c)-pad)<3)?0:1;
            fillMaskFlipped.at<unsigned char>(r,c)=flag;
        }
    
    for (int c=fillMaskFlipped.cols-1; c>=space; c--)
    {
        bool cont=false;
        for (int r=0; r<fillMaskFlipped.rows-space; r++)
        {
            int flag = (abs(mat.at<unsigned char>(r,c)-pad)<3)?0:1;
            if (flag==0 && !cont)
                cont=true;
            fillMaskFlipped.at<unsigned char>(r+space,c-space)=flag;
            //if (c==fillMaskFlipped.cols-1 && flag==0)
            //{
           //   for (int cf=c-space-1; cf<=fillMaskFlipped.cols-1; cf++)
           //         fillMaskFlipped.at<unsigned char>(r+space,cf)=flag;
            //}
            //if (r==0 && flag==0)
            //{
            //    for (int rf=r+space-1; rf>=0; rf--)
            //        fillMaskFlipped.at<unsigned char>(rf,c-space)=flag;
            //}
        
        }
        if (!cont)
            break;
    }*/
    if (VIZ)
    {   Binarization::imshowB("fillamsk",fillMaskFlipped,255,0); waitKey();
        Mat showMask = mat.clone();
        Mat showUnmask = mat.clone();
        for (int r=fillMaskFlipped.rows-1; r>=0; r--)
            for (int c=0; c<fillMaskFlipped.cols; c++)
            {
                if (fillMaskFlipped.at<unsigned char>(r,c) == 0)
                    showUnmask.at<unsigned char>(r,c)=255;
                else if (fillMaskFlipped.at<unsigned char>(r,c) == 1)
                    showMask.at<unsigned char>(r,c)=255;
            }
        imshow("masked",showMask); waitKey();
        imshow("unmasked",showUnmask); waitKey();
    }
	mat = Binarization::inpainting(mat,fillMaskFlipped,NULL,&average,&std,VIZ);
	//cout << "filled" <<endl;
	/*for (int r=0; r<mat.rows; r++)
	    for (int c=0; c<mat.cols; c++)
	    {
	        if (fillMaskFlipped.at<unsigned char>(r,c)==0 && fabs(mat.at<unsigned char>(r,c)-average)>std)
	            mat.at<unsigned char>(r,c)=average;
	    }*/
	if (VIZ)
	    {imshow("filled",mat); waitKey();}
	//img.save((dirPath+"/"+filePath+".png").c_str(), DImage::DFileFormat_png);
	imwrite(dirPath+"/"+filePath,mat);
	//cout << "write "<<dirPath<<"/"<<filePath<<".png"<<endl;
}
Example #30
0
/**Computes the projection profile of img onto an axis with angle
axisAngDeg.  Horizontal and vertical profiles (when axisAngDeg is 0 or
90 degress, respectively) are special-cased for speed by calling
getImageVerticalProfile() or getImageHorizontalProfile().  I have seen
inconsistent usage of the terms "vertical profile" and "horizontal
profile" since some people describe the direction of projection
instead of the direction of the axis onto which the image is
projected.  It seems more common, however, to use the direction of the
axis.  Therefore, when I say "vertical profile," I mean that the
profile length is equal to the height of the image, and the Rth value
in the profile array is the sum of the values in the Rth row of the
image.  Likewise, a horizontal profile has length equal to the image
width, and each value is the projection of the corresponding image
column onto the horizontal axis.  For a horizontal profile, set
axisAngDeg to 0.  For a vertical profile, set axisAngDeg to 90.  Note
that angles increase clockwise since the y-coordinate of images
increases from top to bottom.  For RGB images and multi-channel float
or double images, the sum of all channels is used (a single profile is
calculated).  If this is not what is desired, you could create
separate images for each channel and take the profiles
seperately. Complex images are not supported directly, so they must be
converted into a different type before a profile can be taken.  If
fInterp is false (default), then the nearest image pixel value is used
when the position the profile passes through is between pixels.  If
fInterp is true, bilinear interpolation is used to estimate the value
that should go in the profile.*/
void DProfile::getImageProfile(const DImage &img, double axisAngDeg, 
			       bool fNormalize, bool fInterp){
  int w, h;
  double wm1, hm1;
  int numPixels;
  double dblSum;
  double theta;
  double dblTmp;
  int alen;//length of anchor segment.  The anchor segment is the
	   //segment that passes through the center of the image and
	   //is oriented perpendicular to axisAngDeg.  The length of
	   //the profile will be equal to alen.
  int olen;//length of offset segments.  The offset segments are the 
           //integration paths parallel to axisAngDeg (one segment per
           //profile value.
  double asx, asy;//start (x,y) of the anchor segment
  double adx, ady;//deltaX and deltaY of the anchor segment
  double ax, ay;  // current anchor point (x,y along the anchor segment)
  double osx, osy;//starty x,y offset from ax,ay for an offset segment
  double odx, ody;//deltaX and deltaY of offset segments
  double ox, oy;  // current offset point (x,y along the offset segment)

  if(DImage::DImage_cmplx == img.getImageType()){
    fprintf(stderr,
	    "DProfile::getImageProfile() does not support complex images\n");
    abort();
  }
//   if(((axisAngDeg > -0.00001) && (axisAngDeg < 0.00001)) ||
//      ((axisAngDeg > 179.00001) && (axisAngDeg < 180.00001)) ||
//      ((axisAngDeg > 359.00001) && (axisAngDeg < 360.00001))){
//     getImageHorizontalProfile(img, fNormalize);
//     return;
//   }
//   if(((axisAngDeg > 89.00001) && (axisAngDeg < 90.00001)) ||
//      ((axisAngDeg > 269.00001) && (axisAngDeg < 270.00001)) ||
//      ((axisAngDeg < -269.00001) && (axisAngDeg > -270.00001)) ||
//      ((axisAngDeg < -89.00001) && (axisAngDeg > -90.00001))){
//     getImageVerticalProfile(img, fNormalize);
//     return;
//   }
  w = img.width();
  h = img.height();
  wm1 = w-1;
  hm1 = h-1;
  theta = DMath::degreesToRadians(axisAngDeg);
  //figure out how long rgProf should be and how wide the integration should be
  odx = cos(theta);
  ody = sin(theta);
  adx = -1. * ody;
  ady = odx;
  olen = (int)(2*DMath::distPointLine(0, 0,  w/2., h/2.,  w/2.+adx, h/2.+ady));
  dblTmp = 2*DMath::distPointLine(w, 0,  w/2., h/2.,  w/2.+adx, h/2.+ady);
  if(dblTmp > olen)
    olen = (int)dblTmp;

  alen = (int)(2*DMath::distPointLine(0, 0,  w/2., h/2.,  w/2.+odx, h/2.+ody));
  dblTmp = 2*DMath::distPointLine(w, 0,  w/2., h/2.,  w/2.+odx, h/2.+ody);
  if(dblTmp > alen)
    alen = (int)dblTmp;

//   printf("w=%d h=%d\n", w, h);
//   printf("adx=%.2f ady=%.2f  alen=%d\n", adx, ady, alen);
//   printf("odx=%.2f ody=%.2f  olen=%d\n", odx, ody, olen);

  // allocate the rgProf array
  if(NULL == rgProf){
    rgProf = (double*)malloc(alen * sizeof(double));
    D_CHECKPTR(rgProf);
    len = alen;
  }
  else{
    if(len != alen){
      rgProf = (double*)realloc(rgProf,alen*sizeof(double));
      D_CHECKPTR(rgProf);
      len = alen;
    }
  }

  ax = asx = w/2.-(alen/2*adx);
  ay = asy = h/2.-(alen/2*ady);
  osx = -(olen/2*odx);
  osy = -(olen/2*ody);

  switch(img.getImageType()){
    case DImage::DImage_u8:
      {
	D_uint8 *pu8;
	pu8=img.dataPointer_u8();
	if(fInterp){
	  fprintf(stderr, "WARNING! DProfile::getImageProfile() may be buggy "
		  "when fInterp is true\n");
	  for(int aa=0; aa < alen; ++aa){
	    int ix, iy;
	    double w1, w2; //weight of left vs right pixels
	    double  w3, w4;//weight of top vs bottom pixels
	    double left, right;
	    int oidx;
	    ox = ax+osx;
	    oy = ay+osy;
	    numPixels = 0;
	    dblSum = 0.;
	    for(int oo=0; oo < olen; ++oo){
	      if( (ox>=0) && (ox < wm1) && (oy>=0) && (oy<hm1)){
		ix = (int)ox;
		iy = (int)oy;
		oidx = iy*w + ix;
		w2 = ox-ix;
		w1 = 1.-w2;
		w4 = oy-iy;
		w3 = 1.-w4;
		left = (pu8[oidx] * w3 + pu8[oidx+w] * w4);
		right = (pu8[oidx+1] * w3 + pu8[oidx+w+1] * w4);
		dblSum += left*w1 + right*w2;
		++numPixels;
	      }
	      else if((ox==wm1) || (oy == hm1)){
		// don't interpolate on the edges, just approximate
		ix = (int)ox;
		iy = (int)oy;
		oidx = iy*w + ix;
		dblSum += pu8[oidx];
		++numPixels;
	      }
	      ox += odx;
	      oy += ody;
	    }
	    ax += adx;
	    ay += ady;
	    if(fNormalize && (numPixels>0))
	      rgProf[aa] = dblSum / numPixels;
	    else
	      rgProf[aa] = dblSum;
	  }
	}
	else{
	  for(int aa=0; aa < alen; ++aa){
	    int ix, iy;
	    int oidx;
	    ox = ax+osx;
	    oy = ay+osy;
	    numPixels = 0;
	    dblSum = 0.;
	    for(int oo=0; oo < olen; ++oo){
	      if( (ox>=0) && (ox <w) && (oy>=0) && (oy<h)){
		ix = (int)ox;
		iy = (int)oy;
		oidx = iy*w + ix;
		dblSum += pu8[oidx];
		++numPixels;
	      }
	      ox += odx;
	      oy += ody;
	    }
	    ax += adx;
	    ay += ady;
	    if(fNormalize && (numPixels>0))
	      rgProf[aa] = dblSum / numPixels;
	    else
	      rgProf[aa] = dblSum;
	  }
	}
      }
      break;
    default:
      fprintf(stderr, "Not yet implemented!\n");
      abort();
  }//end switch(img.getImageType())

}