⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fullsearch.cpp

📁 x264全搜索源代码
💻 CPP
字号:
#include <iostream.h>
//#include <iomanip.h>
#include <math.h>
#include <stdio.h>
#include <time.h>
#define T 0

const unsigned short int height=288;
const unsigned short int  width=352;
unsigned short int  yMax=height-16;
unsigned short int  xMax=width-16;
unsigned char CurrentFrame[height][width];
unsigned char RefFrame[height][width];
unsigned char RefOrgFrame[height][width];

unsigned char *PCurrentFrame=&CurrentFrame[0][0];
unsigned char *PRefFrame=&RefFrame[0][0];
unsigned char *PRefOrgFrame=&RefOrgFrame[0][0];
unsigned char *PSwitchFrame;

FILE *Yuv_file,*ReconImage;
unsigned int frameNO;
unsigned int frameNOMax=50;

struct MotInfo{
	 int xoff;
	 int yoff;
};
MotInfo   MVList1[height/16][width/16];
MotInfo    *CurMV=&MVList1[0][0];  //指向当前帧运动矢量矩阵的指针

void frame_ME(int,int);
void  FullSearch(int,int,int&,int&,unsigned int&,int&); 
unsigned int SadFun(int,int,int,int);

int kSum=0;      //每帧图像总的搜索点
int KSUM=0;      //所有压缩图像的搜索点数          
float kAverage=0;   //每帧中每块的平均搜索点数
float KAVERAGE=0;  //每帧的平均搜索点数

float msesum=0;
float mse=0;
float MSESUM=0;
float psnr=0;
float PSNR=0;

	void main()
{ 
 
  if((Yuv_file=fopen("d:\\sequense\\mobile.yuv","rb"))==NULL){//foreman.yuvmother_daughter.yuv"akiyo_cif.yuv""vectra.yuv""mobile.yuv"
	        printf("cannot open this file0\n");
   }

  if((ReconImage=fopen("recon.yuv","wb"))==NULL){
            printf("cannot open this file1\n");
   }
  
fread(PRefOrgFrame,sizeof(unsigned char),288*352,Yuv_file);
fseek(Yuv_file,sizeof(unsigned char)*352*288/2,1);
fread(PCurrentFrame,sizeof(unsigned char),288*352,Yuv_file);

int i,j;

for(i=0;i<height;i+=16)          //行,y方向
		for(j=0;j<width;j+=16)   //列,x方向
		{
		   frame_ME(i,j);
		   
	       CurMV++;
         }
 
CurMV=&MVList1[0][0];

	 KSUM+=kSum;
   kAverage=(float)kSum/396;

for(i=0;i<height;i+=16)          //行
		for(j=0;j<width;j+=16)   //列
		{
          	for(int m=0;m<16;m++)
	          	for(int n=0;n<16;n++)
				{
		       RefFrame[i+m][j+n]=RefOrgFrame[i+CurMV->yoff+m][j+CurMV->xoff+n];
				} //预测图像
	       
				CurMV++;
                
		 }
CurMV=&MVList1[0][0];

	for(i=0;i<height;i++)          //行
		for(j=0;j<width;j++)   //列

		{ 
	    	msesum+=(CurrentFrame[i][j]-RefFrame[i][j])*(CurrentFrame[i][j]-RefFrame[i][j]);}
		    mse=msesum/(288*352);
		    psnr=10*log10(255*255/mse);
            MSESUM+=msesum;

 fwrite(RefFrame,sizeof(unsigned char),288*352,ReconImage);

 cout<<"第2帧:"<<psnr<<";"<<"平均搜索点数是:"<<kAverage<<endl;

 for(frameNO=3;frameNO<=frameNOMax;frameNO++)
 {
  msesum=0;
  mse=0;
  psnr=0;
  kAverage=0;
  kSum=0;      
 
  PSwitchFrame=PCurrentFrame;
 PCurrentFrame=PRefOrgFrame;
 PRefOrgFrame=PSwitchFrame;
	
  fseek(Yuv_file,sizeof(unsigned char)*352*288/2,1);
  fread(PCurrentFrame,sizeof(unsigned char),288*352,Yuv_file);

  for(i=0;i<height;i+=16)          //行,y方向
		for(j=0;j<width;j+=16)   //列,x方向
		{
		   frame_ME(i,j);
		   
	       CurMV++;
         
		}
  
 
  CurMV=&MVList1[0][0];

   KSUM+=kSum;
   kAverage=(float)kSum/396;

 for(i=0;i<height;i+=16)          //行
		for(j=0;j<width;j+=16)   //列
		{
          	for(int m=0;m<16;m++)
	          	for(int n=0;n<16;n++)
				{
		         RefFrame[i+m][j+n]=RefOrgFrame[i+CurMV->yoff+m][j+CurMV->xoff+n];
				} //预测图像
	       
				CurMV++;
		       
		}

  CurMV=&MVList1[0][0];
 
	for(i=0;i<height;i++)          //行
		for(j=0;j<width;j++)   //列
		{ 
	    	msesum+=(CurrentFrame[i][j]-RefFrame[i][j])*(CurrentFrame[i][j]-RefFrame[i][j]);
		}
	
		mse=msesum/(288*352);
		psnr=10*log10(255*255/mse);
        MSESUM+=msesum;
fseek(ReconImage,sizeof(unsigned char)*352*288/2,1);
fwrite(PRefFrame,sizeof(unsigned char),288*352,ReconImage);

cout<<"第"<<frameNO<<"帧"<<psnr<<";"<<"平均搜索点数:"<<kAverage<<endl;
 }

fclose(Yuv_file);
fclose(ReconImage);	
PSNR=10*log10(255*255/(MSESUM/(288*352*(frameNOMax-1))));
KAVERAGE=(float)KSUM/(396*(frameNOMax-1));
cout<<"平均PSNR:"<<PSNR<<";"<<"平均搜索点数:"<<KAVERAGE<<endl;
cout<<clock()<<endl;
}   


void frame_ME(int y0,int x0)          //估计函数
{
    int N=0;                     //记录每块的搜索点数
    
	int imin=65535,jmin=65535;
    unsigned int BSadMin=65535;
	unsigned	int BSad=65535;
    
	
	BSadMin=65535;	

    FullSearch(y0,x0,imin,jmin,BSadMin,N); 

	BSad=BSadMin;
	CurMV->xoff=jmin,CurMV->yoff=imin;
	 kSum+=N;	
    
}

		
void FullSearch(int i,int j,int& imin,int& jmin,unsigned int& BSadMin,int& N)
{
	int m,n,dx;
	unsigned int BSad=65535;
	unsigned int BSad0=65535;
	BSad0=SadFun(i,j,i,j); //原点位置
	N+=1;		
	if(BSad0<=T)
			{imin=0,jmin=0;
			return;
			}
	
	for(dx=1;dx<16;dx++)
			{
				for(int k=1;k<=4;k++)       //分四条边搜索
				{
					switch(k)
					{case 1:m=dx,n=dx;
					       for(n=dx;n>-dx;n--)
						   {
					         if(i+m<0||i+m>yMax||j+n<0||j+n>xMax) //图像边界
    	 
							 {;}//边界条件

	                          else 
							  {
				               BSad=SadFun(m+i,n+j,i,j);
	                             N+=1;
				                if(BSad<BSadMin)//当前点sad值小于最小值则保存此当前点状态,值与坐标
								{
			                     BSadMin=BSad,imin=m,jmin=n; 
								}
	    	                     if(BSadMin<=T)
						         return;
							  }
						   } 
				  	        break;
                     case 2: m=dx,n=-dx;
						 for(m=dx;m>-dx;m--)
				             {
					              if(i+m<0||i+m>yMax||j+n<0||j+n>xMax) //图像边界
    	 
								  {;}//边界条件

	                               else 
								   {
				                      BSad=SadFun(m+i,n+j,i,j);
				                       N+=1;
				                      if(BSad<BSadMin)//当前点sad值小于最小值则保存此当前点状态,值与坐标
									  {
			                                BSadMin=BSad,imin=m,jmin=n; 
									  }
	    	                           if(BSadMin<=T)
						               return;
								   }
							 } 
				           	break;
					 case 3: m=-dx,n=-dx;
						     for(n=-dx;n<dx;n++)
				             {
					              if(i+m<0||i+m>yMax||j+n<0||j+n>xMax) //图像边界
    	 
								  {;}//边界条件

	                               else 
								   {
				                      BSad=SadFun(m+i,n+j,i,j);	
									  N+=1;
				                      if(BSad<BSadMin)//当前点sad值小于最小值则保存此当前点状态,值与坐标
									  {
			                                BSadMin=BSad,imin=m,jmin=n; 
									  }
	    	                           if(BSadMin<=T)
						               return;
								   }
							 } 
				           	break;
                     case 4:m=-dx,n=dx;
						     for(m=-dx;m<dx;m++)
				             {
					              if(i+m<0||i+m>yMax||j+n<0||j+n>xMax) //图像边界
    	 
								  {;}//边界条件

	                               else 
								   {
				                      BSad=SadFun(m+i,n+j,i,j);	
									  N+=1;
				                      if(BSad<BSadMin)//当前点sad值小于最小值则保存此当前点状态,值与坐标
									  {
			                                BSadMin=BSad,imin=m,jmin=n; 
									  }
	    	                           if(BSadMin<=T)
						               return;
								   }
							 } 
                             break;
				           	
					}
                     
				}
				

            

	}
	if(BSad0<BSadMin)
			{BSadMin=BSad0,imin=0,jmin=0;}


}



//求sad值
unsigned int SadFun(int ycur,int xcur,int y0,int x0)
{
	unsigned int sum=0;
 	for(int i=0;i<16;i++)
		for(int j=0;j<16;j++)
		
			sum+=abs(CurrentFrame[y0+i][x0+j]-RefOrgFrame[ycur+i][xcur+j]);

		 
	return sum;
}
	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -