整像素运动估计的C语言代码可用于FPGA验证Word文档下载推荐.docx

上传人:b****2 文档编号:820424 上传时间:2023-04-29 格式:DOCX 页数:19 大小:19.64KB
下载 相关 举报
整像素运动估计的C语言代码可用于FPGA验证Word文档下载推荐.docx_第1页
第1页 / 共19页
整像素运动估计的C语言代码可用于FPGA验证Word文档下载推荐.docx_第2页
第2页 / 共19页
整像素运动估计的C语言代码可用于FPGA验证Word文档下载推荐.docx_第3页
第3页 / 共19页
整像素运动估计的C语言代码可用于FPGA验证Word文档下载推荐.docx_第4页
第4页 / 共19页
整像素运动估计的C语言代码可用于FPGA验证Word文档下载推荐.docx_第5页
第5页 / 共19页
整像素运动估计的C语言代码可用于FPGA验证Word文档下载推荐.docx_第6页
第6页 / 共19页
整像素运动估计的C语言代码可用于FPGA验证Word文档下载推荐.docx_第7页
第7页 / 共19页
整像素运动估计的C语言代码可用于FPGA验证Word文档下载推荐.docx_第8页
第8页 / 共19页
整像素运动估计的C语言代码可用于FPGA验证Word文档下载推荐.docx_第9页
第9页 / 共19页
整像素运动估计的C语言代码可用于FPGA验证Word文档下载推荐.docx_第10页
第10页 / 共19页
整像素运动估计的C语言代码可用于FPGA验证Word文档下载推荐.docx_第11页
第11页 / 共19页
整像素运动估计的C语言代码可用于FPGA验证Word文档下载推荐.docx_第12页
第12页 / 共19页
整像素运动估计的C语言代码可用于FPGA验证Word文档下载推荐.docx_第13页
第13页 / 共19页
整像素运动估计的C语言代码可用于FPGA验证Word文档下载推荐.docx_第14页
第14页 / 共19页
整像素运动估计的C语言代码可用于FPGA验证Word文档下载推荐.docx_第15页
第15页 / 共19页
整像素运动估计的C语言代码可用于FPGA验证Word文档下载推荐.docx_第16页
第16页 / 共19页
整像素运动估计的C语言代码可用于FPGA验证Word文档下载推荐.docx_第17页
第17页 / 共19页
整像素运动估计的C语言代码可用于FPGA验证Word文档下载推荐.docx_第18页
第18页 / 共19页
整像素运动估计的C语言代码可用于FPGA验证Word文档下载推荐.docx_第19页
第19页 / 共19页
亲,该文档总共19页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

整像素运动估计的C语言代码可用于FPGA验证Word文档下载推荐.docx

《整像素运动估计的C语言代码可用于FPGA验证Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《整像素运动估计的C语言代码可用于FPGA验证Word文档下载推荐.docx(19页珍藏版)》请在冰点文库上搜索。

整像素运动估计的C语言代码可用于FPGA验证Word文档下载推荐.docx

P_16x16

//最终分割方式

typedefstruct

intframe;

//帧号

uint8_t*plane[3];

//存放一副图像的原始数据

}picture_t;

typedefstruct

FILE*fp;

//图像文件

intpix_width;

//图像宽按像素计

intpix_height;

//图像高按像素计

intmb_width;

//图像宽按宏块计

intmb_height;

//图像高按宏块计

picture_tpic[I_FRAME];

}yuv_t;

intmv[2];

//对应的最佳mv

uint_tsad;

//对应的sad值

}mvs_t;

uint8_tsad[16][16];

mvs_tmvs[9];

//存放种最佳mv

intpartition;

intmv[4];

yuv_t*init_yuv(yuv_t*);

voidinit_sad();

intcreat_yuv(yuv_t*,int);

voidstart_ime(yuv_t*);

voidfull_search(yuv_t*,int,int);

voidcal_sad(uint8_t*,uint8_t*,int);

voidcompare(int,int,int,int);

uint_tsub_block_sad(int[],int[]);

voidfree_yuv(yuv_t*);

voidfinal_opt();

voidadjust_range(int*,int*,int,int);

voidadjust_mv(int,int,int);

intmain(intargc,char*argv[])

yuv_t*h=NULL;

h=init_yuv(h);

//初始化yuv

if(!

h)

return-1;

if(creat_yuv(h,I_FRAME)<

0)//读图像

{

free_yuv(h);

}

start_ime(h);

//开始整像素搜索

free_yuv(h);

//释放内存

return0;

}

//初始化yuv

yuv_t*init_yuv(yuv_t*h)

inti;

h=(yuv_t*)malloc(sizeof(yuv_t));

//分配内存

//初始化像素指针

for(i=0;

i<

I_FRAME;

++i)

h->

pic[i].plane[0]=NULL;

h->

fp=fopen(PIC_P,"

rb"

);

h->

fp)

returnNULL;

pix_width=PIC_W;

//像素宽

pix_height=PIC_H;

//像素高

mb_width=h->

pix_width/16;

//宏块宽

mb_height=h->

pix_height/16;

//宏块高

returnh;

//预测宏块之前,初始化mvs中的sad值

voidinit_sad()

//初始化sad值

9;

++i)

mvs[i].sad=SAD_MAX;

mvs[i].mv[0]=0;

mvs[i].mv[1]=0;

//读取yuv序列

intcreat_yuv(yuv_t*h,inti_frame)

inticnt;

inti,j,sum=0;

//FILE*outf;

for(icnt=0;

icnt<

i_frame;

++icnt)//读取像素

pic[icnt].frame=icnt;

//为存储像素分配存储空间

pic[icnt].plane[0]=(uint8_t*)malloc(h->

pix_width*h->

pix_height*3/2*sizeof(uint8_t));

if(!

pic[icnt].plane[0])//若分配失败,返回-1//Y分量

return-1;

pic[icnt].plane[1]=h->

pic[icnt].plane[0]+h->

pix_height;

//U分量

pic[icnt].plane[2]=h->

pic[icnt].plane[1]+h->

pix_height/4;

//V分量

//找到一帧的开头

if(fseek(h->

fp,(uint64_t)(icnt+BEG)*h->

pix_height*3/2,SEEK_SET))

//分别读取Y、U、V三个分量至内存

if(fread(h->

pic[icnt].plane[0],1,h->

pix_height,h->

fp)<

=0

||fread(h->

pic[icnt].plane[1],1,h->

pix_height/4,h->

pic[icnt].plane[2],1,h->

=0)

//开始整像素运动估计

voidstart_ime(yuv_t*h)

intmb_x,mb_y;

intmbx_max=h->

mb_width-1;

intmby_max=h->

mb_height-1;

for(mb_y=0;

mb_y<

=mby_max;

++mb_y)

for(mb_x=0;

mb_x<

=mbx_max;

++mb_x)

{init_sad();

full_search(h,mb_x,mb_y);

final_opt(mb_x,mb_y);

printf("

\nMB:

x=%d,y=%d"

mb_x,mb_y);

//输出宏块坐标

switch(partition)

{

caseP_8x8:

{

//输出分割方式

printf("

\tPartition:

P_8x8"

//输出最佳sad

\tsad=%d%d%d%d\n"

mvs[0].sad,mvs[1].sad,mvs[2].sad,mvs[3].sad);

//输出参考块坐标

mv[0]=(%d,%d)"

mvs[0].mv[0],mvs[0].mv[1]);

mv[1]=(%d,%d)"

mvs[1].mv[0],mvs[1].mv[1]);

mv[2]=(%d,%d)"

mvs[2].mv[0],mvs[2].mv[1]);

mv[3]=(%d,%d)\n"

mvs[3].mv[0],mvs[3].mv[1]);

break;

}

caseP_8x16:

P_8x16"

\tsad=%d%d\n"

mvs[4].sad,mvs[5].sad);

mvs[4].mv[0],mvs[4].mv[1]);

mv[1]=(%d,%d)\n"

mvs[5].mv[0],mvs[5].mv[1]);

caseP_16x8:

P_16x8"

mvs[6].sad,mvs[7].sad);

mvs[6].mv[0],mvs[6].mv[1]);

mvs[7].mv[0],mvs[7].mv[1]);

caseP_16x16:

P_16x16"

\tsad=%d\n"

mvs[8].sad);

mv=(%d,%d)\n"

mvs[8].mv[0],mvs[8].mv[1]);

}

}

//开始搜索

voidfull_search(yuv_t*h,intmx,intmy)

intsr_x[2];

intsr_y[2];

inti,j=-1,k;

intpix_x,pix_y;

intshift_x,shift_y;

intstride=h->

pix_width;

uint8_t*ref_pix;

uint8_t*ref_mb,*cur_mb;

//找到搜索区域

sr_x[0]=MAX(0,mx-1);

//搜索范围x坐标的最小值按宏块计

sr_x[1]=MIN(h->

mb_width-1,mx+1);

//搜索范围x坐标的最大值按宏块计

sr_y[0]=MAX(0,my-1);

//搜索范围y坐标的最小值按宏块计

sr_y[1]=MIN(h->

mb_height-1,my+1);

//搜索范围y坐标的最大值按宏块计

//搜索范围按像素计

pix_x=(sr_x[1]-sr_x[0])*16;

pix_y=(sr_y[1]-sr_y[0])*16;

adjust_range(&

pix_x,&

pix_y,mx,my);

//搜索区域左上顶点相对于中心点的位移

shift_x=(mx-sr_x[0])*16;

shift_y=(my-sr_y[0])*16;

//找到搜索区域起始像素点

ref_pix=h->

pic[0].plane[0]+mx*16+my*16*stride

-shift_x-shift_y*stride;

//当前待编码宏块的起始像素位置

cur_mb=h->

pic[1].plane[0]+mx*16+my*16*stride;

//按全搜索算法搜索

pix_x;

i+=4)//一次做个点

if(j==-1)//按行正向搜索

{

for(j=0;

j<

pix_y;

++j)

for(k=i;

k<

i+4&

&

++k)

ref_mb=ref_pix+k+j*stride;

cal_sad(cur_mb,ref_mb,stride);

//算出当前个sad值

compare(k,j,mx,my);

//通过比较得出个最佳mv

}

elseif(j==pix_y)//按行逆向搜索

for(j=pix_y-1;

j>

=0;

--j)

//根据宏块位置调整搜索范围

voidadjust_range(int*rx,int*ry,intmx,intmy)

if(mx==MB_W-1&

my>

=0&

my<

MB_H-1)

*rx=*rx+1;

elseif(mx>

mx<

MB_W-1&

my==MB_H-1)

*ry=*ry+1;

elseif(mx==MB_W-1&

*rx=*rx+1;

//计算sad值

voidcal_sad(uint8_t*cur,uint8_t*ref,intstride)

inti,j;

16;

for(j=0;

sad[i][j]=abs(cur[j+i*stride]-ref[j+i*stride]);

//比较sad值,获得个最佳mv

voidcompare(intpx,intpy,intmx,intmy)

introw[2],col[2];

uint_ts[9]={SAD_MAX};

intt;

intmvx,mvy;

for(t=0;

t<

++t)

switch(t)

caseP_8x8_UL:

//左上角x8子块

row[0]=0;

row[1]=8;

col[0]=0;

col[1]=8;

s[P_8x8_UL]=sub_block_sad(row,col);

mvx=px;

mvy=py;

break;

caseP_8x8_UR:

//右上角x8子块

col[0]=8;

col[1]=16;

s[P_8x8_UR]=sub_block_sad(row,col);

mvx=px+8;

if(mx==7&

my==1)

printf("

(%d,%d)sad=%d\n"

mvx,mvy,s[t]);

system("

pause"

caseP_8x8_DL:

//左下角x8子块

row[0]=8;

row[1]=16;

s[P_8x8_DL]=sub_block_sad(row,col);

mvy=py+8;

caseP_8x8_DR:

//右下角x8子块

s[P_8x8_DR]=sub_block_sad(row,col);

caseP_8x16_L:

//左边x16子块

s[P_8x16_L]=s[P_8x8_UL]+s[P_8x8_DL];

caseP_8x16_R:

//右边x16子块

s[P_8x16_R]=s[P_8x8_UR]+s[P_8x8_DR];

caseP_16x8_U:

//上边x8子块

s[P_16x8_U]=s[P_8x8_UR]+s[P_8x8_UL];

caseP_16x8_D:

//下边x8子块

s[P_16x8_D]=s[P_8x8_DL]+s[P_8x8_DR];

caseP_16x16_:

//16x16子块

s[P_16x16_]=s[P_16x8_D]+s[P_16x8_U];

//若当前sad小于以前的sad,则更新sad和mv

if(s[t]<

mvs[t].sad)

mvs[t].sad=s[t];

mvs[t].mv[0]=mvx;

mvs[t].mv[1]=mvy;

adjust_mv(t,mx,my);

//根据宏块位置调整mv的值

voidadjust_mv(intt,intmx,intmy)

if(mx==0&

my==0)

mvs[t].mv[0]=mvs[t].mv[0]+16;

mvs[t].mv[1]=mvs[t].mv[1]+16;

elseif(my==0&

mx>

0&

=MB_W-1)

elseif(mx==0&

=MB_H-1)

mvs[t].mv[0]=mvs[t].mv[0]+16;

else;

//计算某个子块的sad

uint_tsub_block_sad(introw[2],intcol[2])

uint_ts=0;

for(i=row[0];

row[1];

for(j=col[0];

col[1];

s+=sad[i][j];

returns;

//最终分割方式及其最佳mv的判决

voidfinal_opt()

uint_ts=SAD_MAX,s0;

s0=mvs[0].sad+mvs[1].sad+mvs[2].sad+mvs[3].sad;

if(s>

=s0)

s=s0;

partition=P_8x8;

s0=mvs[4].sad+mvs[5].sad;

partition=P_8x16;

s0=mvs[6].sad+mvs[7].sad;

partition=P_16x8;

s0=mvs[8].sad;

partition=P_16x16;

//释放内存

voidfree_yuv(yuv_t*h)

I_FRAM

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2