整像素运动估计的C语言代码,可用于FPGA验证.docx_第1页
整像素运动估计的C语言代码,可用于FPGA验证.docx_第2页
整像素运动估计的C语言代码,可用于FPGA验证.docx_第3页
整像素运动估计的C语言代码,可用于FPGA验证.docx_第4页
整像素运动估计的C语言代码,可用于FPGA验证.docx_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

#include #include #include #include #include #pragma warning( disable : 4996 ) #define SEEK_SET 0 #define BEG 0 /从第几帧开始#define I_FRAME 2 /读取帧#define PIC_W 176 /图像宽度#define PIC_H 144 /图像高度#define PIC_P F:sequenceyuvforeman_qcif.yuv/图像路径#define MB_W PIC_W / 16#define MB_H PIC_H / 16#define SAD_MAX 65536/最大sad值#define MAX(a, b) ( (a)(b) ? (a) : (b) ) /取a、b中值较大的#define MIN(a, b) ( (a)(b) ? (a) : (b) ) /取a、b中值较小的typedef unsigned int uint_t;typedef unsigned char uint8_t;typedef unsigned _int64 uint64_t;enum P_8x8_UL, P_8x8_UR, P_8x8_DL, P_8x8_DR, P_8x16_L, P_8x16_R,P_16x8_U, P_16x8_D, P_16x16_; /宏块分割类型,9种enumP_8x8 = 1,P_16x8,P_8x16,P_16x16; /最终分割方式typedef struct int frame; /帧号uint8_t *plane3; /存放一副图像的原始数据picture_t;typedef structFILE *fp; /图像文件int pix_width; /图像宽按像素计int pix_height; /图像高按像素计 int mb_width; /图像宽按宏块计int mb_height; /图像高按宏块计picture_t picI_FRAME; yuv_t;typedef struct int mv2; /对应的最佳mvuint_t sad; /对应的sad值mvs_t;uint8_t sad1616;mvs_t mvs9; /存放种最佳mvint partition;int mv4;yuv_t* init_yuv(yuv_t*);void init_sad();int creat_yuv(yuv_t*, int);void start_ime(yuv_t*);void full_search(yuv_t*, int, int);void cal_sad(uint8_t*, uint8_t*, int);void compare(int, int, int, int);uint_t sub_block_sad(int, int);void free_yuv(yuv_t*);void final_opt();void adjust_range(int*, int*, int, int);void adjust_mv(int, int, int);int main(int argc, char *argv)yuv_t *h = NULL;h = init_yuv(h); /初始化yuvif (!h) return -1;if (creat_yuv(h, I_FRAME) 0) /读图像free_yuv(h);return -1;start_ime(h); /开始整像素搜索free_yuv(h); /释放内存return 0;/初始化yuvyuv_t* init_yuv(yuv_t *h)int i;h = (yuv_t*)malloc(sizeof(yuv_t); /分配内存/初始化像素指针for (i = 0; i pici.plane0 = NULL;h-fp = fopen(PIC_P, rb);if (!h-fp)return NULL;h-pix_width = PIC_W; /像素宽h-pix_height = PIC_H; /像素高h-mb_width = h-pix_width/16; /宏块宽h-mb_height = h-pix_height/16; /宏块高return h;/预测宏块之前,初始化mvs中的sad值void init_sad()int i;/初始化sad值for (i = 0; i 9; +i)mvsi.sad = SAD_MAX;mvsi.mv0 = 0;mvsi.mv1 = 0;/读取yuv序列int creat_yuv(yuv_t *h, int i_frame )int icnt;int i, j, sum = 0;/FILE *outf;for (icnt = 0; icnt picicnt.frame = icnt;/为存储像素分配存储空间h-picicnt.plane0 = (uint8_t*)malloc(h-pix_width * h-pix_height * 3 / 2 * sizeof(uint8_t);if (!h-picicnt.plane0) /若分配失败,返回-1 /Y分量return -1;h-picicnt.plane1 = h-picicnt.plane0 + h-pix_width * h-pix_height; /U分量h-picicnt.plane2 = h-picicnt.plane1 + h-pix_width * h-pix_height / 4; /V分量/找到一帧的开头if( fseek( h-fp, (uint64_t)(icnt+BEG) * h-pix_width * h-pix_height * 3 / 2, SEEK_SET ) )return -1; /分别读取Y、U、V三个分量至内存if( fread( h-picicnt.plane0, 1, h-pix_width * h-pix_height, h-fp ) picicnt.plane1, 1, h-pix_width * h-pix_height / 4, h-fp ) picicnt.plane2, 1, h-pix_width * h-pix_height / 4, h-fp ) mb_width - 1; int mby_max = h-mb_height - 1;for (mb_y = 0; mb_y = mby_max; +mb_y)for (mb_x = 0; mb_x pix_width; uint8_t *ref_pix;uint8_t *ref_mb, *cur_mb;/找到搜索区域sr_x0 = MAX(0, mx - 1); /搜索范围x坐标的最小值按宏块计sr_x1 = MIN(h-mb_width - 1, mx + 1); /搜索范围x坐标的最大值按宏块计sr_y0 = MAX(0, my - 1); /搜索范围y坐标的最小值按宏块计sr_y1 = MIN(h-mb_height - 1, my + 1);/搜索范围y坐标的最大值按宏块计/搜索范围按像素计pix_x = (sr_x1 - sr_x0) * 16;pix_y = (sr_y1 - sr_y0) * 16; adjust_range(&pix_x, &pix_y, mx, my);/搜索区域左上顶点相对于中心点的位移shift_x = (mx - sr_x0) * 16;shift_y = (my - sr_y0) * 16;/找到搜索区域起始像素点ref_pix = h-pic0.plane0 + mx * 16 + my * 16 * stride - shift_x - shift_y * stride;/当前待编码宏块的起始像素位置cur_mb = h-pic1.plane0 + mx * 16 + my * 16 * stride;/按全搜索算法搜索for (i = 0; i pix_x; i += 4) /一次做个点if (j = -1) /按行正向搜索for (j = 0; j pix_y; +j)for (k = i; k i + 4 & k = 0; -j)for (k = i; k i + 4 & k = 0 & my = 0 & mx MB_W - 1 & my = MB_H - 1)*ry = *ry + 1;else if(mx = MB_W - 1 & my = MB_H - 1) *rx = *rx + 1;*ry = *ry + 1;/计算sad值void cal_sad(uint8_t *cur, uint8_t *ref, int stride) int i, j;for (i = 0; i 16; +i)for (j = 0; j 16; +j)sadij = abs(curj + i*stride - refj + i*stride);/比较sad值,获得个最佳mvvoid compare(int px, int py, int mx, int my)int row2, col2;uint_t s9 = SAD_MAX;int t;int mvx, mvy;for (t = 0; t 9; +t)switch (t) case P_8x8_UL: /左上角x8子块row0 = 0; row1 = 8;col0 = 0; col1 = 8;sP_8x8_UL = sub_block_sad(row, col);mvx = px;mvy = py;break;case P_8x8_UR: /右上角x8子块row0 = 0; row1 = 8;col0 = 8; col1 = 16;sP_8x8_UR = sub_block_sad(row, col);mvx = px + 8;mvy = py;if (mx = 7 & my = 1)printf(%d, %d) sad = %dn, mvx, mvy, st);system(pause);break;case P_8x8_DL: /左下角x8子块row0 = 8; row1 = 16;col0 = 0; col1 = 8;sP_8x8_DL = sub_block_sad(row, col);mvx = px;mvy = py + 8;break;case P_8x8_DR: /右下角x8子块row0 = 8; row1 = 16;col0 = 8; col1 = 16;sP_8x8_DR = sub_block_sad(row, col);mvx = px + 8;mvy = py + 8;break;case P_8x16_L: /左边x16子块sP_8x16_L = sP_8x8_UL + sP_8x8_DL;mvx = px;mvy = py;break;case P_8x16_R: /右边x16子块sP_8x16_R = sP_8x8_UR + sP_8x8_DR;mvx = px + 8;mvy = py;break;case P_16x8_U: /上边x8子块 sP_16x8_U = sP_8x8_UR + sP_8x8_UL;mvx = px;mvy = py;break;case P_16x8_D: /下边x8子块sP_16x8_D = sP_8x8_DL + sP_8x8_DR;mvx = px;mvy = py + 8;break;case P_16x16_: /16x16子块sP_16x16_ = sP_16x8_D + sP_16x8_U;mvx = px;mvy = py;break;/若当前sad小于以前的sad,则更新sad和mvif (st 0 & mx 0 & my = MB_H - 1) mvst.mv0 = mvst.mv0 + 16;else;/计算某个子块的saduint_t sub_block_sad(int row2, int col2)int i, j;uint_t s = 0;for (i = row0; i row1; +i)for (j = col0; j = s0)s = s0;partition = P

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论