通过拼接,实现将一张图片与另一张图片拼接融合的效果,常用于APA和全景图拼接等场景。
| 输入图像 | 位置 | 输出图像 |
| 前视 | ![]() | |
| 后视 | ||
| 右视 | ||
| 左视 | ||
![]() | 底层图 |
如果是拼接模式,将两张图做拼接粘贴至dst图层,那么公式如下:
dst(x,y)=src0(x,y)∗alpha+src1(x,y)∗(255−alpha)
其中, dst 是输出图片,src0 是输入图片0,src1 是输入图片1。 src0像素点乘以alpha系数,另一张图的对应像素点乘以beta系数,将两个结果相加,更新dst图层的像素点。
如果是粘贴原图模式,将一张图粘贴至dst图层,那么公式如下:
dst(x,y)=src(x,y)
其中, dst 是输出图片,src 是输入图片。 使用src像素点,更新dst图层的像素点。
lut表,就是由上述n个alpha组成的,能够表示w*h区域每个像素点融合情况的表。通过配置每个像素点不同的alpha值,可以实现不同的拼接值。
int32_t hbVPStitch(hbUCPTaskHandle_t *taskHandle, hbVPImage *dstImg,
hbVPImage const *srcImgs, hbVPPoint const *dstPoses, int32_t srcImgCount,
hbVPAlphaBlendLut alphaBlendLut);
详细接口信息请查看 hbVPStitch 。
// 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);

