Ejemplo n.º 1
0
/* perform flow computation at one level of the pyramid */
void compute_one_level(image_t *wx, image_t *wy, color_image_t *im1, color_image_t *im2, const variational_params_t *params){ 
    const int width = wx->width, height = wx->height, stride=wx->stride;

    image_t *du = image_new(width,height), *dv = image_new(width,height), // the flow increment
        *mask = image_new(width,height), // mask containing 0 if a point goes outside image boundary, 1 otherwise
        *smooth_horiz = image_new(width,height), *smooth_vert = image_new(width,height), // horiz: (i,j) contains the diffusivity coeff from (i,j) to (i+1,j) 
        *uu = image_new(width,height), *vv = image_new(width,height), // flow plus flow increment
        *a11 = image_new(width,height), *a12 = image_new(width,height), *a22 = image_new(width,height), // system matrix A of Ax=b for each pixel
        *b1 = image_new(width,height), *b2 = image_new(width,height); // system matrix b of Ax=b for each pixel

    color_image_t *w_im2 = color_image_new(width,height), // warped second image
        *Ix = color_image_new(width,height), *Iy = color_image_new(width,height), *Iz = color_image_new(width,height), // first order derivatives
        *Ixx = color_image_new(width,height), *Ixy = color_image_new(width,height), *Iyy = color_image_new(width,height), *Ixz = color_image_new(width,height), *Iyz = color_image_new(width,height); // second order derivatives
  
  
    image_t *dpsis_weight = compute_dpsis_weight(im1, 5.0f, deriv);  
  
    int i_outer_iteration;
    for(i_outer_iteration = 0 ; i_outer_iteration < params->niter_outer ; i_outer_iteration++){
        int i_inner_iteration;
        // warp second image
        image_warp(w_im2, mask, im2, wx, wy);
        // compute derivatives
        get_derivatives(im1, w_im2, deriv, Ix, Iy, Iz, Ixx, Ixy, Iyy, Ixz, Iyz);
        // erase du and dv
        image_erase(du);
        image_erase(dv);
        // initialize uu and vv
        memcpy(uu->data,wx->data,wx->stride*wx->height*sizeof(float));
        memcpy(vv->data,wy->data,wy->stride*wy->height*sizeof(float));
        // inner fixed point iterations
        for(i_inner_iteration = 0 ; i_inner_iteration < params->niter_inner ; i_inner_iteration++){
            //  compute robust function and system
            compute_smoothness(smooth_horiz, smooth_vert, uu, vv, dpsis_weight, deriv_flow, half_alpha );
            compute_data_and_match(a11, a12, a22, b1, b2, mask, du, dv, Ix, Iy, Iz, Ixx, Ixy, Iyy, Ixz, Iyz, half_delta_over3, half_gamma_over3);
            sub_laplacian(b1, wx, smooth_horiz, smooth_vert);
            sub_laplacian(b2, wy, smooth_horiz, smooth_vert);
            // solve system
            sor_coupled(du, dv, a11, a12, a22, b1, b2, smooth_horiz, smooth_vert, params->niter_solver, params->sor_omega);          
            // update flow plus flow increment
            int i;
            v4sf *uup = (v4sf*) uu->data, *vvp = (v4sf*) vv->data, *wxp = (v4sf*) wx->data, *wyp = (v4sf*) wy->data, *dup = (v4sf*) du->data, *dvp = (v4sf*) dv->data;
            for( i=0 ; i<height*stride/4 ; i++){
                (*uup) = (*wxp) + (*dup);
                (*vvp) = (*wyp) + (*dvp);
                uup+=1; vvp+=1; wxp+=1; wyp+=1;dup+=1;dvp+=1;
	        }
        }
        // add flow increment to current flow
        memcpy(wx->data,uu->data,uu->stride*uu->height*sizeof(float));
        memcpy(wy->data,vv->data,vv->stride*vv->height*sizeof(float));
    }   
    // free memory
    image_delete(du); image_delete(dv);
    image_delete(mask);
    image_delete(smooth_horiz); image_delete(smooth_vert);
    image_delete(uu); image_delete(vv);
    image_delete(a11); image_delete(a12); image_delete(a22);
    image_delete(b1); image_delete(b2);
    image_delete(dpsis_weight);
    color_image_delete(w_im2); 
    color_image_delete(Ix); color_image_delete(Iy); color_image_delete(Iz);
    color_image_delete(Ixx); color_image_delete(Ixy); color_image_delete(Iyy); color_image_delete(Ixz); color_image_delete(Iyz);
}
Ejemplo n.º 2
0
/*
 * call-seq:
 *   IplImage.smoothness(<i>lowFreqRatio, blankDensity, messyDensity, highFreqRatio</i>) -> [ symbol, float, float ]
 *
 * Determines if the image's smoothness is either, :smooth, :messy, or :blank.
 *
 * Original Author: [email protected]
 */
VALUE
rb_smoothness(int argc, VALUE *argv, VALUE self)
{
  VALUE lowFreqRatio, blankDensity, messyDensity, highFreqRatio;
  rb_scan_args(argc, argv, "04", &lowFreqRatio, &blankDensity, &messyDensity, &highFreqRatio);

  double f_lowFreqRatio, f_blankDensity, f_messyDensity, f_highFreqRatio;
  double outLowDensity, outHighDensity;
  if (TYPE(lowFreqRatio) == T_NIL) {
    f_lowFreqRatio = 10 / 128.0f;
  } else {
    Check_Type(lowFreqRatio, T_FLOAT);
    f_lowFreqRatio = NUM2DBL(lowFreqRatio);
  }
  if (TYPE(blankDensity) == T_NIL) {
    f_blankDensity = 1.2f;
  } else {
    Check_Type(blankDensity, T_FLOAT);
    f_blankDensity = NUM2DBL(blankDensity);
  }
  if (TYPE(messyDensity) == T_NIL) {
    f_messyDensity = 0.151f;
  } else {
    Check_Type(messyDensity, T_FLOAT);
    f_messyDensity = NUM2DBL(messyDensity);
  }
  if (TYPE(highFreqRatio) == T_NIL) {
    f_highFreqRatio = 5 / 128.0f;
  } else {
    Check_Type(highFreqRatio, T_FLOAT);
    f_highFreqRatio = NUM2DBL(highFreqRatio);
  }

  IplImage *pFourierImage;
  IplImage *p64DepthImage;

  // the image is required to be in depth of 64
  if (IPLIMAGE(self)->depth == 64) {
	p64DepthImage = NULL;
	pFourierImage = create_fourier_image(IPLIMAGE(self));
  } else {
	p64DepthImage = rb_cvCreateImage(cvGetSize(IPLIMAGE(self)), IPL_DEPTH_64F, 1);
	cvConvertScale(CVARR(self), p64DepthImage, 1.0, 0.0);
	pFourierImage = create_fourier_image(p64DepthImage);
  }

  Smoothness result = compute_smoothness(pFourierImage, f_lowFreqRatio, f_blankDensity, f_messyDensity, f_highFreqRatio, outLowDensity, outHighDensity);

  cvReleaseImage(&pFourierImage);
  if (p64DepthImage != NULL)
	cvReleaseImage(&p64DepthImage);

  switch(result)
  {
    case SMOOTH:
      return rb_ary_new3(3, ID2SYM(rb_intern("smooth")), rb_float_new(outLowDensity), rb_float_new(outHighDensity));
    case MESSY:
      return rb_ary_new3(3, ID2SYM(rb_intern("messy")), rb_float_new(outLowDensity), rb_float_new(outHighDensity));
    case BLANK:
      return rb_ary_new3(3, ID2SYM(rb_intern("blank")), rb_float_new(outLowDensity), rb_float_new(outHighDensity));
    default:
      return rb_ary_new3(3, NULL, rb_float_new(outLowDensity), rb_float_new(outHighDensity));
  }
}