void handleKeyboardspecial(int key, int x, int y) { /* keyboard handler */ switch(key) { case GLUT_KEY_F1: /* call help menu */ print_console_line(); printf("\n\n F1 ........this help\n"); printf(" F2 ........write out displacement field in colour code \n"); printf(" F8 ........write out motion compensated 2nd frame \n"); printf(" ESC ........program termination\n"); printf(" p ........select presmoothing parameter\n"); printf(" a ........select smoothness weight\n"); printf(" i ........select number of iterations\n"); printf(" o ........select SOR overrelaxation parameter\n"); printf(" w ........select number of warping levels\n"); printf(" e ........select warping rescaling factor\n"); printf(" g ........select max displacement magnitude\n"); printf(" up ........increase active parameter\n"); printf(" down ........decrease active parameter\n"); printf(" , ........direct computation on/off \n"); printf(" . ........compute displacement field \n"); print_console_line(); fflush(stdout); break; case GLUT_KEY_F2: /* write out displacement field */ if (g_u_ref!=NULL) { int i,j; for (i=g_bx; i<g_nx+g_bx; i++) for (j=g_by; j<g_ny+g_by; j++) { if((g_u_ref[i][j]==100.0)&&(g_v_ref[i][j]==100.0)) { g_u[i][j]=100.0; g_v[i][j]=100.0; } } } write_ppm_blank_header("out.ppm",g_nx,g_ny); write_ppm_data("out.ppm",g_p6,g_nx,g_ny,g_bx+g_nx,g_by); write_ppm_blank_header("displacement.ppm",g_nx,g_ny); write_ppm_data("displacement.ppm",g_disp,g_nx,g_ny,g_bx,g_by); break; case GLUT_KEY_F8: /* write out motion compensated 2nd frame */ backward_registration(g_f1,g_f2,g_f2_bw,g_u,g_v, g_nx,g_ny,g_bx,g_by,g_hx,g_hy); write_pgm_blank_header("frame2_bw.pgm",g_nx,g_ny); write_pgm_data("frame2_bw.pgm",g_f2_bw,g_nx,g_ny,g_bx,g_by); break; case GLUT_KEY_DOWN: /* decrease sigma */ if (g_active_param==0) { g_e_sigma-=0.1; if (g_e_sigma<0.1) g_e_sigma=0.1; if (g_direct_compute==1) handleComputeDisplacements(); break; } /* decrease alpha */ if (g_active_param==1) { g_m_alpha--; if (g_m_alpha<=0) g_m_alpha=1; if (g_direct_compute==1) handleComputeDisplacements(); break; } /* decrease number of iterations */ if (g_active_param==2) { g_n_iter-=100; if (g_n_iter<0) g_n_iter=0; if (g_direct_compute==1) handleComputeDisplacements(); break; } /* decrease displacement field magnitude (visualsiation) */ if (g_active_param==4) { if (g_g_max_disp>=0.01) g_g_max_disp=g_g_max_disp/1.1; break; } /* decrease omega */ if (g_active_param==5) { g_n_omega=g_n_omega-0.01; if (g_n_omega<0.01) g_n_omega=0.01; if (g_direct_compute==1) handleComputeDisplacements(); break; } /* decrease number of warping levels */ if (g_active_param==6) { g_n_warp_levels-=1; if (g_n_warp_levels<0) g_n_warp_levels=0; if (g_direct_compute==1) handleComputeDisplacements(); break; } /* decrease type */ if (g_active_param==8) { g_m_type-=1; if (g_m_type<0) g_m_type=0; if (g_direct_compute==1) handleComputeDisplacements(); break; } /* decrease eta */ if (g_active_param==7) { g_n_warp_eta-=0.05; if (g_n_warp_eta<0.05) g_n_warp_eta=0.05; if (g_direct_compute==1) handleComputeDisplacements(); break; } case GLUT_KEY_UP: /* increase sigma */ if (g_active_param==0) { g_e_sigma+=0.1; if (g_direct_compute==1) handleComputeDisplacements(); break; } /* increase alpha */ if (g_active_param==1) { g_m_alpha++; if (g_direct_compute==1) handleComputeDisplacements(); break; } /* increase number of iterations */ if (g_active_param==2) { g_n_iter+=100; if (g_direct_compute==1) handleComputeDisplacements(); break; } /* increase displacement field magnitude (visualisation) */ if (g_active_param==4) { g_g_max_disp=g_g_max_disp*1.1; break; } /* increase omega */ if (g_active_param==5) { g_n_omega+=0.01; if (g_n_omega>1.99) g_n_omega=1.99; if (g_direct_compute==1) handleComputeDisplacements(); break; } /* decrease number of warping levels */ if (g_active_param==6) { g_n_warp_levels+=1; if (g_direct_compute==1) handleComputeDisplacements(); break; } /* increase eta */ if (g_active_param==7) { g_n_warp_eta+=0.05; if (g_n_warp_eta>0.95) g_n_warp_eta=0.95; if (g_direct_compute==1) handleComputeDisplacements(); break; } /* increase type */ if (g_active_param==8) { g_m_type+=1; if (g_m_type>10) g_m_type=10; if (g_direct_compute==1) handleComputeDisplacements(); break; } default: printf("\nUnknown key pressed (Code %d).",key); } /* show new parameters and displacement field */ showParams(); handleDraw(); return; }
void HORN_SCHUNCK_WARP ( /*****************************************************/ float **f1_orig, /* in : 1st image (original resolution) */ float **f2_orig, /* in : 2nd image (original resolution) */ int nx_orig, /* in : size in x-direction (original resolution)*/ int ny_orig, /* in : size in y-direction (original resoluiton)*/ float **f1_res, /* in+out : 1st image, resampled */ float **f2_res, /* in+out : 2nd image, resampled */ float **f2_res_warp, /* in+out : 2nd image, resampled and warped */ float **du, /* in+out : x-component of flow increment */ float **dv, /* in+out : y-component of flow increment */ float **u, /* in+out : x-component of flow field */ float **v, /* in+out : y-component of flow field */ float **tmp, /* in+out : temporary aray for resampling */ int nx_fine, /* in : size in x-direction (current resolution) */ int ny_fine, /* in : size in y-direction (current resolution) */ int bx, /* in : boundary size in x-direction */ int by, /* in : boundary size in y-direction */ float hx_fine, /* in : spacing in x-direction (current resol.) */ float hy_fine, /* in : spacing in y-direction (current resol.) */ float m_alpha, /* in : smoothness weight */ float epsilon_d, /* in : diffusivity param data term */ float epsilon_s, float w_bright_grad, int num_iter_inner, /* in : inner solver iterations */ int num_iter_outer, /* in : outer nonlin update iterations */ float n_omega, /* in : SOR overrelaxation parameter */ float n_warp_eta, /* in : warping reduction factor between levels */ int max_rec_depth, /* in : maximum recursion depth */ int rec_depth /* in : current recursion depth */ /*****************************************************/ ) /* implements warping for the Horn and Schunck method */ { /************************************************/ int nx_coarse,ny_coarse; /* dimensions on previous coarser grid */ float hx_coarse,hy_coarse; /* grid sizes on previous coarser grid */ /************************************************/ /* compute dimensions and grid sizes for previous coarser grid */ nx_coarse=(int)ceil(nx_orig*pow(n_warp_eta,rec_depth+1)); ny_coarse=(int)ceil(ny_orig*pow(n_warp_eta,rec_depth+1)); hx_coarse=(float)nx_orig/(float)nx_coarse; hy_coarse=(float)ny_orig/(float)ny_coarse; /* start at coarsest level by recursively calling the routine */ if (rec_depth<max_rec_depth) { HORN_SCHUNCK_WARP(f1_orig, f2_orig, nx_orig, ny_orig, f1_res, f2_res, f2_res_warp, du, dv, u, v, tmp, nx_coarse, ny_coarse, bx, by, hx_coarse, hy_coarse, m_alpha, epsilon_d,epsilon_s, w_bright_grad, num_iter_inner,num_iter_outer, n_omega, n_warp_eta, max_rec_depth,rec_depth+1); } /* ---- resample images ---------------------------------------------------- */ /* restrict original image pair to resolution of current level */ resample_2d(f1_orig,nx_orig,ny_orig,bx,by,f1_res,nx_fine,ny_fine,tmp); resample_2d(f2_orig,nx_orig,ny_orig,bx,by,f2_res,nx_fine,ny_fine,tmp); /* ---- get overall flow field from previous resolution level -------------- */ /* if on coarsest resolution */ if(rec_depth==max_rec_depth) { /* set flow field zero */ set_matrix_2d(u,nx_fine+2*bx,ny_fine+2*by,0,0,(float)0.0); set_matrix_2d(v,nx_fine+2*bx,ny_fine+2*by,0,0,(float)0.0); } /* if not on coarsest resolution */ else { /* interpolate solution from previous coarser level */ resample_2d(u,nx_coarse,ny_coarse,bx,by,u,nx_fine,ny_fine,tmp); resample_2d(v,nx_coarse,ny_coarse,bx,by,v,nx_fine,ny_fine,tmp); } /* ---- set up difference problem at current resolution -------------------- */ /* warp second image by overall flow field from previous coarser resolution */ backward_registration(f1_res,f2_res,f2_res_warp,u,v, nx_fine,ny_fine,bx,by,hx_fine,hy_fine); /* ---- solve difference problem at current resolution --------------------- */ /* solve difference problem at current resolution to obtain increment */ HORN_SCHUNCK_WARP_LEVEL(f1_res, f2_res_warp, du, dv, u, v, nx_fine, ny_fine, bx, by, hx_fine, hy_fine, m_alpha, epsilon_d, epsilon_s, w_bright_grad, num_iter_inner, num_iter_outer, n_omega); /* ---- compute overall flow field at current resolution ------------------- */ /* sum up flow increment */ add_matrix_2d(u,du,u,nx_fine,ny_fine,bx,by); add_matrix_2d(v,dv,v,nx_fine,ny_fine,bx,by); // printf (" current depth: -- %d -- \n", rec_depth); }