/* 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); }
/* * 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)); } }