int8_t YoloAsend::letterbox(void *yuvDevBuffer, uint32_t img_w, uint32_t img_h,
uint32_t yuv_w_stride, uint32_t yuv_h_stride) noexcept
{
if (!yuvDevBuffer || !dvppChannelDesc_ || !resizeConfig_)
{
ERROR_LOG("Invalid parameters or uninitialized resources");
return -1;
}
acldvppPicDesc *vpcInputDesc = acldvppCreatePicDesc();
if (!vpcInputDesc)
{
ERROR_LOG("acldvppCreatePicDesc failed");
return -1;
}
acldvppSetPicDescData(vpcInputDesc, reinterpret_cast<char *>(yuvDevBuffer));
acldvppSetPicDescFormat(vpcInputDesc, PIXEL_FORMAT_YUV_SEMIPLANAR_420);
acldvppSetPicDescWidth(vpcInputDesc, img_w);
acldvppSetPicDescHeight(vpcInputDesc, img_h);
acldvppSetPicDescWidthStride(vpcInputDesc, yuv_w_stride);
acldvppSetPicDescHeightStride(vpcInputDesc, yuv_h_stride);
acldvppSetPicDescSize(vpcInputDesc, yuv_w_stride * yuv_h_stride * 3 / 2);
m_ratio = std::min(static_cast<float>(inputDims[0][2]) / img_w,
static_cast<float>(inputDims[0][1] * 2 / 3) / img_h);
m_ratio = min(1.0f, m_ratio);
int newWidth = static_cast<int>(img_w * m_ratio);
int newHeight = static_cast<int>(img_h * m_ratio);
uint32_t resizeOutWidthStride = (newWidth + 15) / 16 * 16;
uint32_t resizeOutHeightStride = (newHeight + 1) / 2 * 2;
uint32_t resizeBufferSize = resizeOutWidthStride * resizeOutHeightStride * 3 / 2;
void *resizeBuffer = nullptr;
aclError ret = acldvppMalloc(&resizeBuffer, resizeBufferSize);
if (ret != ACL_SUCCESS)
{
ERROR_LOG("acldvppMalloc temp buffer failed, errorCode = %d", static_cast<int32_t>(ret));
acldvppDestroyPicDesc(vpcInputDesc);
return -1;
}
acldvppPicDesc *vpcOutputDesc = acldvppCreatePicDesc();
if (!vpcOutputDesc)
{
ERROR_LOG("acldvppCreatePicDesc output failed");
acldvppDestroyPicDesc(vpcInputDesc);
acldvppFree(resizeBuffer);
return -1;
}
acldvppSetPicDescData(vpcOutputDesc, resizeBuffer);
acldvppSetPicDescFormat(vpcOutputDesc, PIXEL_FORMAT_YUV_SEMIPLANAR_420);
acldvppSetPicDescWidth(vpcOutputDesc, newWidth);
acldvppSetPicDescHeight(vpcOutputDesc, newHeight);
acldvppSetPicDescWidthStride(vpcOutputDesc, resizeOutWidthStride);
acldvppSetPicDescHeightStride(vpcOutputDesc, resizeOutHeightStride);
acldvppSetPicDescSize(vpcOutputDesc, resizeBufferSize);
ret = acldvppVpcResizeAsync(dvppChannelDesc_, vpcInputDesc, vpcOutputDesc, resizeConfig_, stream_);
if (ret != ACL_SUCCESS)
{
ERROR_LOG("acldvppVpcResizeAsync failed, errorCode = %d", static_cast<int32_t>(ret));
acldvppDestroyPicDesc(vpcOutputDesc);
acldvppDestroyPicDesc(vpcInputDesc);
acldvppFree(resizeBuffer);
return -1;
}
m_padding_w = (inputDims[0][2] - newWidth) / 2;
m_padding_h = (inputDims[0][1] * 2 / 3 - newHeight) / 2;
acldvppPicDesc *borderOutputDesc = acldvppCreatePicDesc();
if (!borderOutputDesc)
{
ERROR_LOG("acldvppCreatePicDesc border output failed");
acldvppDestroyPicDesc(vpcOutputDesc);
acldvppDestroyPicDesc(vpcInputDesc);
acldvppFree(resizeBuffer);
return -1;
}
uint32_t borderWidthStride = (inputDims[0][2] + 31) / 32 * 32;
uint32_t borderHeightStride = (inputDims[0][1] * 2 / 3 + 1) / 2 * 2;
acldvppSetPicDescData(borderOutputDesc, reinterpret_cast<char *>(yuvPaddedDevBuffer_));
acldvppSetPicDescFormat(borderOutputDesc, PIXEL_FORMAT_YUV_SEMIPLANAR_420);
acldvppSetPicDescWidth(borderOutputDesc, inputDims[0][2]);
acldvppSetPicDescHeight(borderOutputDesc, inputDims[0][1] * 2 / 3);
acldvppSetPicDescWidthStride(borderOutputDesc, borderWidthStride);
acldvppSetPicDescHeightStride(borderOutputDesc, borderHeightStride);
acldvppSetPicDescSize(borderOutputDesc, yuvPaddedDevBufferSize_);
ret = acldvppSetBorderConfigTop(borderConfig_, m_padding_h);
if (ret != ACL_SUCCESS)
{
ERROR_LOG("acldvppSetBorderConfigTop failed, errorCode = %d", static_cast<int32_t>(ret));
acldvppDestroyPicDesc(borderOutputDesc);
acldvppDestroyPicDesc(vpcOutputDesc);
acldvppDestroyPicDesc(vpcInputDesc);
acldvppFree(resizeBuffer);
return -1;
}
ret = acldvppSetBorderConfigBottom(borderConfig_, inputDims[0][1] * 2 / 3 - newHeight - m_padding_h);
if (ret != ACL_SUCCESS)
{
ERROR_LOG("acldvppSetBorderConfigBottom failed, errorCode = %d", static_cast<int32_t>(ret));
acldvppDestroyPicDesc(borderOutputDesc);
acldvppDestroyPicDesc(vpcOutputDesc);
acldvppDestroyPicDesc(vpcInputDesc);
acldvppFree(resizeBuffer);
return -1;
}
ret = acldvppSetBorderConfigLeft(borderConfig_, m_padding_w);
if (ret != ACL_SUCCESS)
{
ERROR_LOG("acldvppSetBorderConfigLeft failed, errorCode = %d", static_cast<int32_t>(ret));
acldvppDestroyPicDesc(borderOutputDesc);
acldvppDestroyPicDesc(vpcOutputDesc);
acldvppDestroyPicDesc(vpcInputDesc);
acldvppFree(resizeBuffer);
return -1;
}
ret = acldvppSetBorderConfigRight(borderConfig_, inputDims[0][2] - newWidth - m_padding_w);
if (ret != ACL_SUCCESS)
{
ERROR_LOG("acldvppSetBorderConfigRight failed, errorCode = %d", static_cast<int32_t>(ret));
acldvppDestroyPicDesc(borderOutputDesc);
acldvppDestroyPicDesc(vpcOutputDesc);
acldvppDestroyPicDesc(vpcInputDesc);
acldvppFree(resizeBuffer);
return -1;
}
ret = acldvppVpcMakeBorderAsync(dvppChannelDesc_, vpcOutputDesc, borderOutputDesc, borderConfig_, stream_);
if (ret != ACL_SUCCESS)
{
ERROR_LOG("acldvppVpcMakeBorderAsync failed, errorCode = %d", static_cast<int32_t>(ret));
acldvppDestroyPicDesc(borderOutputDesc);
acldvppDestroyPicDesc(vpcOutputDesc);
acldvppDestroyPicDesc(vpcInputDesc);
acldvppFree(resizeBuffer);
return -1;
}
ret = aclrtSynchronizeStream(stream_);
if (ret != ACL_SUCCESS)
{
ERROR_LOG("aclrtSynchronizeStream failed, errorCode = %d", static_cast<int32_t>(ret));
acldvppDestroyPicDesc(borderOutputDesc);
acldvppDestroyPicDesc(vpcOutputDesc);
acldvppDestroyPicDesc(vpcInputDesc);
acldvppFree(resizeBuffer);
return -1;
}
acldvppDestroyPicDesc(borderOutputDesc);
acldvppDestroyPicDesc(vpcOutputDesc);
acldvppDestroyPicDesc(vpcInputDesc);
acldvppFree(resizeBuffer);
// std::vector<uint8_t> yuvHostData(yuvPaddedDevBufferSize_);
// ret = aclrtMemcpy(yuvHostData.data(), yuvPaddedDevBufferSize_, yuvPaddedDevBuffer_, yuvPaddedDevBufferSize_, ACL_MEMCPY_DEVICE_TO_HOST);
// if (ret == ACL_SUCCESS)
// {
// char filename[256] = "yolo_yuv.yuv";
// std::ofstream outFile(filename, std::ios::binary);
// if (outFile)
// {
// outFile.write(reinterpret_cast<char *>(yuvHostData.data()), yuvHostData.size());
// outFile.close();
// }
// }
return 0;
}
复制
环境: 310b, mxVision-7.2.RC1, ascend-toolkit-8.3.RC1
官方的yolo模型,转换成om后在aipp里面做的yuv转rgb,也就是输入是yuv格式的
使用mxvision dvppWrapper VpcPadding报错内容
E20260402 14:14:09.240523 255085725491264 DvppWrapper.cpp:1249] Get Padding config failed. Current format is 1. (Code = 1004, Message = "Invalid parameter")
使用vpc做letterbox没有问题代码如下
int8_t YoloAsend::letterbox(void *yuvDevBuffer, uint32_t img_w, uint32_t img_h, uint32_t yuv_w_stride, uint32_t yuv_h_stride) noexcept { if (!yuvDevBuffer || !dvppChannelDesc_ || !resizeConfig_) { ERROR_LOG("Invalid parameters or uninitialized resources"); return -1; } acldvppPicDesc *vpcInputDesc = acldvppCreatePicDesc(); if (!vpcInputDesc) { ERROR_LOG("acldvppCreatePicDesc failed"); return -1; } acldvppSetPicDescData(vpcInputDesc, reinterpret_cast<char *>(yuvDevBuffer)); acldvppSetPicDescFormat(vpcInputDesc, PIXEL_FORMAT_YUV_SEMIPLANAR_420); acldvppSetPicDescWidth(vpcInputDesc, img_w); acldvppSetPicDescHeight(vpcInputDesc, img_h); acldvppSetPicDescWidthStride(vpcInputDesc, yuv_w_stride); acldvppSetPicDescHeightStride(vpcInputDesc, yuv_h_stride); acldvppSetPicDescSize(vpcInputDesc, yuv_w_stride * yuv_h_stride * 3 / 2); m_ratio = std::min(static_cast<float>(inputDims[0][2]) / img_w, static_cast<float>(inputDims[0][1] * 2 / 3) / img_h); m_ratio = min(1.0f, m_ratio); int newWidth = static_cast<int>(img_w * m_ratio); int newHeight = static_cast<int>(img_h * m_ratio); uint32_t resizeOutWidthStride = (newWidth + 15) / 16 * 16; uint32_t resizeOutHeightStride = (newHeight + 1) / 2 * 2; uint32_t resizeBufferSize = resizeOutWidthStride * resizeOutHeightStride * 3 / 2; void *resizeBuffer = nullptr; aclError ret = acldvppMalloc(&resizeBuffer, resizeBufferSize); if (ret != ACL_SUCCESS) { ERROR_LOG("acldvppMalloc temp buffer failed, errorCode = %d", static_cast<int32_t>(ret)); acldvppDestroyPicDesc(vpcInputDesc); return -1; } acldvppPicDesc *vpcOutputDesc = acldvppCreatePicDesc(); if (!vpcOutputDesc) { ERROR_LOG("acldvppCreatePicDesc output failed"); acldvppDestroyPicDesc(vpcInputDesc); acldvppFree(resizeBuffer); return -1; } acldvppSetPicDescData(vpcOutputDesc, resizeBuffer); acldvppSetPicDescFormat(vpcOutputDesc, PIXEL_FORMAT_YUV_SEMIPLANAR_420); acldvppSetPicDescWidth(vpcOutputDesc, newWidth); acldvppSetPicDescHeight(vpcOutputDesc, newHeight); acldvppSetPicDescWidthStride(vpcOutputDesc, resizeOutWidthStride); acldvppSetPicDescHeightStride(vpcOutputDesc, resizeOutHeightStride); acldvppSetPicDescSize(vpcOutputDesc, resizeBufferSize); ret = acldvppVpcResizeAsync(dvppChannelDesc_, vpcInputDesc, vpcOutputDesc, resizeConfig_, stream_); if (ret != ACL_SUCCESS) { ERROR_LOG("acldvppVpcResizeAsync failed, errorCode = %d", static_cast<int32_t>(ret)); acldvppDestroyPicDesc(vpcOutputDesc); acldvppDestroyPicDesc(vpcInputDesc); acldvppFree(resizeBuffer); return -1; } m_padding_w = (inputDims[0][2] - newWidth) / 2; m_padding_h = (inputDims[0][1] * 2 / 3 - newHeight) / 2; acldvppPicDesc *borderOutputDesc = acldvppCreatePicDesc(); if (!borderOutputDesc) { ERROR_LOG("acldvppCreatePicDesc border output failed"); acldvppDestroyPicDesc(vpcOutputDesc); acldvppDestroyPicDesc(vpcInputDesc); acldvppFree(resizeBuffer); return -1; } uint32_t borderWidthStride = (inputDims[0][2] + 31) / 32 * 32; uint32_t borderHeightStride = (inputDims[0][1] * 2 / 3 + 1) / 2 * 2; acldvppSetPicDescData(borderOutputDesc, reinterpret_cast<char *>(yuvPaddedDevBuffer_)); acldvppSetPicDescFormat(borderOutputDesc, PIXEL_FORMAT_YUV_SEMIPLANAR_420); acldvppSetPicDescWidth(borderOutputDesc, inputDims[0][2]); acldvppSetPicDescHeight(borderOutputDesc, inputDims[0][1] * 2 / 3); acldvppSetPicDescWidthStride(borderOutputDesc, borderWidthStride); acldvppSetPicDescHeightStride(borderOutputDesc, borderHeightStride); acldvppSetPicDescSize(borderOutputDesc, yuvPaddedDevBufferSize_); ret = acldvppSetBorderConfigTop(borderConfig_, m_padding_h); if (ret != ACL_SUCCESS) { ERROR_LOG("acldvppSetBorderConfigTop failed, errorCode = %d", static_cast<int32_t>(ret)); acldvppDestroyPicDesc(borderOutputDesc); acldvppDestroyPicDesc(vpcOutputDesc); acldvppDestroyPicDesc(vpcInputDesc); acldvppFree(resizeBuffer); return -1; } ret = acldvppSetBorderConfigBottom(borderConfig_, inputDims[0][1] * 2 / 3 - newHeight - m_padding_h); if (ret != ACL_SUCCESS) { ERROR_LOG("acldvppSetBorderConfigBottom failed, errorCode = %d", static_cast<int32_t>(ret)); acldvppDestroyPicDesc(borderOutputDesc); acldvppDestroyPicDesc(vpcOutputDesc); acldvppDestroyPicDesc(vpcInputDesc); acldvppFree(resizeBuffer); return -1; } ret = acldvppSetBorderConfigLeft(borderConfig_, m_padding_w); if (ret != ACL_SUCCESS) { ERROR_LOG("acldvppSetBorderConfigLeft failed, errorCode = %d", static_cast<int32_t>(ret)); acldvppDestroyPicDesc(borderOutputDesc); acldvppDestroyPicDesc(vpcOutputDesc); acldvppDestroyPicDesc(vpcInputDesc); acldvppFree(resizeBuffer); return -1; } ret = acldvppSetBorderConfigRight(borderConfig_, inputDims[0][2] - newWidth - m_padding_w); if (ret != ACL_SUCCESS) { ERROR_LOG("acldvppSetBorderConfigRight failed, errorCode = %d", static_cast<int32_t>(ret)); acldvppDestroyPicDesc(borderOutputDesc); acldvppDestroyPicDesc(vpcOutputDesc); acldvppDestroyPicDesc(vpcInputDesc); acldvppFree(resizeBuffer); return -1; } ret = acldvppVpcMakeBorderAsync(dvppChannelDesc_, vpcOutputDesc, borderOutputDesc, borderConfig_, stream_); if (ret != ACL_SUCCESS) { ERROR_LOG("acldvppVpcMakeBorderAsync failed, errorCode = %d", static_cast<int32_t>(ret)); acldvppDestroyPicDesc(borderOutputDesc); acldvppDestroyPicDesc(vpcOutputDesc); acldvppDestroyPicDesc(vpcInputDesc); acldvppFree(resizeBuffer); return -1; } ret = aclrtSynchronizeStream(stream_); if (ret != ACL_SUCCESS) { ERROR_LOG("aclrtSynchronizeStream failed, errorCode = %d", static_cast<int32_t>(ret)); acldvppDestroyPicDesc(borderOutputDesc); acldvppDestroyPicDesc(vpcOutputDesc); acldvppDestroyPicDesc(vpcInputDesc); acldvppFree(resizeBuffer); return -1; } acldvppDestroyPicDesc(borderOutputDesc); acldvppDestroyPicDesc(vpcOutputDesc); acldvppDestroyPicDesc(vpcInputDesc); acldvppFree(resizeBuffer); // std::vector<uint8_t> yuvHostData(yuvPaddedDevBufferSize_); // ret = aclrtMemcpy(yuvHostData.data(), yuvPaddedDevBufferSize_, yuvPaddedDevBuffer_, yuvPaddedDevBufferSize_, ACL_MEMCPY_DEVICE_TO_HOST); // if (ret == ACL_SUCCESS) // { // char filename[256] = "yolo_yuv.yuv"; // std::ofstream outFile(filename, std::ios::binary); // if (outFile) // { // outFile.write(reinterpret_cast<char *>(yuvHostData.data()), yuvHostData.size()); // outFile.close(); // } // } return 0; } 复制使用mxvision做letterbox就报上面的那个错误了,resize后保存出来的图像是正确的,代码如下:
int8_t YoloAsend::letterbox(MxBase::MemoryData yuvDevDataMemery, uint32_t img_w, uint32_t img_h, uint32_t yuv_w_stride, uint32_t yuv_h_stride) noexcept { if (!yuvDevDataMemery.ptrData) { ERROR_LOG("Invalid parameters"); return -1; } MxBase::DvppDataInfo inputDataInfo; inputDataInfo.width = img_w; // 1920 inputDataInfo.height = img_h; // 1080 inputDataInfo.widthStride = yuv_w_stride; // 1920 inputDataInfo.heightStride = yuv_h_stride; // 1080 inputDataInfo.format = MxBase::MXBASE_PIXEL_FORMAT_YUV_SEMIPLANAR_420; inputDataInfo.dataSize = yuv_w_stride * yuv_h_stride * 3 / 2; // 3110400 inputDataInfo.data = static_cast<uint8_t *>(yuvDevDataMemery.ptrData); // inputDims[0][1]:960 inputDims[0][2]: 640 m_ratio = std::min(static_cast<float>(inputDims[0][2]) / img_w, static_cast<float>(inputDims[0][1] * 2 / 3) / img_h); m_ratio = min(1.0f, m_ratio); // 0.333333343 int newWidth = static_cast<int>(img_w * m_ratio); // 640 int newHeight = static_cast<int>(img_h * m_ratio); // 360 uint32_t resizeOutWidthStride = (newWidth + 15) / 16 * 16; //640 uint32_t resizeOutHeightStride = (newHeight + 1) / 2 * 2; // 360 uint32_t resizeBufferSize = resizeOutWidthStride * resizeOutHeightStride * 3 / 2; //345600 MxBase::MemoryData resizeMemoryData(resizeBufferSize, MxBase::MemoryData::MemoryType::MEMORY_DVPP); APP_ERROR memRet = MxBase::MemoryHelper::MxbsMalloc(resizeMemoryData); if (memRet != APP_ERR_OK) { ERROR_LOG("MxbsMalloc resize buffer failed, errorCode = %d", memRet); return -1; } MxBase::DvppDataInfo outputDataInfo; outputDataInfo.width = newWidth; // 640 outputDataInfo.height = newHeight; // 360 outputDataInfo.widthStride = resizeOutWidthStride; //640 outputDataInfo.heightStride = resizeOutHeightStride; //360 outputDataInfo.format = MxBase::MXBASE_PIXEL_FORMAT_YUV_SEMIPLANAR_420; outputDataInfo.dataSize = resizeBufferSize; //345600 outputDataInfo.data = static_cast<uint8_t *>(resizeMemoryData.ptrData); MxBase::ResizeConfig resizeConfig; resizeConfig.width = newWidth; // 640 resizeConfig.height = newHeight; //360 MxBase::DvppWrapper dvppWrapper; APP_ERROR ret = dvppWrapper.Init(); if (ret != APP_ERR_OK) { ERROR_LOG("dvppWrappper Init failed, errorCode = %d", ret); MxBase::MemoryHelper::MxbsFree(resizeMemoryData); return -1; } ret = dvppWrapper.VpcResize(inputDataInfo, outputDataInfo, resizeConfig); if (ret != APP_ERR_OK) { ERROR_LOG("VpcResize failed, errorCode = %d", ret); MxBase::MemoryHelper::MxbsFree(resizeMemoryData); return -1; } // 保存出来的yuv图能够正确打开 // std::vector<uint8_t> yuvresizeHostData(resizeBufferSize); // ret = aclrtMemcpy(yuvresizeHostData.data(), resizeBufferSize, resizeMemoryData.ptrData, resizeBufferSize, ACL_MEMCPY_DEVICE_TO_HOST); // if (ret == ACL_SUCCESS) // { // char filename[256] = "yolo_resize_yuv.yuv"; // std::ofstream outFile(filename, std::ios::binary); // if (outFile) // { // outFile.write(reinterpret_cast<char *>(yuvresizeHostData.data()), yuvresizeHostData.size()); // outFile.close(); // } // } m_padding_w = (inputDims[0][2] - newWidth) / 2; // 0 m_padding_h = (inputDims[0][1] * 2 / 3 - newHeight) / 2; // 140 MxBase::DvppDataInfo paddedDataInfo; paddedDataInfo.width = inputDims[0][2]; // 640 paddedDataInfo.height = inputDims[0][1] * 2 / 3; // 640 paddedDataInfo.widthStride = yuvPaddedWidthStride_; // 640 paddedDataInfo.heightStride = yuvPaddedHeightStride_; // 640 paddedDataInfo.format = MxBase::MXBASE_PIXEL_FORMAT_YUV_SEMIPLANAR_420; paddedDataInfo.dataSize = yuvPaddedMemeryDataSize_; // 614400 paddedDataInfo.data = static_cast<uint8_t *>(yuvPaddedMemoryData_.ptrData); MxBase::MakeBorderConfig makeBorderConfig; makeBorderConfig.left = m_padding_w; // 0 makeBorderConfig.right = inputDims[0][2] - newWidth - m_padding_w; // 0 makeBorderConfig.top = m_padding_h; // 140 makeBorderConfig.bottom = inputDims[0][1] * 2 / 3 - newHeight - m_padding_h; // 140 makeBorderConfig.channel_zero = 114; makeBorderConfig.channel_one = 128; makeBorderConfig.channel_two = 128; makeBorderConfig.borderType = MxBase::MakeBorderConfig::BORDER_CONSTANT; ret = dvppWrapper.VpcPadding(outputDataInfo, paddedDataInfo, makeBorderConfig); if (ret != APP_ERR_OK) { ERROR_LOG("VpcPadding failed, errorCode = %d", ret); MxBase::MemoryHelper::MxbsFree(resizeMemoryData); return -1; } MxBase::MemoryHelper::MxbsFree(resizeMemoryData); ret = dvppWrapper.DeInit(); if (ret != APP_ERR_OK) { ERROR_LOG("dvppWrapper DeInit, errorCode = %d", ret); return -1; } std::vector<uint8_t> yuvHostData(yuvPaddedMemeryDataSize_); ret = aclrtMemcpy(yuvHostData.data(), yuvPaddedMemeryDataSize_, yuvPaddedMemoryData_.ptrData, yuvPaddedMemeryDataSize_, ACL_MEMCPY_DEVICE_TO_HOST); if (ret == ACL_SUCCESS) { char filename[256] = "yolo_yuv.yuv"; std::ofstream outFile(filename, std::ios::binary); if (outFile) { outFile.write(reinterpret_cast<char *>(yuvHostData.data()), yuvHostData.size()); outFile.close(); } } return 0; }