void warp3(float ***slice /* [nx][ny][nt] input */, float ***coord1 /* [nx][ny][nt] coordinates */, float ***coord2 /* [nx][ny][nt] coordinates */, float ***coord3 /* [nx][ny][nt] coordinates */, float ***slice2 /* [n3][n2][n1] output */) /*< apply warping >*/ { int i1, i2, i3; for (i3=0; i3 < nx; i3++) { for (i2=0; i2 < ny; i2++) { stretch4_define (map1,coord1[i3][i2]); stretch4_apply (false,map1,slice[i3][i2],trace1); for (i1=0; i1 < n1; i1++) { slice1[i1][i3][i2] = trace1[i1]; } stretch4_apply (false,map1,coord2[i3][i2],trace1); for (i1=0; i1 < n1; i1++) { str2[i1][i3][i2] = trace1[i1]; } stretch4_apply (false,map1,coord3[i3][i2],trace1); for (i1=0; i1 < n1; i1++) { str3[i1][i3][i2] = trace1[i1]; } } } for (i1=0; i1 < n1; i1++) { warp2(slice1[i1],str2[i1],str3[i1],trace2); for (i3=0; i3 < n3; i3++) { for (i2=0; i2 < n2; i2++) { slice2[i3][i2][i1] = trace2[i3][i2]; } } } }
int main (int argc, char* argv[]) { bool half, mzo; int it,ix,ih, nt,nx, nh, CDPtype, ntx; float dt, t0, h, h0, t, tm, tp, tx, tq, dh, dx, x0, x; float *px, *ph, **xstr, **tstr, **slice, **img, eps; sf_file cmp, mig, xdip, hdip; sf_init (argc,argv); cmp = sf_input("in"); xdip = sf_input("xdip"); hdip = sf_input("hdip"); mig = sf_output("out"); if (SF_FLOAT != sf_gettype(cmp)) sf_error("Need float input"); if (!sf_histint(cmp,"n1",&nt)) sf_error("No n1= in input"); if (!sf_histfloat(cmp,"d1",&dt)) sf_error("No d1= in input"); if (!sf_histfloat(cmp,"o1",&t0)) sf_error("No o1= in input"); if (!sf_histint(cmp,"n3",&nh)) sf_error("No n3= in input"); if (!sf_histfloat(cmp,"d3",&dh)) sf_error("No d3= in input"); if (!sf_histfloat(cmp,"o3",&h0)) sf_error("No o3= in input"); if (!sf_histint(cmp,"n2",&nx)) sf_error("No n2= in input"); if (!sf_histfloat(cmp,"d2",&dx)) sf_error("No d2= in input"); if (!sf_histfloat(cmp,"o2",&x0)) sf_error("No o2= in input"); if (!sf_getbool("half",&half)) half=true; /* if y, the second axis is half-offset instead of full offset */ if (!half) { dh *= 0.5; h0 *= 0.5; } CDPtype=0.5+dh/dx; if (1 != CDPtype) sf_histint(cmp,"CDPtype",&CDPtype); sf_warning("CDPtype=%d",CDPtype); ntx = nt*nx; px = sf_floatalloc(nt); ph = sf_floatalloc(nt); tstr = sf_floatalloc2(nt,nx); xstr = sf_floatalloc2(nt,nx); slice = sf_floatalloc2(nt,nx); img = sf_floatalloc2(nt,nx); if (!sf_getbool("mzo",&mzo)) mzo=false; /* do migration to zero offset */ if (!sf_getfloat("eps",&eps)) eps=1.0; /* stretch regularization */ warp2_init (nt, t0, dt, nx, x0, dx, nt, nx, eps); for (ih = 0; ih < nh; ih++) { sf_floatread (slice[0], ntx, cmp); for (ix = 0; ix < nx; ix++) { x = x0 + ix*dx; h = h0 + (ih+0.5)*dh + (dh/CDPtype)*(ix%CDPtype); sf_floatread (px, nt, xdip); sf_floatread (ph, nt, hdip); for (it=0; it < nt; it++) { t = t0 + it*dt; tm = t - ph[it]*h*dt/dh; tx = h*px[it]*dt/dx; tp = tm*ph[it] + px[it]*tx*dh/dx; tq = tm*tm-tx*tx; if (mzo) { tstr[ix][it] = sqrtf(fabsf(t*tq*tq)/ (fabsf(tm*tm*tm)+SF_EPS)); xstr[ix][it] = x - h*tx/(tm+SF_EPS); } else { tstr[ix][it] = sqrtf(fabsf(t*ph[it]*tq*tq)/ (fabsf(tm*tm*tp)+SF_EPS)); xstr[ix][it] = x - t*h*px[it]/(tp+SF_EPS); } } } warp2(slice,tstr,xstr,img); sf_floatwrite (img[0],ntx,mig); } exit (0); }
int main(int argc, char* argv[]) { int n=pow(2,GC_FRAMES); int *codes=new int[n]; struct termios options; pthread_t get_result_thread; void * thread_ret; if(argc<3){ printf("usage:\n\t%s <dev_file> <baud rate>\n",argv[0]); return -1; } printf("Selected baud rate is %ld\n",atol(argv[2])); int fd=open_port(argv[1]); if(fd==-1){ return -1; } tcgetattr(fd, &options); //Set the baud rate switch(atol(argv[2])){ case 9600: cfsetispeed(&options, B9600); cfsetospeed(&options, B9600); break; case 19200: cfsetispeed(&options, B19200); cfsetospeed(&options, B19200); break; case 38400: cfsetispeed(&options, B38400); cfsetospeed(&options, B38400); break; case 57600: cfsetispeed(&options, B57600); cfsetospeed(&options, B57600); break; case 115200: cfsetispeed(&options, B115200); cfsetospeed(&options, B115200); break; case 230400: cfsetispeed(&options, B230400); cfsetospeed(&options, B230400); break; default: printf("Selected baud rate %ld is not support now!\n", atol(argv[2])); close(fd); return -1; } //Enable the receiver and set local mode... options.c_cflag |= (CLOCAL | CREAD); options.c_cflag &= ~CSIZE; /* Mask the character size bits */ options.c_cflag |= CS8; /* Select 8 data bits */ //No parity options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; //Set the new options for the port... tcsetattr(fd, TCSANOW, &options); GCTHREAD_FUNC gc_func=get_result; pthread_create( &get_result_thread, NULL, gc_func, (void*)&fd); //------------------------------------------------------------------------ generate_graycode(GC_FRAMES,codes); cv::Scalar color; cv::namedWindow(window_name); // 移动到第二个屏幕上(第一个屏幕的大小是2560x1440) cv::moveWindow(window_name,DESKTOP_WIDTH,0); // 全屏显示窗口。事实上未必会全屏,但至少可以去掉标题栏部分 cv::setWindowProperty(window_name, cv::WND_PROP_FULLSCREEN, cv::WINDOW_FULLSCREEN); // show an image cv::Mat mengnalisha=cv::imread("mengnalisha.png"); cv::imshow(window_name, mengnalisha); cv::waitKey(0); for(int i=0; i<GC_FRAMES; i++){ gcImgH[i].create(PROJ_HEIGHT,PROJ_WIDTH,CV_8UC3); for(int c=0; c<n; c++){ int delta_c=PROJ_WIDTH/n; int b=(codes[c]>>(GC_FRAMES-1-i)) & 0x01; if(!b) color=cv::Scalar(0,0,0); else color=cv::Scalar(255,255,255); cv::rectangle(gcImgH[i], cv::Point(c*delta_c,0), cv::Point((c+1)*delta_c,PROJ_HEIGHT-1), color, cv::FILLED); } gcImgV[i].create(PROJ_HEIGHT,PROJ_WIDTH,CV_8UC3); for(int r=0; r<n; r++){ int delta_r=PROJ_HEIGHT/n; int b=(codes[r]>>(GC_FRAMES-1-i)) & 0x01; if(!b) color=cv::Scalar(0,0,0); else color=cv::Scalar(255,255,255); cv::rectangle(gcImgV[i], cv::Point(0,r*delta_r), cv::Point(PROJ_WIDTH-1, (r+1)*delta_r), color, cv::FILLED); } // 保存两种格雷码结构图 /* char fname[32]; snprintf(fname,32,"gcImgV%02d.png", i); std::cout<<fname<<std::endl; cv::imwrite(fname, gcImgV[i]); snprintf(fname,32,"gcImgH%02d.png", i); std::cout<<fname<<std::endl; cv::imwrite(fname, gcImgH[i]); */ } cv::Mat black(cv::Size(PROJ_WIDTH,PROJ_HEIGHT), CV_8UC3, cv::Scalar(0,0,0)); cv::Mat white(cv::Size(PROJ_WIDTH,PROJ_HEIGHT), CV_8UC3, cv::Scalar(255,255,255)); // 标定亮暗水平 std::cout<<"Prepare step: begin to detect light level, wait for some seconds..."<<std::endl; char wbuf[1]; wbuf[0]=CALIB_L; n=write(fd,wbuf, 1); if(n!=1){ std::cout<<"Write ttyUSB error!"<<std::endl; } cv::imshow(window_name, white); cv::waitKey(500); std::cout<<"Prepare step: begin to detect dark level, wait for some seconds..."<<std::endl; wbuf[0]=CALIB_D; n=write(fd,wbuf, 1); if(n!=1){ std::cout<<"Write ttyUSB error!"<<std::endl; } cv::imshow(window_name, black); cv::waitKey(500); if((!board1_exist) && !(board2_exist)){ std::cout<<"No projecting board found!"<<std::endl; return -1; } if(board1_exist){ while(x_current_pass[0]<COORDS_MULTIPASS){ calib_X(fd); } while(y_current_pass[0]<COORDS_MULTIPASS){ calib_Y(fd); } } if(board2_exist){ while(x_current_pass[1]<COORDS_MULTIPASS){ calib_X(fd); } while(y_current_pass[1]<COORDS_MULTIPASS){ calib_Y(fd); } } cv::Mat warp1(cv::Size(PROJ_WIDTH,PROJ_HEIGHT), CV_8UC3, cv::Scalar(0,0,0)); cv::Mat warp2(cv::Size(PROJ_WIDTH,PROJ_HEIGHT), CV_8UC3, cv::Scalar(0,0,0)); if(board1_exist){ std::cout<<"X & Y coordinates are stable, now to calibrate the projector..."<<std::endl; // 输出坐标值 for(int i=0;i<SENSOR_NUMBER;i++){ std::cout<<"("<<x_coords[0][0][i]<<","<<y_coords[0][0][i]<<")"<<std::endl; } warp1=generate_max_display(1); } if(board2_exist){ std::cout<<"X & Y coordinates are stable, now to calibrate the projector..."<<std::endl; // 输出坐标值 for(int i=0;i<SENSOR_NUMBER;i++){ std::cout<<"("<<x_coords[1][0][i]<<","<<y_coords[1][0][i]<<")"<<std::endl; } warp2=generate_max_display(2); } output_perspective_images(warp1,warp2); cv::waitKey(10000); // 等待接收线程结束 pthread_join(get_result_thread,&thread_ret); }