static void image_imagesize_callback(t_image *x, t_float w, t_float h) { //fprintf(stderr,"received w %f h %f should %d spill %d\n", w, h, gobj_shouldvis((t_gobj *)x, glist_getcanvas(x->x_glist)), x->x_gop_spill); x->x_img_width = w; x->x_img_height = h; if (x->x_img_width + x->x_img_height == 0) { //invalid image if (strcmp("@pd_extra/ggee/empty_image.png", x->x_fname->s_name) != 0) { x->x_fname = gensym("@pd_extra/ggee/empty_image.png"); image_doopen(x); return; } } if (!gobj_shouldvis((t_gobj *)x, x->x_glist) && !x->x_gop_spill) { //fprintf(stderr,"erasing\n"); image_erase(x, glist_getcanvas(x->x_glist)); } else { //sys_vgui("catch {.x%lx.c delete %xMT}\n", glist_getcanvas(x->x_glist), x); // reselect if we are on a toplevel canvas to adjust the selection rectangle, if necessary if (glist_isselected(x->x_glist, (t_gobj *)x) && glist_getcanvas(x->x_glist) == x->x_glist) { image_select((t_gobj *)x, glist_getcanvas(x->x_glist), 0); image_select((t_gobj *)x, glist_getcanvas(x->x_glist), 1); } canvas_fixlinesfor(x->x_glist,(t_text*) x); } }
static void image_vis(t_gobj *z, t_glist *glist, int vis) { //fprintf(stderr,"image_vis %d\n", vis); t_image* x = (t_image*)z; if (vis) image_drawme(x, glist, 1); else image_erase(x,glist); }
void input2darray_to_matches( image_t *match_x, image_t *match_y, image_t *match_z, const mxArray *p){ const int nmatch = mxGetM(p); const int w = match_x->width, h = match_x->height, s = match_x->stride; float *data = (float*) mxGetData(p); image_erase(match_x); image_erase(match_y); image_erase(match_z); for( int i=0 ; i<nmatch ; i++){ float x1 = data[0*nmatch+i], y1 = data[1*nmatch+i], x2 = data[2*nmatch+i], y2 = data[3*nmatch+i]; if( x1<0 || y1<0 || x2<0 || y2<0 || x1>=w || y1>=h || x2>=w || y2>=h){ fprintf(stderr, "Warning: match out of bound: %f %f -> %f %f\n", x1, y1, x2, y2); x1 = MINMAX(x1,w); x2 = MINMAX(x2,w); y1 = MINMAX(y1,h); y2 = MINMAX(y2,h); } int pos = (int) (y1*s+x1); match_x->data[ pos ] = x2-x1; match_y->data[ pos ] = y2-y1; match_z->data[ pos ] = 1.0f; } }
/* 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); }
int main(int argc, char ** argv){ image_t *match_x = NULL, *match_y = NULL, *match_z = NULL; // load images if(argc < 4){ fprintf(stderr,"Wrong command, require at least 3 arguments.\n\n"); usage(); exit(1); } color_image_t *im1 = color_image_load(argv[1]), *im2 = color_image_load(argv[2]); if(im1->width != im2->width || im1->height != im2->height){ fprintf(stderr,"Image dimensions does not match\n"); exit(1); } // set params to default optical_flow_params_t* params = (optical_flow_params_t*) malloc(sizeof(optical_flow_params_t)); if(!params){ fprintf(stderr,"error deepflow(): not enough memory\n"); exit(1); } optical_flow_params_default(params); // parse options int current_arg = 4; while(1){ if( current_arg >= argc) break; if(!strcmp(argv[current_arg],"-h") || !strcmp(argv[current_arg],"--help") ){ usage(); exit(1); }else if(!strcmp(argv[current_arg],"-a") || !strcmp(argv[current_arg],"-alpha") ){ current_arg++; if(current_arg >= argc) require_argument("alpha"); float alpha = atof(argv[current_arg++]); if(alpha<0){ fprintf(stderr,"Alpha argument cannot be negative\n"); exit(1); } params->alpha = alpha; }else if(!strcmp(argv[current_arg],"-b") || !strcmp(argv[current_arg],"-beta") ){ current_arg++; if(current_arg >= argc) require_argument("beta"); float beta = atof(argv[current_arg++]); if(beta<0){ fprintf(stderr,"Beta argument cannot be negative\n"); exit(1); } params->beta = beta; }else if(!strcmp(argv[current_arg],"-g") || !strcmp(argv[current_arg],"-gamma") ){ current_arg++; if(current_arg >= argc) require_argument("gamma"); float gamma = atof(argv[current_arg++]); if(gamma<0){ fprintf(stderr,"Gamma argument cannot be negative\n"); exit(1); } params->gamma = gamma; }else if(!strcmp(argv[current_arg],"-d") || !strcmp(argv[current_arg],"-delta") ){ current_arg++; if(current_arg >= argc) require_argument("delta"); float delta = atof(argv[current_arg++]); if(delta<0) { fprintf(stderr,"Delta argument cannot be negative\n"); exit(1); } params->delta = delta; }else if(!strcmp(argv[current_arg],"-s") || !strcmp(argv[current_arg],"-sigma") ){ current_arg++; if(current_arg >= argc) require_argument("sigma"); float sigma = atof(argv[current_arg++]); if(sigma<0){ fprintf(stderr,"Sigma argument is negative\n"); exit(1); } params->sigma = sigma; }else if(!strcmp(argv[current_arg],"-bk")) { current_arg++; if(current_arg >= argc) require_argument("bk"); float betak = atof(argv[current_arg++]); if(betak<0.0f){ fprintf(stderr,"Bk argument must be positive\n"); exit(1); } params->bk = betak; }else if(!strcmp(argv[current_arg],"-e") || !strcmp(argv[current_arg],"-eta") ){ current_arg++; if(current_arg >= argc) require_argument("eta"); float eta = atof(argv[current_arg++]); if(eta<0.25 || eta>0.98){ fprintf(stderr,"Eta argument has to be between 0.25 and 0.98\n"); exit(1); } params->eta = eta; }else if( !strcmp(argv[current_arg],"-minsize") ){ current_arg++; if(current_arg >= argc) require_argument("minsize"); int minsize = atoi(argv[current_arg++]); if(minsize < 10){ fprintf(stderr,"Minsize argument has to be higher than 10\n"); exit(1); } params->min_size = minsize; }else if(!strcmp(argv[current_arg],"-inner") ){ current_arg++; if(current_arg >= argc) require_argument("inner"); int inner = atoi(argv[current_arg++]); if(inner<=0){ fprintf(stderr,"Inner argument must be strictly positive\n"); exit(1); } params->n_inner_iteration = inner; }else if(!strcmp(argv[current_arg],"-iter") ){ current_arg++; if(current_arg >= argc) require_argument("iter"); int iter = atoi(argv[current_arg++]); if(iter<=0){ fprintf(stderr,"Iter argument must be strictly positive\n"); exit(1); } params->n_solver_iteration = iter; }else if( !strcmp(argv[current_arg],"-match") || !strcmp(argv[current_arg],"-matchf")){ int wm = im1->width, hm = im1->height; if( !strcmp(argv[current_arg++],"-match") ){ wm = 512; hm = 256; } image_delete(match_x); image_delete(match_y); image_delete(match_z); match_x = image_new(wm, hm); match_y = image_new(wm, hm); match_z = image_new(wm, hm); image_erase(match_x); image_erase(match_y); image_erase(match_z); FILE *fid = stdin; if( current_arg<argc && argv[current_arg][0] != '-'){ fid = fopen(argv[current_arg++], "r"); if(fid==NULL){ fprintf(stderr, "Cannot read matches from file %s", argv[current_arg-1]); exit(1); } } int x1, x2, y1, y2; float score; while(!feof(fid) && fscanf(fid, "%d %d %d %d %f\n", &x1, &y1, &x2, &y2, &score)==5){ if( x1<0 || y1<0 || x2<0 || y2<0 || x1>=wm || y1>=hm || x2>=wm || y2>=hm){ fprintf(stderr, "Error while reading matches %d %d -> %d %d, out of bounds\n", x1, y1, x2, y2); exit(1); } match_x->data[ y1*match_x->stride+x1 ] = (float) (x2-x1); match_y->data[ y1*match_x->stride+x1 ] = (float) (y2-y1); match_z->data[ y1*match_x->stride+x1 ] = score; } }else if ( !strcmp(argv[current_arg],"-sintel") ){ current_arg++; optical_flow_params_sintel(params); }else if ( !strcmp(argv[current_arg],"-middlebury") ){ current_arg++; optical_flow_params_middlebury(params); }else if ( !strcmp(argv[current_arg],"-kitti") ){ current_arg++; optical_flow_params_kitti(params); }else{ if(argv[current_arg][0] == '-'){ fprintf(stderr,"Unknow options %s\n",argv[current_arg]); }else{ fprintf(stderr,"Error while reading options, %s\n",argv[current_arg]); } exit(1); } } image_t *wx = image_new(im1->width,im1->height), *wy = image_new(im1->width,im1->height); optical_flow(wx, wy, im1, im2, params, match_x, match_y, match_z); writeFlowFile(argv[3], wx, wy); image_delete(wx); image_delete(wy); image_delete(match_x); image_delete(match_y); image_delete(match_z); color_image_delete(im1); color_image_delete(im2); free(params); return 0; }