📄 motion_estimation.c
字号:
return(0); if (motion_vectors_horizontal == NULL) return(0); if (motion_vectors_vertical == NULL) return(0); if (current_frame->image == NULL) return(0); if (reference_frame->image == NULL) return(0); if (motion_vectors_horizontal->image == NULL) return(0); if (motion_vectors_vertical->image == NULL) return(0); if ((motion_vectors_horizontal->num_rows != current_frame->num_rows / block_size) || (motion_vectors_horizontal->num_cols != current_frame->num_cols / block_size)) { QccErrorAddMessage("(QccVIDMotionEstimationFullSearch): Motion-vector field is inconsistent with current-frame size"); goto Error; } if ((motion_vectors_vertical->num_rows != current_frame->num_rows / block_size) || (motion_vectors_vertical->num_cols != current_frame->num_cols / block_size)) { QccErrorAddMessage("(QccVIDMotionEstimationFullSearch): Motion-vector field is inconsistent with current-frame size"); goto Error; } switch (subpixel_accuracy) { case QCCVID_ME_FULLPIXEL: if ((reference_frame->num_rows != current_frame->num_rows) || (reference_frame->num_cols != current_frame->num_cols)) { QccErrorAddMessage("(QccVIDMotionEstimationFullSearch): Reference-frame size is inconsistent with current-frame size for full-pixel motion estimation"); goto Error; } final_search_step = 1.0; break; case QCCVID_ME_HALFPIXEL: if ((reference_frame->num_rows != 2 * current_frame->num_rows) || (reference_frame->num_cols != 2 * current_frame->num_cols)) { QccErrorAddMessage("(QccVIDMotionEstimationFullSearch): Reference-frame size is inconsistent with current-frame size for half-pixel motion estimation"); goto Error; } final_search_step = 0.5; break; case QCCVID_ME_QUARTERPIXEL: if ((reference_frame->num_rows != 4 * current_frame->num_rows) || (reference_frame->num_cols != 4 * current_frame->num_cols)) { QccErrorAddMessage("(QccVIDMotionEstimationFullSearch): Reference-frame size is inconsistent with current-frame size for quarter-pixel motion estimation"); goto Error; } final_search_step = 0.25; break; case QCCVID_ME_EIGHTHPIXEL: if ((reference_frame->num_rows != 8 * current_frame->num_rows) || (reference_frame->num_cols != 8 * current_frame->num_cols)) { QccErrorAddMessage("(QccVIDMotionEstimationFullSearch): Reference-frame size is inconsistent with current-frame size for eighth-pixel motion estimation"); goto Error; } final_search_step = 0.125; break; default: QccErrorAddMessage("(QccVIDMotionEstimationFullSearch): Unrecognized motion-estimation accuracy (%d)", subpixel_accuracy); goto Error; } if ((current_block = QccMatrixAlloc(block_size, block_size)) == NULL) { QccErrorAddMessage("(QccVIDMotionEstimationFullSearch): Error calling QccMatrixAlloc()"); goto Error; } if ((reference_block = QccMatrixAlloc(block_size, block_size)) == NULL) { QccErrorAddMessage("(QccVIDMotionEstimationFullSearch): Error calling QccMatrixAlloc()"); goto Error; } for (block_row = 0; block_row < current_frame->num_rows; block_row += block_size) for (block_col = 0; block_col < current_frame->num_cols; block_col += block_size) { if (QccVIDMotionEstimationExtractBlock(current_frame, (double)block_row, (double)block_col, current_block, block_size, QCCVID_ME_FULLPIXEL)) { QccErrorAddMessage("(QccVIDMotionEstimationFullSearch): Error calling QccVIDMotionEstimationExtractBlock()"); goto Error; } mv_row = block_row / block_size; mv_col = block_col / block_size; motion_vectors_horizontal->image[mv_row][mv_col] = 0.0; motion_vectors_vertical->image[mv_row][mv_col] = 0.0; for (current_search_step = 1.0; current_search_step >= final_search_step; current_search_step /= 2) { search_row = block_row + motion_vectors_vertical->image[mv_row][mv_col]; search_col = block_col + motion_vectors_horizontal->image[mv_row][mv_col]; current_window_size = (current_search_step == 1.0) ? (double)window_size : current_search_step; if (QccVIDMotionEstimationWindowSearch(current_block, reference_block, block_size, reference_frame, search_row, search_col, current_window_size, current_search_step, subpixel_accuracy, &u, &v)) { QccErrorAddMessage("(QccVIDMotionEstimationFullSearch): Error calling QccVIDMotionEstimationWindowSearch()"); goto Error; } motion_vectors_horizontal->image[mv_row][mv_col] += u; motion_vectors_vertical->image[mv_row][mv_col] += v; } } return_value = 0; goto Return; Error: return_value = 1; Return: QccMatrixFree(current_block, block_size); QccMatrixFree(reference_block, block_size); return(return_value);}int QccVIDMotionEstimationCalcReferenceFrameSize(int num_rows, int num_cols, int *reference_num_rows, int *reference_num_cols, int subpixel_accuracy){ switch (subpixel_accuracy) { case QCCVID_ME_FULLPIXEL: *reference_num_rows = num_rows; *reference_num_cols = num_cols; break; case QCCVID_ME_HALFPIXEL: *reference_num_rows = num_rows * 2; *reference_num_cols = num_cols * 2; break; case QCCVID_ME_QUARTERPIXEL: *reference_num_rows = num_rows * 4; *reference_num_cols = num_cols * 4; break; case QCCVID_ME_EIGHTHPIXEL: *reference_num_rows = num_rows * 8; *reference_num_cols = num_cols * 8; break; default: QccErrorAddMessage("(QccVIDMotionEstimationCalcReferenceFrameSize): Unrecognized subpixel accuracy (%d)", subpixel_accuracy); return(1); } return(0);}int QccVIDMotionEstimationCreateReferenceFrame(const QccIMGImageComponent *current_frame, QccIMGImageComponent *reference_frame, int subpixel_accuracy, const QccFilter *filter1, const QccFilter *filter2, const QccFilter *filter3){ int return_value; QccIMGImageComponent reference_frame2; QccIMGImageComponent reference_frame3; QccIMGImageComponentInitialize(&reference_frame2); QccIMGImageComponentInitialize(&reference_frame3); if (current_frame == NULL) return(0); if (reference_frame == NULL) return(0); switch (subpixel_accuracy) { case QCCVID_ME_FULLPIXEL: if ((reference_frame->num_rows != current_frame->num_rows) || (reference_frame->num_cols != current_frame->num_cols)) { QccErrorAddMessage("(QccVIDMotionEstimationCreateReferenceFrame): Reference-frame size is inconsistent with current-frame size for full-pixel motion estimation"); goto Error; } if (QccIMGImageComponentCopy(reference_frame, current_frame)) { QccErrorAddMessage("(QccVIDMotionEstimationCreateReferenceFrame): Error calling QccIMGImageComponentCopy()"); goto Error; } break; case QCCVID_ME_HALFPIXEL: if ((reference_frame->num_rows != 2 * current_frame->num_rows) || (reference_frame->num_cols != 2 * current_frame->num_cols)) { QccErrorAddMessage("(QccVIDMotionEstimationCreateReferenceFrame): Reference-frame size is inconsistent with current-frame size for half-pixel motion estimation"); goto Error; } if (filter1 == NULL) { if (QccIMGImageComponentInterpolateBilinear(current_frame, reference_frame)) { QccErrorAddMessage("(QccVIDMotionEstimationCreateReferenceFrame): Error calling QccIMGImageComponentInterpolateBilinear()"); goto Error; } } else if (QccIMGImageComponentInterpolateFilter(current_frame, reference_frame, filter1)) { QccErrorAddMessage("(QccVIDMotionEstimationCreateReferenceFrame): Error calling QccIMGImageComponentInterpolateFilter()"); goto Error; } break; case QCCVID_ME_QUARTERPIXEL: if ((reference_frame->num_rows != 4 * current_frame->num_rows) || (reference_frame->num_cols != 4 * current_frame->num_cols)) { QccErrorAddMessage("(QccVIDMotionEstimationCreateReferenceFrame): Reference-frame size is inconsistent with current-frame size for quarter-pixel motion estimation"); goto Error; } reference_frame2.num_rows = 2 * current_frame->num_rows; reference_frame2.num_cols = 2 * current_frame->num_cols; if (QccIMGImageComponentAlloc(&reference_frame2)) { QccErrorAddMessage("(QccVIDMotionEstimationCreateReferenceFrame): Error calling QccIMGImageComponentAlloc()"); goto Error; } if (filter1 == NULL) { if (QccIMGImageComponentInterpolateBilinear(current_frame, &reference_frame2)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -