Stitch

Through stitch, realize the effect of stitching and fusion of one picture with another picture, commonly used in APA and panorama stitching and other scenarios.

Operator Effect

Input ImagePositionOutput Image
VP5input_stitch_apa_topForward visionVP5out_apa_res
VP5input_stitch_apa_bottomRear view
VP5input_stitch_apa_rightRight vision
VP5input_stitch_apa_leftLeft vision
VP5input_stitch_dstBottom view

Principle

If it's a stitch mode, where you do a stitch of two pictures and paste them into a dst layer, then the formula is as follows:

dst(x,y)=src0(x,y)alpha+src1(x,y)(255alpha)dst(x, y) = src0(x, y) * alpha + src1(x, y) * (255-alpha)

Among them, dst is the output picture, src0 is the input picture 0, and src1 is the input picture 1. The src0 pixel points are multiplied by the alpha coefficient and the corresponding pixel points of the other image are multiplied by the beta coefficient, and the two results are added together to update the pixel points of the dst layer.

VP5input_stitch_blend

If you are in paste original mode, pasting a picture to a dst layer, then the formula is as follows:

dst(x,y)=src(x,y)dst(x, y) = src(x, y)

Among them, dst is the output picture and src is the input picture. Updates the pixel points of the dst layer, using the src pixel points.

VP5input_stitch_copy

The lut table, which is composed of the above n alpha, is the table that can represent the fusion of each pixel point in the w*h region. By configuring different alpha values for each pixel point, different stitching values can be realized.

VP5input_stitch_lut

API Interface

int32_t hbVPStitch(hbUCPTaskHandle_t *taskHandle, hbVPImage *dstImg, hbVPImage const *srcImgs, hbVPPoint const *dstPoses, int32_t srcImgCount, hbVPAlphaBlendLut alphaBlendLut);

For detailed interface information, please refer to hbVPStitch .

Usage

// Include the header #include "hobot/hb_ucp.h" #include "hobot/vp/hb_vp.h" #include "hobot/vp/hb_vp_stitch.h" // init param int32_t alphaBlendRegionNum{1}; std::vector<uint8_t> alpha(320 * 160); memset(alpha.data(), uint8_t(200), 320 * 160); std::vector<uint8_t *> alphaDataArray = {alpha.data()}; std::vector<hbVPRoi> alphaBlendRegions = {{320, 0, 480 - 1, 320 - 1}}; // create alpha-blend lut hbVPAlphaBlendLut alphaBlendLut{nullptr}; hbVPCreateAlphaBlendLut(&alphaBlendLut, alphaDataArray.data(), alphaBlendRegions.data(), alphaBlendRegionNum); // init task handle and schedule param hbUCPTaskHandle_t task_handle{nullptr}; hbUCPSchedParam sched_param; HB_UCP_INITIALIZE_SCHED_PARAM(&sched_param); sched_param.backend = HB_UCP_STITCH_CORE_0; // init Image, allocate memory for image data int32_t srcImgCount{2}; std::vector<hbUCPSysMem> src_mems(srcImgCount); std::vector<hbVPImage> src_imgs(srcImgCount); for (int32_t i{0}; i < srcImgCount; i++) { hbUCPMallocCached(&src_mems[i], src_stride * src_height, 0); src_imgs[i] = {HB_VP_IMAGE_FORMAT_NV12, HB_VP_IMAGE_TYPE_U8C1, src_width, src_height, src_stride, src_mems[i].virAddr, src_mems[i].phyAddr, reinterpret_cast<char *>(src_imgs[i].dataVirAddr) + src_stride * src_height, src_imgs[i].dataPhyAddr + src_stride * src_height, src_stride}; } std::vector<hbVPPoint> dstPoses(srcImgCount); dstPoses[0] = {160, 0}; dstPoses[1] = {320, 0}; hbUCPSysMem dst_mem; hbUCPMallocCached(&dst_mem, dst_stride * dst_height * 3 / 2, 0); hbVPImage dst_img{HB_VP_IMAGE_FORMAT_NV12, HB_VP_IMAGE_TYPE_U8C1, dst_width, dst_height, dst_stride, dst_mem.virAddr, dst_mem.phyAddr, reinterpret_cast<char *>(dst_img.dataVirAddr) + dst_stride * dst_height, dst_img.dataPhyAddr + dst_stride * dst_height, dst_stride}; // create task hbVPStitch(&task_handle, &dst_img, src_imgs.data(), dstPoses.data(), srcImgCount, alphaBlendLut); // submit task hbUCPSubmitTask(task_handle, &sched_param); // wait for task done hbUCPWaitTaskDone(task_handle, 0); // release task handle hbUCPReleaseTask(task_handle); // release alpha-blend lut hbVPReleaseAlphaBlendLut(alphaBlendLut); // release memory for (int32_t i{0}; i < srcImgCount; i++) { hbUCPFree(&src_mems[i]); } hbUCPFree(&dst_mem);