打开微信,使用扫一扫进入页面后,点击右上角菜单,
点击“发送给朋友”或“分享到朋友圈”完成分享
本人现在编写了一个函数。使用CNCV库将解码出来的cncodec 数据进行缩放和格式转换成Mat格式的图像再输出。确认输入的cncodec 数据是正确的(可保存成文件输出,图像显示正常)但是输出的画面是是全绿。
以下是源码
// 缩放到720P cncodec -> Mat int decodeCambrian::decodeCambrian_resize(cncodec src ,cv::Mat *img){ //初始化 cnrtDev_t CV_dev; cnrtQueue_t CV_queue = nullptr; cncvHandle_t CV_handle = nullptr; uint32_t batch_size = 1; cncvContextInit(CV_dev, CV_queue, CV_handle);//缩放功能初始化 //参数转换 cncvImage srcImg; // 输入的图像信息 cncvImage dstImg; // 输出的图像信息 memset(&srcImg, 0, sizeof(srcImg)); memset(&dstImg, 0, sizeof(dstImg)); //cncodec to cncvImage //【源数据】 srcImg.width=src .width; srcImg.height=src .height; srcImg.stride[0]=src .stride[0]; srcImg.stride[1]=src .stride[1]; srcImg.planeNum=src .planeNum; srcImg.plane[0].size=src .height * src .stride[0]; srcImg.plane[1].size=(src .height/2)*src .stride[1]; memcpy(&(srcImg.plane[0].addr),(void *)(src .plane[0].addr),src .plane[0].size); memcpy(&(srcImg.plane[1].addr),(void *)(src .plane[1].addr),src .plane[1].size); // srcImg.plane[0].addr=malloc(srcImg.plane[0].size); // srcImg.plane[1].addr=malloc(srcImg.plane[1].size); srcImg.colorSpace=(cncvColorSpace)(src .colorSpace); srcImg.pixelFmt=(cncvPixelFormat)(src .pixelFmt); srcImg.depth=CNCV_DEPTH_8U; //Mat to cncvImage dstImg.width=img->cols; dstImg.height=img->rows; dstImg.stride[0]=(img->step); dstImg.pixelFmt=CNCV_PIX_FMT_BGRA;//图像格式 dstImg.colorSpace=CNCV_COLOR_SPACE_BT_601;//颜色空间 dstImg.plane[0].size=(img->rows)*(img->step); dstImg.plane[0].addr=malloc(dstImg.plane[0].size); dstImg.planeNum=1; dstImg.depth=CNCV_DEPTH_8U; //参数获取 cncvImageDe or_t src_desc_yuv;//输入的图像参数 createImageDe or(&src_desc_yuv); src_desc_yuv->width = srcImg.width; src_desc_yuv->height = srcImg.height; src_desc_yuv->depth = CNCV_DEPTH_8U; src_desc_yuv->pixel_fmt = CNCV_PIX_FMT_NV12; src_desc_yuv->color_space = (cncvColorSpace)(src .colorSpace); src_desc_yuv->stride[0] = srcImg.stride[0];//地址 src_desc_yuv->stride[1] = srcImg.stride[1]; cncvImageDe or_t det_desc_rgba;//输出的图像参数 createImageDe or(&det_desc_rgba); det_desc_rgba->width = dstImg.width; det_desc_rgba->height = dstImg.height; det_desc_rgba->depth = CNCV_DEPTH_8U; det_desc_rgba->pixel_fmt = CNCV_PIX_FMT_BGRA; det_desc_rgba->color_space = (cncvColorSpace)(src .colorSpace); det_desc_rgba->stride[0] = dstImg.stride[0]; //感兴趣的区域(默认全局) cncvRect *src_rois_yuv = (cncvRect *)malloc(batch_size * sizeof(cncvRect)); src_rois_yuv[0].x=0; src_rois_yuv[0].y=0; src_rois_yuv[0].w=srcImg.width; src_rois_yuv[0].h=srcImg.height; cncvRect *dst_rois_rgba = (cncvRect *)malloc(batch_size * sizeof(cncvRect)); dst_rois_rgba[0].x=0; dst_rois_rgba[0].y=0; dst_rois_rgba[0].w=(unsigned int)(dstImg.width); dst_rois_rgba[0].h=(unsigned int)(dstImg.height); printf("-------------------------------------------------\n\r"); printf(">>> srcImg width:%8d,height:%8d \n\r",srcImg.width,srcImg.height); printf(">>> dstImg width:%8d,height:%8d \n\r",dstImg.width,dstImg.height); printf("-------------------------------------------------\n\r"); printf("src_rois_yuv :%8d,%8d,%8d,%8d \n\r",src_rois_yuv[0].x,src_rois_yuv[0].y,src_rois_yuv[0].w,src_rois_yuv[0].h); printf("dst_rois_rgba:%8d,%8d,%8d,%8d \n\r",dst_rois_rgba[0].x,dst_rois_rgba[0].y,dst_rois_rgba[0].w,dst_rois_rgba[0].h); printf("-------------------------------------------------\n\r"); //计算工作空间大小 void *workspace_switch = nullptr; size_t workspace_size_switch;//工作空间大小 cncvGetResizeConvertWorkspaceSize(batch_size, src_desc_yuv, src_rois_yuv, det_desc_rgba, dst_rois_rgba, &workspace_size_switch); CNRT_CHECK(cnrtMalloc((void **)&(workspace_switch), workspace_size_switch));//在MLU设备上分配内存,创建工作空间 //相关工作内存空间创建 void **srcYDev = NULL;//yuv的Y值,指向MLU上源图像y数据的指针 void **srcUVDev = NULL;//yuv的UV值,指向MLU上源图像UV数据的指针 void **dstDev = NULL;//指向用于存储输出数据的MLU空间的指针 CNRT_CHECK(cnrtMalloc((void **)&srcYDev, batch_size * sizeof(void *)));//在mlu220中创建输入图像内存空间 CNRT_CHECK(cnrtMalloc((void **)&srcUVDev, batch_size * sizeof(void *))); CNRT_CHECK(cnrtMalloc((void **)&dstDev, batch_size * sizeof(void *))); //主机内存空间(交换变量) size_t srcYDataSize = src .height * src .stride[0]; size_t srcUVDataSize = (src .height/2) * src .stride[1]; size_t dstDataSize = (img->rows)*(img->step); void **srcYDev_tmp = (void **)(malloc(batch_size * sizeof(void *))); void **srcUVDev_tmp = (void **)(malloc(srcYDataSize * sizeof(void *))); void **dstDev_tmp = (void **)(malloc(dstDataSize * sizeof(void *))); //主机到模块 CNRT_CHECK(cnrtMalloc((void **)&(srcYDev_tmp[0]), srcYDataSize));//在mlu220中创建输入图像内存空间 CNRT_CHECK(cnrtMalloc((void **)&(srcUVDev_tmp[0]), srcUVDataSize)); CNRT_CHECK(cnrtMalloc((void **)&(dstDev_tmp[0]), dstDataSize)); CNRT_CHECK(cnrtMemcpy(srcYDev_tmp[0],srcImg.plane[0].addr ,srcYDataSize ,CNRT_MEM_TRANS_DIR_HOST2DEV)); CNRT_CHECK(cnrtMemcpy(srcUVDev_tmp[0],srcImg.plane[1].addr,srcUVDataSize ,CNRT_MEM_TRANS_DIR_HOST2DEV)); //将主机的内存信息映射到模块的内存中 CNRT_CHECK(cnrtMemcpy(srcYDev,srcYDev_tmp,batch_size*sizeof(void *),CNRT_MEM_TRANS_DIR_HOST2DEV)); CNRT_CHECK(cnrtMemcpy(srcUVDev,srcUVDev_tmp,batch_size*sizeof(void *),CNRT_MEM_TRANS_DIR_HOST2DEV)); CNRT_CHECK(cnrtMemcpy(dstDev,dstDev_tmp,batch_size*sizeof(void *),CNRT_MEM_TRANS_DIR_HOST2DEV)); //执行图像格式转换(当前版本为0.2.118) CNCV_CHECK(cncvResizeConvert( CV_handle, // 上下文指针 batch_size, // src_desc_yuv, // src_rois_yuv, // (void **)srcYDev, // (void **)srcUVDev, // det_desc_rgba, // dst_rois_rgba, // (void **)dstDev, // workspace_size_switch, // workspace_switch, // CNCV_INTER_BILINEAR)); // CNRT_CHECK(cnrtSyncQueue(CV_queue));//同步队列 //获取结果 //目的地址、源地址,大小,方向 CNRT_CHECK(cnrtMemcpy(dstImg.plane[0].addr,dstDev_tmp[0],dstDataSize, CNRT_MEM_TRANS_DIR_DEV2HOST));//模块到主机 printf(">>>dstImg info:w=%d,h=%d, planeNum=%d, addr=%llu,size=%d \n\r ", dstImg.width, dstImg.height, dstImg.planeNum, dstImg.plane->addr, dstImg.plane->size); //转换图像格式 cncvStatus_t status; status = cncvutils::cncvImageToMat(dstImg, *img);//cncvImage to Mat if (status != CNCV_STATUS_SUCCESS) { ERROR("error, cannot translate to cv::Mat"); } else { LOG("transform cncvImage to cv::Mat success!"); //printf(">>>dstImg.pixelFmt=%d,\n\r",dstImg.pixelFmt); } //释放内存 free(src_rois_yuv); free(dst_rois_rgba); CNRT_CHECK(cnrtFree(srcYDev)); CNRT_CHECK(cnrtFree(srcUVDev)); CNRT_CHECK(cnrtFree(dstDev)); CNRT_CHECK(cnrtFree(workspace_switch)); CNRT_CHECK(cnrtFree(srcYDev_tmp[0])); CNRT_CHECK(cnrtFree(srcUVDev_tmp[0])); CNRT_CHECK(cnrtFree(dstDev_tmp[0])); free(srcYDev_tmp); free(srcUVDev_tmp); free(dstDev_tmp); delete src_desc_yuv;//回收内存 delete det_desc_rgba; cncvDestroyImage(&srcImg); cncvDestroyImage(&dstImg); cncvDestroy(CV_handle); cnrtDestroyQueue(CV_queue); cnrtDestroy(); return 0; }
我该如何去排查与处理这个问题呢?谢谢!~
热门帖子
精华帖子