// bug? delete2d<int> would crash?! void test_LemotionComp(){ int h = 3; int w = 6; int mb = 3; const double LE[8][18] = {{0 , 1 , 0 , 0 , 1 , 1 ,0, 0 , 1 ,1 ,1 ,1 ,0, 0 , 1 ,1 ,1 ,1},{0, 0 , 1 ,1 ,1 ,1, 0 , 1 , 1 ,0, 0 , 1, 0 , 1 , 1 ,0, 0 , 1}, {0 , 1 , 0 , 0 , 1 , 1 ,0, 0 , 1 ,1 ,1 ,1 ,0, 0 , 1 ,1 ,1 ,1},{0, 0 , 1 ,1 ,1 ,1, 0 , 1 , 1 ,0, 0 , 1, 0 , 1 , 1 ,0, 0 , 1}, {0 , 1 , 0 , 0 , 1 , 1 ,0, 0 , 1 ,1 ,1 ,1 ,0, 0 , 1 ,1 ,1 ,1},{0, 0 , 1 ,1 ,1 ,1, 0 , 1 , 1 ,0, 0 , 1, 0 , 1 , 1 ,0, 0 , 1}, {0 , 1 , 0 , 0 , 1 , 1 ,0, 0 , 1 ,1 ,1 ,1 ,0, 0 , 1 ,1 ,1 ,1},{0, 0 , 1 ,1 ,1 ,1, 0 , 1 , 1 ,0, 0 , 1, 0 , 1 , 1 ,0, 0 , 1}}; const int MV[2][3] = {{0,0,0},{0,0,0}}; double ** le = new2d<double>(PXL,w*h,0); double ** comp = new2d<double>(PXL,w*h,0); int ** mv = new2d<int>(2,h*w/mb/mb); for(int i = 0 ; i < PXL ; ++i) for(int j = 0 ; j < w*h ; ++j){ le[i][j] = LE[i][j]; } for(int i = 0 ; i<h*w/mb/mb ; ++i){ mv[0][i] = MV[0][i]; mv[1][i] = MV[1][i]; } printf("le:\n"); for(int i = 0 ; i < PXL ; ++i){ for(int j = 0 ; j < w*h ; ++j) printf("%lf ",le[i][j]); printf("\n"); } motionComp(le,mv,h,w,mb,comp); printf("\ncomp:\n"); for(int i = 0 ; i < PXL ; ++i){ for(int j = 0 ; j < w*h ; ++j) printf("%lf ",comp[i][j]); printf("\n"); } printf("delete comp\n"); delete2d<double>(comp); printf("delete le\n"); delete2d<double>(le); printf("delete mv\n"); delete2d<int>(mv); printf("done\n"); }
// bug? delete2d<int> would crash?! void test_motionComp(){ int h = 3; int w = 6; int mb = 3; const int imgI[3][6] = {{0 , 1 , 0 , 0 , 1 , 1},{0, 0 , 1 ,1 ,1 ,1},{0, 0 , 1 ,1 ,0 ,1}}; const int MV[2][3] = {{0,0,0},{0,0,0}}; int ** im = new2d<int>(h,w,0); int ** comp = new2d<int>(h,w,0); int ** mv = new2d<int>(2,h*w/mb/mb); for(int i = 0 ; i < h ; ++i) for(int j = 0 ; j < w ; ++j){ im[i][j] = imgI[i][j]; mv[0][i*w+j] = MV[0][i*w+j]; mv[1][i*w+j] = MV[1][i*w+j]; } printf("imgI:\n"); for(int i = 0 ; i < h ; ++i){ for(int j = 0 ; j < w ; ++j) printf("%d ",im[i][j]); printf("\n"); } motionComp(im,mv,h,w,mb,comp); printf("\ncomp:\n"); for(int i = 0 ; i < h ; ++i){ for(int j = 0 ; j < w ; ++j) printf("%d ",comp[i][j]); printf("\n"); } printf("delete comp\n"); delete2d<int>(comp); printf("delete im\n"); delete2d<int>(im); printf("delete mv\n"); delete2d<int>(mv); printf("done\n"); }
//**************************POCS superresolution restoration algorithm************************************// //function: 实现POCS超分辨率复原 //input: //imgIn: 输入图像的指针,理想的HR图 //imgWidth: 输入图像的宽度 //imgHeight: 输入图像的高度 //LRNum: 产生的低分辨率图像的数目 //iterNum: 复原迭代次数 //output: //imgOut: 输出图像的指针 void pocs(unsigned char* imgIn,int imgWidth,int imgHeight,int LRNum,int iterNum, unsigned char* imgOut, bool noiseAuto, double noiseVar) { //生成LRNum数目的LR图像 //LRNum 数目的LR图像指针 unsigned char *p[MAXLRNUM]; int newHeight = imgHeight/2; int newWidth = imgWidth/2; int masksize = 5; int k; /* blur =[.25 0 1 0 .25;... 0 1 2 1 0;... 1 2 4 2 1;... 0 1 2 1 0;... .25 0 1 0 .25]; double blur[25] = {0.25,0,1.0,0,0.25, 0,1.0,2.0,1.0, 1.0,2.0,4.0,2.0,1.0, 0,1.0,2.0,1.0,0, 0.25,0,1.0,0,0.25};//21 for(k=0;k<masksize*masksize;k++) { blur[k]=blur[k]/21; } */ double blur[25] = {0.00296901674395050, 0.0133062098910137, 0.0219382312797146, 0.0133062098910137, 0.00296901674395050, 0.0133062098910137, 0.0596342954361801, 0.0983203313488458, 0.0596342954361801, 0.0133062098910137, 0.0219382312797146, 0.0983203313488458, 0.162102821637127, 0.0983203313488458, 0.0219382312797146, 0.0133062098910137, 0.0596342954361801, 0.0983203313488458, 0.0596342954361801, 0.0133062098910137, 0.00296901674395050, 0.0133062098910137, 0.0219382312797146, 0.0133062098910137, 0.00296901674395050 }; int seqNum[9] = {1,5,7,9,2,3,6,4,8}; double sigmaHtr=0; for(k=0;k<masksize*masksize;k++) { sigmaHtr=sigmaHtr+pow(*(blur+k),2); } for(k=0;k<LRNum;k++) { int s1_rand, s2_rand, s3_rand, s4_rand; s1_rand = seqNum[k]; s2_rand = seqNum[k]; s3_rand = seqNum[k]; s4_rand = seqNum[k]; unsigned char *LRtmp[MAXLRNUM]; LRtmp[k] = new unsigned char [newHeight*newWidth]; p[k] = new unsigned char [imgWidth*imgHeight]; //产生低分辨率图像 GenLR(imgIn,LRtmp[k],imgWidth,imgHeight,noiseAuto,noiseVar,s1_rand,s2_rand,s3_rand,s4_rand); //在此处直接进行双线性插值 zoomGray2(LRtmp[k], newWidth, newHeight, 2, 2,p[k], imgWidth, imgHeight); delete []LRtmp[k]; } //生成参考HR,p[0]第一幅图为参考图像---------------------------------到此为止算法正常实现 //开始迭代 for(int iter=0;iter<iterNum;iter++) { int err_acc; for(int picNum=1;picNum<LRNum;picNum++) { int i,j; //读入下一幅图,并与参考帧进行运动估计,通过运动补偿获得估计的运动图像f^ int motionVect[2][MAX]; double DScomputations[1]; //分配内存 unsigned char* imgComp = new unsigned char[imgWidth*imgHeight]; unsigned char* residual= new unsigned char[imgWidth*imgHeight]; // unsigned char residual; motionEstDS( p[0],p[picNum], imgWidth, imgHeight, motionVect, DScomputations); motionComp(p[picNum],16,imgWidth,imgHeight,motionVect,imgComp);//补偿向p[0]估计 //************************imgComp是对参考图像的估计********************************// //乘上模糊PSF后算作估计值 Filter(imgComp,imgWidth,imgHeight,1,blur,masksize); // 循环遍历每一个像素 for(i=0;i<imgHeight;i++) { for(j=0;j<imgWidth;j++) { int m,n; unsigned char res; //得出估计的残差数据块 res = *(imgComp+i*imgWidth+j)-*(p[0]+i*imgWidth+j); //根据残差反向迭代每一个像素 err_acc += res; if(res>R) { for(m=0;m<5;m++) for(n=0;n<5;n++) { if((i+m-2<0)||(j+n-2)<0||(i+m-2>=imgHeight)||(j+n-2>=imgWidth)) continue; else *(residual+(i+m-2)*imgWidth+(j+n-2))+=(unsigned char)((res-R)**(blur+m*5+n)/sigmaHtr); } } else if(res<-R) { for(m=0;m<5;m++) for(n=0;n<5;n++) { if((i+m-2<0)||(j+n-2)<0||(i+m-2>=imgHeight)||(j+n-2>=imgWidth)) continue; else *(residual+(i+m-2)*imgWidth+(j+n-2))+=(unsigned char)((res+R)**(blur+m*5+n)/sigmaHtr); } } else *(residual+i*imgWidth+j)=0; } } if(err_acc=255*R) break; for(i=0;i<imgHeight;i++) { for(j=0;j<imgWidth;j++) { *(p[0]+i*imgWidth+j)=*(p[0]+i*imgWidth+j)+*(residual+i*imgWidth+j);//残差的权重对图像复原效果有较大的影响 } } delete []imgComp; delete []residual; /* for(i=0;i<imgHeight;i++) { for(j=0;j<imgWidth;j++) { //初始化误差和 err_acc = 0; unsigned char res; //得出估计的残差数据块 res = *(imgComp+i*imgWidth+j)-*(p[0]+i*imgWidth+j); err_acc += res; //根据残差反向迭代每一个像素 if(res>R) *(residual+i*imgWidth+j)=res-R; else if(res<-R) *(residual+i*imgWidth+j)=res+R; else *(residual+i*imgWidth+j)=0; } } Filter(residual,imgWidth,imgHeight,1,blur,masksize); //反向迭代,对参考图像做修正,下一次循环使用的是修正后的参考图像 if(err_acc=255*R) break; for(i=0;i<imgHeight;i++) { for(j=0;j<imgWidth;j++) { *(p[0]+i*imgWidth+j)=*(p[0]+i*imgWidth+j)+*(residual+i*imgWidth+j)*1.9649; } } delete []imgComp; delete []residual; */ } } //复制图像输出 for(int i=0;i<imgHeight;i++) { for(int j=0;j<imgWidth;j++) { *(imgOut+i*imgWidth+j)=*(p[0]+i*imgWidth+j); } } //清空内存 for(k=0;k<LRNum;k++) { delete []p[k]; } }
int main(int argc,char* argv[]){ startRandom(); // control SNR step const double s_snr = -1; const double step = 0.05; const int snr_size = 500; // control the certain Frame and the bp int frame = 2; if(argc >= 4) frame = strtod(argv[3],NULL); // for video encode const int puncture = 0; // puncture or not const double rate = 1/(double)(2-puncture); // code rate const double a = 1; // Fading amplitude. a=1 -> AWGN channel double EbN0,L_c,sigma; // for basical info char buffer[50]; const int h = __HEIGHT, w = __WIDTH, f = frame+2 ; const int lm = h*w; const int lu = lm+(G_L-1); int*** Y = new3d<int>(f,h,w); int** MV_prev = new2d<int>(2,lm/64,0); int** MV = new2d<int>(2,lm/64,0); double** Lu = new2d<double>(PXL,lu,0); double** Lu_prev = new2d<double>(PXL,lu,0); double** Lu_next = new2d<double>(PXL,lu,0); // frame buffer int*** imgr_bp = new3d<int>(PXL,h,w); int*** imgr_bp_prev = new3d<int>(PXL,h,w); int*** imgr_bp_next = new3d<int>(PXL,h,w); int*** img = new3d<int>(PXL,h,w); int*** img_prev = new3d<int>(PXL,h,w); int*** img_next = new3d<int>(PXL,h,w); int** imgr = new2d<int>(h,w); int** imgr_prev = new2d<int>(h,w); int** imgr_next = new2d<int>(h,w); double** Lu_c = new2d<double>(PXL,lu); //channel decoder output // buffer for Ia, Ie double** Le = new2d<double>(PXL,lm); // source extrinsic informatiom double** Le_s_inter = new2d<double>(PXL,lm,0); // source extrinsic information double** Le_s_inter_next = new2d<double>(PXL,lm,0); // source extrinsic information double** Le_s_intra = new2d<double>(PXL,lm,0); // source extrinsic information double** Ia = new2d<double>(PXL,snr_size); double** Ie = new2d<double>(PXL,snr_size); int idx = 0; double tmp_sum = 0, tmp ; double* beta_t = (double*) malloc(sizeof(double)*PXL); double* beta_s = (double*) malloc(sizeof(double)*PXL); double* beta_t_prev = (double*) malloc(sizeof(double)*PXL); // read YUV sprintf(buffer,"%s_cif.yuv",argv[1]); yuv_read(buffer,h,w,f,Y,NULL,NULL); img2bp_frame(Y[frame],h,w,imgr_bp); img2bp_frame(Y[frame-1],h,w,imgr_bp_prev); img2bp_frame(Y[frame+1],h,w,imgr_bp_next); printf("processing ... %2.2f%%",0); for(double snr = s_snr; idx < snr_size ; snr+=step, idx++ ){ printf("\rprocessing ... %2.2f%%",100*(snr-s_snr)/step/snr_size); // encode EbN0 = pow(10,snr/10); // convert Eb/N0[dB] to normal number L_c = 4*a*EbN0*rate; // reliability value of the channel sigma = 1/sqrt(2*rate*EbN0); // standard deviation of AWGN noise for(int t_lvl = 0 ; t_lvl <PXL ; ++t_lvl){ tmp_sum = 0; for(int i = 0 ; i < lm ; ++i){ tmp = (2*imgr_bp[t_lvl][i/w][i%w] - 1); Lu[t_lvl][i] = 0.5*L_c*( tmp + sigma*gaussian_noise()); tmp_sum+=log2(1 + exp(-Lu[t_lvl][i]*tmp)); tmp = (2*imgr_bp_prev[t_lvl][i/w][i%w] - 1); Lu_prev[t_lvl][i] = 0.5*L_c*( tmp + sigma*gaussian_noise()); } Ia[t_lvl][idx] = 1 - tmp_sum/lm; } // decode for(int i = 0, j=0, t_lvl=0; i <h ; ++i) for(j = 0 ; j < w ; ++j) for(t_lvl=0 ; t_lvl < PXL ; ++t_lvl){ img[t_lvl][i][j] = ((Lu[t_lvl][j+i*w]>=0)?1:0); img_prev[t_lvl][i][j] = ((Lu_prev[t_lvl][j+i*w]>=0)?1:0); } bin2dec_img(img,h,w,imgr); bin2dec_img(img_prev,h,w,imgr_prev); motionEstES(imgr,imgr_prev,h,w,8,5,MV_prev); intra_inter_beta_estimation(img,img_prev,MV_prev,beta_s,beta_t,h,w,8); motionComp(Lu_prev,MV_prev,h,w,8,Lu_c); mrf_siso_inter(Lu,Lu_c,beta_t,h,w,Le_s_inter,0); mrf_siso_intra(Lu,beta_s,h,w,Le_s_intra,0); for(int i = 0, t_lvl = 0 ; i < lm ; ++i) for(t_lvl = 0 ; t_lvl < PXL ; ++t_lvl) Le[t_lvl][i] = (Le_s_inter[t_lvl][i] + Le_s_intra[t_lvl][i]); // Le_s_prev in the next frame // prepare for next frame decode // encode for(int t_lvl = 0 ; t_lvl <PXL ; ++t_lvl){ for(int i = 0 ; i < lm ; ++i){ tmp = (2*imgr_bp_next[t_lvl][i/w][i%w] - 1); Lu_next[t_lvl][i] = 0.5*L_c*( tmp + sigma*gaussian_noise()); // reuse as Lu_next } } for(int i = 0, j=0, t_lvl=0; i <h ; ++i) for(j = 0 ; j < w ; ++j) for(t_lvl=0 ; t_lvl < PXL ; ++t_lvl){ img_next[t_lvl][i][j] = ((Lu_next[t_lvl][j+i*w]>=0)?1:0); } bin2dec_img(img_next,h,w,imgr_next); motionEstES(imgr,imgr_next,h,w,8,5,MV); if(frame==1){ intra_inter_beta_estimation(imgr_bp,imgr_bp_next,MV,beta_s,beta_t,h,w,8); for(int i = 0 ; i < PXL ; ++i) beta_t_prev[i] = 0; } else intra_inter2_beta_estimation(imgr_bp_next,imgr_bp,imgr_bp_prev,MV,beta_s,beta_t,beta_t_prev,h,w,8); motionComp(Lu_next,MV,h,w,8,Lu_c); mrf_siso_inter(Lu,Lu_c,beta_t,h,w,Le_s_inter_next,0); mrf_siso_intra(Lu,beta_s,h,w,Le_s_intra,0); for(int i = 0, t_lvl = 0 ; i < lm ; ++i) for(t_lvl = 0 ; t_lvl < PXL ; ++t_lvl) Le[t_lvl][i] = (Le_s_inter_next[t_lvl][i] + Le_s_intra[t_lvl][i] + Le_s_inter[t_lvl][i]*beta_t_prev[t_lvl]); // compute Ie for(int t_lvl = 0 , i = 0; t_lvl < PXL ; ++t_lvl){ tmp_sum = 0; for(i=0; i < lm ; ++i){ tmp_sum+=log2(1 + exp(-Le[t_lvl][i]*(2*imgr_bp[0][0][i+t_lvl*lm]-1))); } Ie[t_lvl][idx] = 1 - tmp_sum/lm; } } printf("\r100.00%% completed!\n"); FILE *file = fopen("output/exit_curve_ps.txt","a+"); for(int t_lvl = 0 ; t_lvl < PXL ; ++t_lvl){ fprintf(file,"==== v2 ========================\n%s: frame#%d,bp#%d\nIa=\n",argv[1],frame+1,t_lvl+1); for(int i = 0 ; i < snr_size ; ++i) fprintf(file,"%lf,",Ia[t_lvl][i]); fprintf(file,"\nIe=\n"); for(int i = 0 ; i < snr_size ; ++i) fprintf(file,"%lf,",Ie[t_lvl][i]); fprintf(file,"\n\n"); } fclose(file); write_ps_for_matlab(Ia,Ie,snr_size); // free memory deleteY(Y); delete3d<int>(imgr_bp); delete3d<int>(imgr_bp_prev); delete3d<int>(imgr_bp_next); delete3d<int>(img_next); delete3d<int>(img_prev); delete3d<int>(img); delete2d<int>(imgr_next); delete2d<int>(imgr_prev); delete2d<int>(imgr); delete2d<double>(Lu_c); delete2d<double>(Lu_next); delete2d<double>(Lu); delete2d<double>(Lu_prev); delete2d<double>(Ia); delete2d<double>(Ie); delete2d<int>(MV_prev); delete2d<int>(MV); delete2d<double>(Le); delete2d<double>(Le_s_inter); delete2d<double>(Le_s_inter_next); delete2d<double>(Le_s_intra); free(beta_s); free(beta_t); free(beta_t_prev); }