Ejemplo n.º 1
0
void mexFunction(int nout, mxArray *pout[], int nin, const mxArray *pin[]) {
  FILE *f = fopen("log.txt", "wt");
  fclose(f);

  if (nin < 2) { mexErrMsgTxt("nnmex called with < 2 input arguments"); }

  const mxArray *A = pin[0], *B = pin[1];
  const mxArray *ANN_PREV = NULL, *ANN_WINDOW = NULL, *AWINSIZE = NULL;
  int aw = -1, ah = -1, bw = -1, bh = -1;
  BITMAP *a = NULL, *b = NULL, *ann_prev = NULL, *ann_window = NULL, *awinsize = NULL;
  VECBITMAP<unsigned char> *ab = NULL, *bb = NULL;
  VECBITMAP<float> *af = NULL, *bf = NULL;

  if (mxGetNumberOfDimensions(A) != 3 || mxGetNumberOfDimensions(B) != 3) { mexErrMsgTxt("dims != 3"); }
  if (mxGetDimensions(A)[2] != mxGetDimensions(B)[2]) { mexErrMsgTxt("3rd dimension not same size"); }

  int mode = MODE_IMAGE;
  if (mxGetDimensions(A)[2] != 3) { // a discriptor rather than rgb
    if (mxIsUint8(A) && mxIsUint8(B)) { mode = MODE_VECB; } 
    else if (is_float(A) && is_float(B)) { mode = MODE_VECF; } 
    else { mexErrMsgTxt("input not uint8, single, or double"); }
  }

  Params *p = new Params();
  RecomposeParams *rp = new RecomposeParams();
  BITMAP *borig = NULL;
  if (mode == MODE_IMAGE) {
    a = convert_bitmap(A);
    b = convert_bitmap(B);
	borig = b;
    aw = a->w; ah = a->h;
    bw = b->w; bh = b->h;
  } 
  else if (mode == MODE_VECB) {
    ab = convert_vecbitmap<unsigned char>(A);
    bb = convert_vecbitmap<unsigned char>(B);
    if (ab->n != bb->n) { mexErrMsgTxt("3rd dimension differs"); }
    aw = ab->w; ah = ab->h;
    bw = bb->w; bh = bb->h;
    p->vec_len = ab->n;
  } 
  else if (mode == MODE_VECF) {
    af = convert_vecbitmap<float>(A);
    bf = convert_vecbitmap<float>(B);
    if (af->n != bf->n) { mexErrMsgTxt("3rd dimension differs"); }
    aw = af->w; ah = af->h;
    bw = bf->w; bh = bf->h;
    p->vec_len = af->n;
  }

  double *win_size = NULL;
  BITMAP *amask = NULL, *bmask = NULL;

  double scalemin = 0.5, scalemax = 2.0;  // The product of these must be one.
  /* parse parameters */
  int i = 2;
  int sim_mode = 0;
  int knn_chosen = -1;
  p->algo = ALGO_CPU;
  int enrich_mode = 0;
  if (nin > i && !mxIsEmpty(pin[i])) {
    if (mxStringEquals(pin[i], "cpu")) { p->algo = ALGO_CPU; }
    else if (mxStringEquals(pin[i], "gpucpu")) { p->algo = ALGO_GPUCPU; }
    else if (mxStringEquals(pin[i], "cputiled")) { p->algo = ALGO_CPUTILED; }
    else if (mxStringEquals(pin[i], "rotscale")) { sim_mode = 1; }
    else if (mxStringEquals(pin[i], "enrich")) { p->algo = ALGO_CPUTILED; enrich_mode = 1; }
    else { mexErrMsgTxt("Unknown algorithm"); }
  } i++;
  if (nin > i && !mxIsEmpty(pin[i])) { p->patch_w = int(mxGetScalar(pin[i])); } i++;
  if (nin > i && !mxIsEmpty(pin[i])) { p->nn_iters = int(mxGetScalar(pin[i])); } i++;
  if (nin > i && !mxIsEmpty(pin[i])) { p->rs_max = int(mxGetScalar(pin[i])); } i++;
  if (nin > i && !mxIsEmpty(pin[i])) { p->rs_min = int(mxGetScalar(pin[i])); } i++;
  if (nin > i && !mxIsEmpty(pin[i])) { p->rs_ratio = mxGetScalar(pin[i]); } i++;
  if (nin > i && !mxIsEmpty(pin[i])) { p->rs_iters = mxGetScalar(pin[i]); } i++;
  if (nin > i && !mxIsEmpty(pin[i])) { p->cores = int(mxGetScalar(pin[i])); } i++;
  if (nin > i && !mxIsEmpty(pin[i])) { bmask = convert_bitmap(pin[i]); } i++; // XC+
  if (nin > i && !mxIsEmpty(pin[i])) { 
    if (!mxIsDouble(pin[i])) { mexErrMsgTxt("\nwin_size should be of type double."); }
    win_size = (double*)mxGetData(pin[i]);
    if (mxGetNumberOfElements(pin[i])==1) { p->window_h = p->window_w = int(win_size[0]); }
    else if (mxGetNumberOfElements(pin[i])==2) { p->window_h = int(win_size[0]); p->window_w = int(win_size[1]); }
    else { mexErrMsgTxt("\nwin_size should be a scalar for square window or [h w] for a rectangular one."); }
  } i++;
  /* continue parsing parameters */
  // [ann_prev=NULL], [ann_window=NULL], [awinsize=NULL], 
  if (nin > i && !mxIsEmpty(pin[i])) { 
    ANN_PREV = pin[i];
    int clip_count = 0;
    ann_prev = convert_field(p, ANN_PREV, bw, bh, clip_count);       // Bug fixed by Connelly
  } i++;
  if (nin > i && !mxIsEmpty(pin[i])) { 
    ANN_WINDOW = pin[i];
    int clip_count = 0;
    ann_window = convert_field(p, ANN_WINDOW, bw, bh, clip_count);      
  } i++;
  if (nin > i && !mxIsEmpty(pin[i])) { 
    AWINSIZE = pin[i];
    awinsize = convert_winsize_field(p, AWINSIZE, aw, ah);  
    if (p->window_w==INT_MAX||p->window_h==INT_MAX) { p->window_w = -1; p->window_h = -1; }
  } i++;
  if (nin > i && !mxIsEmpty(pin[i])) { 
    knn_chosen = int(mxGetScalar(pin[i]));
    if (knn_chosen == 1) { knn_chosen = -1; }
    if (knn_chosen <= 0) { mexErrMsgTxt("\nknn is less than zero"); }
  } i++;
  if (nin > i && !mxIsEmpty(pin[i])) { 
    scalemax = mxGetScalar(pin[i]);
    if (scalemax <= 0) { mexErrMsgTxt("\nscalerange is less than zero"); }
    scalemin = 1.0/scalemax;
    if (scalemax < scalemin) {
      double temp = scalemax;
      scalemax = scalemin;
      scalemin = temp;
    }
  } i++;

  if (ann_window&&!awinsize&&!win_size) {
    mexErrMsgTxt("\nUsing ann_window - either awinsize or win_size should be defined.\n");
  }

  if (enrich_mode) {
	int nn_iters = p->nn_iters;
    p->enrich_iters = nn_iters/2;
	p->nn_iters = 2;
	if (A != B) { mexErrMsgTxt("\nOur implementation of enrichment requires that image A = image B.\n"); }
	if (mode == MODE_IMAGE) {
	  b = a;
	} else {
	  mexErrMsgTxt("\nEnrichment only implemented for 3 channel uint8 inputs.\n");
	}
  }

  init_params(p);
  if (sim_mode) {
    init_xform_tables(scalemin, scalemax, 1);
  }
  
  RegionMasks *amaskm = amask ? new RegionMasks(p, amask): NULL;

  BITMAP *ann = NULL; // NN field
  BITMAP *annd_final = NULL; // NN patch distance field
  BITMAP *ann_sim_final = NULL;

  VBMP *vann_sim = NULL;
  VBMP *vann = NULL;
  VBMP *vannd = NULL;

  if (mode == MODE_IMAGE) {
    // input as RGB image
    if (!a || !b) { mexErrMsgTxt("internal error: no a or b image"); }
    if (knn_chosen > 1) {
      p->knn = knn_chosen;
      if (sim_mode) { mexErrMsgTxt("rotating+scaling patches not implemented with knn (actually it is implemented it is not exposed by the wrapper)"); }
      PRINCIPAL_ANGLE *pa = NULL;
      vann_sim = NULL;
      vann = knn_init_nn(p, a, b, vann_sim, pa);
      vannd = knn_init_dist(p, a, b, vann, vann_sim);
      knn(p, a, b, vann, vann_sim, vannd, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, pa);
//      sort_knn(p, vann, vann_sim, vannd);
    } else if (sim_mode) {
      BITMAP *ann_sim = NULL;
      ann = sim_init_nn(p, a, b, ann_sim);
      BITMAP *annd = sim_init_dist(p, a, b, ann, ann_sim);
      sim_nn(p, a, b, ann, ann_sim, annd);
      if (ann_prev) { mexErrMsgTxt("when searching over rotations+scales, previous guess is not supported"); }
      annd_final = annd;
      ann_sim_final = ann_sim;
    } else {
      ann = init_nn(p, a, b, bmask, NULL, amaskm, 1, ann_window, awinsize);
      BITMAP *annd = init_dist(p, a, b, ann, bmask, NULL, amaskm);
      nn(p, a, b, ann, annd, amaskm, bmask, 0, 0, rp, 0, 0, 0, NULL, p->cores, ann_window, awinsize); 
      if (ann_prev) minnn(p, a, b, ann, annd, ann_prev, bmask, 0, 0, rp, NULL, amaskm, p->cores);  
      annd_final = annd;
    }
  } 
/*
  else if (mode == MODE_VECB) {
//    mexPrintf("mode vecb %dx%dx%d, %dx%dx%d\n", ab->w, ab->h, ab->n, bb->w, bb->h, bb->n);
//    mexPrintf("  %d %d %d %d\n", ab->get(0,0)[0], ab->get(1,0)[0], ab->get(0,1)[0], ab->get(0,0)[1]);
    if (!ab || !bb) { mexErrMsgTxt("internal error: no a or b image"); }
    ann = vec_init_nn<unsigned char>(p, ab, bb, bmask, NULL, amaskm);
    VECBITMAP<int> *annd = vec_init_dist<unsigned char, int>(p, ab, bb, ann, bmask, NULL, amaskm);
//    mexPrintf("  %d %d %d %p %p\n", annd->get(0,0)[0], annd->get(1,0)[0], annd->get(0,1)[0], amaskm, bmask);
    vec_nn<unsigned char, int>(p, ab, bb, ann, annd, amaskm, bmask, 0, 0, rp, 0, 0, 0, NULL, p->cores); 
    if (ann_prev) vec_minnn<unsigned char, int>(p, ab, bb, ann, annd, ann_prev, bmask, 0, 0, rp, NULL, amaskm, p->cores);  
    annd_final = vecbitmap_to_bitmap(annd);
    delete annd;
  } 
  else if (mode == MODE_VECF) {
//    mexPrintf("mode vecf %dx%dx%d, %dx%dx%d\n", af->w, af->h, af->n, bf->w, bf->h, bf->n);
//    mexPrintf("  %f %f %f %f\n", af->get(0,0)[0], af->get(1,0)[0], af->get(0,1)[0], af->get(0,0)[1]);
    if (!af || !bf) { mexErrMsgTxt("internal error: no a or b image"); }
    ann = vec_init_nn<float>(p, af, bf, bmask, NULL, amaskm);
    VECBITMAP<float> *annd = vec_init_dist<float, float>(p, af, bf, ann, bmask, NULL, amaskm);
    vec_nn<float, float>(p, af, bf, ann, annd, amaskm, bmask, 0, 0, rp, 0, 0, 0, NULL, p->cores); 
    if (ann_prev) vec_minnn<float, float>(p, af, bf, ann, annd, ann_prev, bmask, 0, 0, rp, NULL, amaskm, p->cores);  
    annd_final = create_bitmap(annd->w, annd->h);
    clear(annd_final);
    delete annd;
  }
*/
  else if(mode == MODE_VECB) {
    if (sim_mode) { mexErrMsgTxt("internal error: rotation+scales not implemented with descriptor mode"); }
    if (knn_chosen > 1) { mexErrMsgTxt("internal error: kNN not implemented with descriptor mode"); }
//    mexPrintf("mode vecb_xc %dx%dx%d, %dx%dx%d\n", ab->w, ab->h, ab->n, bb->w, bb->h, bb->n);
    // input as uint8 discriptors per pixel
    if (!ab || !bb) { mexErrMsgTxt("internal error: no a or b image"); }
    ann = XCvec_init_nn<unsigned char>(p, ab, bb, bmask, NULL, amaskm);
    VECBITMAP<int> *annd = XCvec_init_dist<unsigned char, int>(p, ab, bb, ann, bmask, NULL, amaskm);
    XCvec_nn<unsigned char, int>(p, ab, bb, ann, annd, amaskm, bmask, 0, 0, rp, 0, 0, 0, NULL, p->cores); 
    if (ann_prev) XCvec_minnn<unsigned char, int>(p, ab, bb, ann, annd, ann_prev, bmask, 0, 0, rp, NULL, amaskm, p->cores);  
    annd_final = vecbitmap_to_bitmap(annd);
    delete annd;
  } else if(mode == MODE_VECF) {
    if (sim_mode) { mexErrMsgTxt("internal error: rotation+scales not implemented with descriptor mode"); }
    if (knn_chosen > 1) { mexErrMsgTxt("internal error: kNN not implemented with descriptor mode"); }
    // input as float/double discriptors per pixel
    if (!af || !bf) { mexErrMsgTxt("internal error: no a or b image"); }
    ann = XCvec_init_nn<float>(p, af, bf, bmask, NULL, amaskm);
    VECBITMAP<float> *annd = XCvec_init_dist<float, float>(p, af, bf, ann, bmask, NULL, amaskm);
    XCvec_nn<float, float>(p, af, bf, ann, annd, amaskm, bmask, 0, 0, rp, 0, 0, 0, NULL, p->cores); 
    if (ann_prev) XCvec_minnn<float, float>(p, af, bf, ann, annd, ann_prev, bmask, 0, 0, rp, NULL, amaskm, p->cores);  
    annd_final = create_bitmap(annd->w, annd->h);
    clear(annd_final);
    delete annd;	
  }

  destroy_region_masks(amaskm);

  // output ann: x | y | patch_distance
  if(nout >= 1) {
    mxArray *ans = NULL;
    if (knn_chosen > 1) {
      if (sim_mode) { mexErrMsgTxt("rotating+scaling patches return value not implemented with knn"); }
      mwSize dims[4] = { ah, aw, 3, knn_chosen };
      ans = mxCreateNumericArray(4, dims, mxINT32_CLASS, mxREAL);
      int *data = (int *) mxGetData(ans);
      for (int kval = 0; kval < knn_chosen; kval++) {
        int *xchan = &data[aw*ah*3*kval+0];
        int *ychan = &data[aw*ah*3*kval+aw*ah];
        int *dchan = &data[aw*ah*3*kval+2*aw*ah];
        for (int y = 0; y < ah; y++) {
//          int *ann_row = (int *) ann->line[y];
//          int *annd_row = (int *) annd_final->line[y];
          for (int x = 0; x < aw; x++) {
//            int pp = ann_row[x];
            int pp = vann->get(x, y)[kval];
            int pos = y + x * ah;
            xchan[pos] = INT_TO_X(pp);
            ychan[pos] = INT_TO_Y(pp);
            dchan[pos] = vannd->get(x, y)[kval];
          }
        }
      }
    } else if (ann_sim_final) {
      mwSize dims[3] = { ah, aw, 5 };
      ans = mxCreateNumericArray(3, dims, mxSINGLE_CLASS, mxREAL);
      float *data = (float *) mxGetData(ans);
      float *xchan = &data[0];
      float *ychan = &data[aw*ah];
      float *dchan = &data[2*aw*ah];
      float *tchan = &data[3*aw*ah];
      float *schan = &data[4*aw*ah];
      double angle_scale = 2.0*M_PI/NUM_ANGLES;
      for (int y = 0; y < ah; y++) {
        int *ann_row = (int *) ann->line[y];
        int *annd_row = (int *) annd_final->line[y];
        int *ann_sim_row = ann_sim_final ? (int *) ann_sim_final->line[y]: NULL;
        for (int x = 0; x < aw; x++) {
          int pp = ann_row[x];
          int pos = y + x * ah;
          xchan[pos] = INT_TO_X(pp);
          ychan[pos] = INT_TO_Y(pp);
          dchan[pos] = annd_row[x];
          if (ann_sim_final) {
            int v = ann_sim_row[x];
            int tval = INT_TO_Y(v)&(NUM_ANGLES-1);
            int sval = INT_TO_X(v);

            tchan[pos] = tval*angle_scale;
            schan[pos] = xform_scale_table[sval]*(1.0/65536.0);
          }
        }
      }
    } else {
      mwSize dims[3] = { ah, aw, 3 };
      ans = mxCreateNumericArray(3, dims, mxINT32_CLASS, mxREAL);
      int *data = (int *) mxGetData(ans);
      int *xchan = &data[0];
      int *ychan = &data[aw*ah];
      int *dchan = &data[2*aw*ah];
      for (int y = 0; y < ah; y++) {
        int *ann_row = (int *) ann->line[y];
        int *annd_row = (int *) annd_final->line[y];
        for (int x = 0; x < aw; x++) {
          int pp = ann_row[x];
          int pos = y + x * ah;
          xchan[pos] = INT_TO_X(pp);
          ychan[pos] = INT_TO_Y(pp);
          dchan[pos] = annd_row[x];
        }
      }
    }
    pout[0] = ans;
  }

  // clean up
  delete vann;
  delete vann_sim;
  delete vannd;
  delete p;
  delete rp;
  destroy_bitmap(a);
  destroy_bitmap(borig);
  delete ab;
  delete bb;
  delete af;
  delete bf;
  destroy_bitmap(ann);
  destroy_bitmap(annd_final);
  destroy_bitmap(ann_sim_final);
  if (ann_prev) destroy_bitmap(ann_prev);
  if (ann_window) destroy_bitmap(ann_window);
  if (awinsize) destroy_bitmap(awinsize);
}
Ejemplo n.º 2
0
/* Match image a to image b, returning the nearest neighbor field mapping a => b coords, stored in an RGB 24-bit image as (by<<12)|bx. */
void PatchMatch::patchmatch(cv::Mat &image, cv::Mat &b, BITMAP *ann, BITMAP &annd) {
  /* Initialize with random nearest neighbor field (NNF). */
		cv::Mat a(image.size(), CV_64F);
		image.copyTo(a);
  int aew = a.cols - patch_w+1, aeh = a.rows - patch_w + 1;       /* Effective width and height (possible upper left corners of patches). */
  int bew = b.cols - patch_w+1, beh = b.rows - patch_w + 1;

  for (int ay = 0; ay < aeh; ay++) {
    for (int ax = 0; ax < aew; ax++) {
		int bx, by;
		//if((*ann)[ay][ax] == 0){
		//	  bx = rand() % bew;
		//	  by = rand() % beh;
		//	  (*ann)[ay][ax] = XY_TO_INT(bx, by);
		//}
		//else{
		//	bx = INT_TO_X((*ann)[ay][ax]);
		//	by = INT_TO_Y((*ann)[ay][ax]);
		//}
		bx = rand() % bew;
		by = rand() % beh;
		(*ann)[ay][ax] = XY_TO_INT(bx, by);
		
      annd[ay][ax] = dist(a, b, ax, ay, bx, by);
    }
  }
    int as;
    std::ofstream o_file;
    o_file.open("1.txt");
  for (int iter = 0; iter < pm_iters; iter++) {
    /* In each iteration, improve the NNF, by looping in scanline or reverse-scanline order. */
    int ystart = 0, yend = aeh, ychange = 1;
    int xstart = 0, xend = aew, xchange = 1;
    if (iter % 2 == 1) {
      xstart = xend-1; xend = -1; xchange = -1;
      ystart = yend-1; yend = -1; ychange = -1;
    }

	
//	if(iter == 2)
		as = 0;
    for (int ay = ystart; ay != yend; ay += ychange) {
      for (int ax = xstart; ax != xend; ax += xchange) { 
        /* Current (best) guess. */
		  //if(ax == 366 && ay == 367)
			 // as++;
		//  int sdsd = targetMask[ay * a.cols + ax];
		//if(ax == 352 && ay == 73){
		//	as++;
		//}
        int v = (*ann)[ay][ax];
        int xbest = INT_TO_X(v), ybest = INT_TO_Y(v);
        int dbest = annd[ay][ax];

        /* Propagation: Improve current guess by trying instead correspondences from left and above (below and right on odd iterations). */
		int targetCount = 0;
		for(int i = 0; i < patch_w; i++){
			for(int j = 0; j < patch_w; j++){
				if(targetMask[(ay + i) * a.cols + ax + j] > 0)
					targetCount++;
			}
		}
		if(targetCount > patch_w){
			int vp = (*ann)[ay][ax - xchange];
			int xp = INT_TO_X(vp) + xchange, yp = INT_TO_Y(vp);
			if ((unsigned) xp < (unsigned) bew) {
				xbest = xp;
				ybest = yp;
				(*ann)[ay][ax] = XY_TO_INT(xbest, ybest);
				annd[ay][ax] = annd[ay][ax - xchange];
				continue;
			}
			//else{
			//	vp = (*ann)[ay - ychange][ax];
			//	xp = INT_TO_X(vp), yp = INT_TO_Y(vp) + ychange;
			//	if ((unsigned) yp < (unsigned) beh) {
			//		xbest = xp;
			//		ybest = yp;
			//		(*ann)[ay][ax] = XY_TO_INT(xbest, ybest);
			//		annd[ay][ax] = annd[ay - ychange][ax];
			//		continue;
			//	}
			//}
			if((unsigned) (ay - ychange) < (unsigned) aeh){
				int vp = (*ann)[ay - ychange][ax];
			    int xp = INT_TO_X(vp), yp = INT_TO_Y(vp) + ychange;
			    if ((unsigned) yp < (unsigned) beh) {
			 		improve_guess(a, b, ax, ay, xbest, ybest, dbest, xp, yp);
			    }
			}
		}
		else{
			if ((unsigned) (ax - xchange) < (unsigned) aew) {
			  int vp = (*ann)[ay][ax - xchange];
			  int xp = INT_TO_X(vp) + xchange, yp = INT_TO_Y(vp);
			  if ((unsigned) xp < (unsigned) bew) {
				improve_guess(a, b, ax, ay, xbest, ybest, dbest, xp, yp);
			  }
			}

			if ((unsigned) (ay - ychange) < (unsigned) aeh) {
			  int vp = (*ann)[ay - ychange][ax];
			  int xp = INT_TO_X(vp), yp = INT_TO_Y(vp) + ychange;
			  if ((unsigned) yp < (unsigned) beh) {
				improve_guess(a, b, ax, ay, xbest, ybest, dbest, xp, yp);
			  }
			}
		}

        /* Random search: Improve current guess by searching in boxes of exponentially decreasing size around the current best guess. */
        int rs_start = rs_max;
        if (rs_start > MAX(b.cols, b.rows)) { rs_start = MAX(b.cols, b.rows); }
        for (int mag = rs_start; mag >= 1; mag /= 2) {
            /* Sampling window */
            int xmin = MAX(xbest-mag, 0), xmax = MIN(xbest+mag+1,bew);
            int ymin = MAX(ybest-mag, 0), ymax = MIN(ybest+mag+1,beh);
            int xp = xmin+rand()%(xmax-xmin);
            int yp = ymin+rand()%(ymax-ymin);

		    int targetCount = 0;
			for(int i = 0; i < patch_w; i++){
				for(int j = 0; j < patch_w; j++){
					if(targetMask[(yp + i) * a.cols + xp + j] > 0){
						targetCount++;
						break;
					}
				}
				if(targetCount > 0)
					break;
			}
			if(targetCount > 0){
				mag *= 2;
				continue;
			}
            improve_guess(a, b, ax, ay, xbest, ybest, dbest, xp, yp);
        }

        (*ann)[ay][ax] = XY_TO_INT(xbest, ybest);
        annd[ay][ax] = dbest;
		//a.at<cv::Vec3b>(ay, ax) = b.at<cv::Vec3b>(ybest, xbest);
		
		//for (int dy = 0; dy < patch_w; dy++) {
		//	for (int dx = 0; dx < patch_w; dx++) {
		//		a.at<cv::Vec3b>(ay + dy, ax + dx) = b.at<cv::Vec3b>(ybest + dy, xbest + dx);
		//	}
	 //   }
		if(ay != ybest || ax != xbest)
			as++;

		if(ax == 352 && ay == 73){
			as++;
		}
	//	for(int i = 0; i < cvImage.rows - 7 + 1; i++){
	//	for(int j = 0; j < cvImage.cols - 7 + 1; j++){
	//		int v = (*ann)[i][j];
	//		int x = INT_TO_X(v);
	//		int y = INT_TO_Y(v);
	//		anni.at<cv::Vec3b>(i, j).val[0] = (0+ x) % 256;
	//		anni.at<cv::Vec3b>(i, j).val[1] = (0 + y) % 256;
	//		anni.at<cv::Vec3b>(i, j).val[2] = 0;

	//		if(annd[i][j] > 0){
	//		anndi.at<cv::Vec3b>(i, j).val[0] = annd[i][j] % 256;
	//		}
	//		else 
	//			anndi.at<cv::Vec3b>(i, j).val[0] = 0;
	//		anndi.at<cv::Vec3b>(i, j).val[1] = 0;
	//		anndi.at<cv::Vec3b>(i, j).val[2] = 0;
	//	}
	//}
	//cv::imshow("r", anni);
	//cv::imshow("rd", anndi);
      }
    }
	//std::string s[] = {"0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19"};
	//cv::imshow(s[iter], a);

	o_file<<as<<std::endl;
	std::cout<<as<<std::endl;
  }
  o_file.close();

  a.copyTo(image);
}
/* Match image a to image b, returning the nearest neighbor field mapping a => b coords, stored in an RGB 24-bit image as (by<<12)|bx. */
void patchmatch(BITMAP *a, BITMAP *b, BITMAP *&ann, BITMAP *&annd) {
  /* Initialize with random nearest neighbor field (NNF). */
  ann = new BITMAP(a->w, a->h);
  annd = new BITMAP(a->w, a->h);
  int aew = a->w - patch_w+1, aeh = a->h - patch_w + 1;       /* Effective width and height (possible upper left corners of patches). */
  int bew = b->w - patch_w+1, beh = b->h - patch_w + 1;
  memset(ann->data, 0, sizeof(int)*a->w*a->h);
  memset(annd->data, 0, sizeof(int)*a->w*a->h);
  for (int ay = 0; ay < aeh; ay++) {
    for (int ax = 0; ax < aew; ax++) {
      int bx = rand()%bew;
      int by = rand()%beh;
      (*ann)[ay][ax] = XY_TO_INT(bx, by);
      (*annd)[ay][ax] = dist(a, b, ax, ay, bx, by);
    }
  }
  for (int iter = 0; iter < pm_iters; iter++) {
    /* In each iteration, improve the NNF, by looping in scanline or reverse-scanline order. */
    int ystart = 0, yend = aeh, ychange = 1;
    int xstart = 0, xend = aew, xchange = 1;
    if (iter % 2 == 1) {
      xstart = xend-1; xend = -1; xchange = -1;
      ystart = yend-1; yend = -1; ychange = -1;
    }
    for (int ay = ystart; ay != yend; ay += ychange) {
      for (int ax = xstart; ax != xend; ax += xchange) { 
        /* Current (best) guess. */
        int v = (*ann)[ay][ax];
        int xbest = INT_TO_X(v), ybest = INT_TO_Y(v);
        int dbest = (*annd)[ay][ax];

        /* Propagation: Improve current guess by trying instead correspondences from left and above (below and right on odd iterations). */
        if ((unsigned) (ax - xchange) < (unsigned) aew) {
          int vp = (*ann)[ay][ax-xchange];
          int xp = INT_TO_X(vp) + xchange, yp = INT_TO_Y(vp);
          if ((unsigned) xp < (unsigned) bew) {
            improve_guess(a, b, ax, ay, xbest, ybest, dbest, xp, yp);
          }
        }

        if ((unsigned) (ay - ychange) < (unsigned) aeh) {
          int vp = (*ann)[ay-ychange][ax];
          int xp = INT_TO_X(vp), yp = INT_TO_Y(vp) + ychange;
          if ((unsigned) yp < (unsigned) beh) {
            improve_guess(a, b, ax, ay, xbest, ybest, dbest, xp, yp);
          }
        }

        /* Random search: Improve current guess by searching in boxes of exponentially decreasing size around the current best guess. */
        int rs_start = rs_max;
        if (rs_start > MAX(b->w, b->h)) { rs_start = MAX(b->w, b->h); }
        for (int mag = rs_start; mag >= 1; mag /= 2) {
          /* Sampling window */
          int xmin = MAX(xbest-mag, 0), xmax = MIN(xbest+mag+1,bew);
          int ymin = MAX(ybest-mag, 0), ymax = MIN(ybest+mag+1,beh);
          int xp = xmin+rand()%(xmax-xmin);
          int yp = ymin+rand()%(ymax-ymin);
          improve_guess(a, b, ax, ay, xbest, ybest, dbest, xp, yp);
        }

        (*ann)[ay][ax] = XY_TO_INT(xbest, ybest);
        (*annd)[ay][ax] = dbest;
      }
    }
  }
}
Ejemplo n.º 4
0
void PatchMatch::vote(cv::Mat &result, cv::Mat &source, BITMAP *ann){
	int length = result.rows * result.cols;
	int *recordL = new int[length];
	int *recordA = new int[length];
	int *recordB = new int[length];
	int *recordT = new int[length];

	for(int row = 0; row < result.rows; row++){
		for(int col = 0; col < result.cols; col++){
			recordL[row * result.cols + col] = 0;
			recordA[row * result.cols + col] = 0;
			recordB[row * result.cols + col] = 0;
			recordT[row * result.cols + col] = 0;
		}
	}
	int count = 0;
	for(int row = 0; row < result.rows - patch_w + 1; row++){
		for(int col = 0; col < result.cols - patch_w + 1; col++){
			// 判断是否在target内部,内部的不算加权
			int tagertCount = 0;
			for (int dy = 0; dy < patch_w; dy++) {
				for (int dx = 0; dx < patch_w; dx++) {
					int ry = row + dy;
					int rx = col + dx;
					if(targetMask[ry * result.cols + rx] == 1)
						tagertCount++;
				}
		    }
			if(tagertCount > patch_w)
				continue;

			//加权
			int v = (*ann)[row][col];
			int x = INT_TO_X(v);
			int y = INT_TO_Y(v);
			for (int dy = 0; dy < patch_w; dy++) {
				for (int dx = 0; dx < patch_w; dx++) {
					int sy = y + dy;
					int sx = x + dx;
					int ry = row + dy;
					int rx = col + dx;

					int b = recordT[0];
					if(source.at<cv::Vec3b>(sy, sx).val[0] == 0 && source.at<cv::Vec3b>(sy, sx).val[1] == 0 && source.at<cv::Vec3b>(sy, sx).val[2] == 0)
						continue;
					recordL[ry * result.cols + rx] += source.at<cv::Vec3b>(sy, sx).val[0];
					recordA[ry * result.cols + rx] += source.at<cv::Vec3b>(sy, sx).val[1];
					recordB[ry * result.cols + rx] += source.at<cv::Vec3b>(sy, sx).val[2];
					recordT[ry * result.cols + rx] += 1;

					if(b < recordT[0]){
						count++;
					}
				}

		    }
		}
	}

	targetCount = 0;

	for(int row = 0; row < result.rows; row++){
		for(int col = 0; col < result.cols; col++){
			if(targetMask[row * result.cols + col] == 1){
				targetCount++;
				if(recordT[row * result.cols + col] == 0)
					continue;
				result.at<cv::Vec3b>(row, col).val[0] = recordL[row * result.cols + col] / recordT[row * result.cols + col];
				result.at<cv::Vec3b>(row, col).val[1] = recordA[row * result.cols + col] / recordT[row * result.cols + col];
				result.at<cv::Vec3b>(row, col).val[2] = recordB[row * result.cols + col] / recordT[row * result.cols + col];
				targetMask[row * result.cols + col] = 0;
			}
			//if(result.at<cv::Vec3b>(row, col).val[0] != 0 || result.at<cv::Vec3b>(row, col).val[1] != 0 || result.at<cv::Vec3b>(row, col).val[2] != 0){
			//	targetMask[row * result.cols + col] = 0;
			//}
		}
	}
	//int c = 0;
	//for(int i = 0; i < result.cols * result.rows; i++){
	//	if(targetMask[i] > 0)
	//		c++;
	//}

	delete recordL;
	delete recordA;
	delete recordB;
	delete recordT;
}