TI中文支持网
TI专业的中文技术问题搜集分享网站

SK-TDA4VM: opencv创建的图像在TIOVX中进行图像的相关处理

Part Number:SK-TDA4VM

TI专家您好,
   关于如何从opencv创建的Mat类型的数据如何在TIOVX中利用vxNorNode的取反操作时,我发现利用vx_image in_img1 vxCreateImageFromHandle(context,VX_DF_IMAGE_U8,&addr,&ptr,VX_MEMORY_TYPE_HOST)从opencv获取的图像,在进行vxNorNode后并未输出算法效果。
   而另外一种将opencv的数据通过imwrite写到本地后,再利用vx_image in_img2 tivx_utils_create_vximage_from_bmpfile加载出来的图像,在进行vxNorNode后则能执行取反算法。
   对此,我比较疑惑,vxCreateImageFromHandle的用法不就是创建对外部分配图像对象的引用吗?而opencv创建Mat对象的地址相关信息已传给vxCreateImageFromHandle,且通过vxQueryImage获取in_img1的图像相关属性和in_img2的都是一摸一样,且两者在vxNorNode节点操作前打印的像素值也是一致的,但vx_node node0=vxNotNode(graph,in_img1,out_img)和node0=vxNotNode(graph,in_img2,out_img)后,打印 out_img 的像素值,前者却没有进行图像取反操作。

是否vxCreateImageFromHandle从外部系统获取的图像不能直接进行图像的相关处理?如果确实不能这样直接操作的话,那么是否只能用后者的方式,那么关于vxCreateImageFromHandle的用法又该如何利用呢?而通过保存到本地再加载出来处理的方式是否比较耗时呢?

望不吝赐教,期待您的回复!

best wish!

Ling Wang

 

opencv创建图像的代码如下:

vx_uint32 width=16;

vx_uint32 height=5;

cv::Mat img(height,width,CV_8UC1,Scalar(0));

img(Rang(1,5),Rang(1,5))=Scalar(255);

//imwrite("inImg_cvSave.bmp",img);

vx_imagepatch_addressing_t addr;

addr.dim_x=width;

addr.dim_y=height;

addr.stride_x=1;

addr.stride_y=16;

addr.step_x=1;

addr.step_y=1;

addr.scale_x=VX_SCALE_UNITY;

addr.scale_y=VX_SCALE_UNITY;

void * ptr=img.data;

Cherry Zhou:

您好,您的问题我们已升级到英文论坛寻求帮助,链接如下:

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1249571/sk-tda4vm-the-image-created-by-opencv-is-processed-in-tiovx

,

Cherry Zhou:

您好,

使用从 vxCreateImageFromHandle 创建的输入映像执行 vxNorNode ()时是否出现任何错误? 如果有的话,您能否分享下运行此应用程序的log? 

,

wang ling:

************************************************************************代码*******************************************************************void show_image_all_pixel(vx_image in_img){ vx_uint32 width; vx_uint32 height;

vxQueryImage(in_img, (vx_enum)VX_IMAGE_WIDTH, &width, sizeof(vx_uint32)); vxQueryImage(in_img, (vx_enum)VX_IMAGE_HEIGHT, &height, sizeof(vx_uint32));

vx_map_id map_id_in; vx_rectangle_t rect_in = {0, 0, width, height}; vx_imagepatch_addressing_t map_addr_in; vx_uint8* map_ptr_in; vxMapImagePatch(in_img, &rect_in, 0, &map_id_in, &map_addr_in, (void **)&map_ptr_in, VX_READ_ONLY, VX_MEMORY_TYPE_HOST, VX_NOGAP_X);

printf("/************************************打印图像像素值************************************/\n"); volatile vx_uint32 i,j,k; i=j=k=0; for(volatile vx_uint32 y = 0; y < map_addr_in.dim_y; y+=map_addr_in.step_y) { j = (map_addr_in.stride_y*y*map_addr_in.scale_y)/VX_SCALE_UNITY; for (volatile vx_uint32 x = 0; x < map_addr_in.dim_x; x+=map_addr_in.step_x) { i = j + (map_addr_in.stride_x*x*map_addr_in.scale_x)/VX_SCALE_UNITY; k++; if (0 == k%width) { printf("%u\n", *(map_ptr_in+i)); } else { printf("%u, ", *(map_ptr_in+i)); } } } printf("/************************************打印图像像素值结束************************************/\n"); vxUnmapImagePatch(in_img, map_id_in);}

void main(void){ vx_uint32 width = 16; vx_uint32 height = 5;

// 创建opencv图像 Mat img(height,width,CV_8UC1,Scalar(0)); img(Range(1,5), Range(1,5)) = Scalar(255); printf("opencv创建图像(高*宽*通道数):%d*%d*%d\n", img.rows, img.cols, img.channels()); cout << "img.elemSize(): " << img.elemSize() << endl; cout << "img.elemSize1(): " << img.elemSize1() << endl; cout << "img.step: " << img.step << endl; cout << "img.step1(): " << img.step1() << endl; imwrite("pics/inImg_cvSave.bmp", img); // 打印opencv创建的图像的所有像素 cout << "———————————打印opencv创建的图像的所有像素———————————" << endl; int tt=0; for (int i=0; i<(int)height; i++) { for(int j=0; j<(int)width; j++) { tt++; if (0 == tt%width) { cout << img.at<uchar>(i,j) << endl; } else { cout << (int)img.at<uchar>(i,j) << ", "; } } }

// 利用opencv图像信息配置openvx图像地址结构 vx_imagepatch_addressing_t addr; addr.dim_x = width; addr.dim_y = height; addr.stride_x = (vx_uint32)img.elemSize(); addr.stride_y = (vx_uint32)img.step; addr.step_x = 1; addr.step_y = 1; addr.scale_x = VX_SCALE_UNITY; addr.scale_y = VX_SCALE_UNITY; void* ptr = img.data; // 创建上下文,输入图像 vx_context context = vxCreateContext(); ERROR_CHECK_OBJECT(context); vx_image in_img; vx_status status = VX_SUCCESS;

// 从句柄中导入输入图像,打印图像属性,openvx图像地址结构 in_img = vxCreateImageFromHandle(context, VX_DF_IMAGE_U8, &addr, &ptr, VX_MEMORY_TYPE_HOST); cout << "———————————打印vxCreateImageFromHandle创建的图像的所有像素———————————" << endl; show_image_all_pixel(in_img); // 创建图,创建输出图像 vx_graph graph = vxCreateGraph(context); vx_image out_img = vxCreateImage(context, width, height, VX_DF_IMAGE_U8); // 创建节点 vx_node n0 = vxNotNode(graph, in_img, out_img); // 验证图,保存图结构 status = vxVerifyGraph(graph); // 调度图 status = vxScheduleGraph(graph); status = vxWaitGraph(graph);

if (VX_SUCCESS == status) { cout << "———————————打印vxNotNode输出图像的所有像素———————————" << endl; show_image_all_pixel(out_img); }

// 释放资源 vxReleaseImage(&in_img); vxReleaseImage(&out_img); vxReleaseNode(&n0); vxReleaseGraph(&graph); vxReleaseContext(&context);}

************************************************************************日志*******************************************************************APP: Init … !!!MEM: Init … !!!MEM: Initialized DMA HEAP (fd=4) !!!MEM: Init … Done !!!IPC: Init … !!!IPC: Init … Done !!!REMOTE_SERVICE: Init … !!!REMOTE_SERVICE: Init … Done !!! 30433.712534 s: GTC Frequency = 200 MHzAPP: Init … Done !!! 30433.712892 s: VX_ZONE_INIT:Enabled 30433.712904 s: VX_ZONE_ERROR:Enabled 30433.712948 s: VX_ZONE_WARNING:Enabled 30433.713889 s: VX_ZONE_INIT:[tivxInitLocal:130] Initialization Done !!! 30433.715078 s: VX_ZONE_INIT:[tivxHostInitLocal:93] Initialization Done for HOST !!!/************************************打印Target使能情况************************************/TIVX_TARGET_A72_0 Enable: YESTIVX_TARGET_A72_1 Enable: YESTIVX_TARGET_A72_2 Enable: YESTIVX_TARGET_A72_3 Enable: YESTIVX_TARGET_DSP1 Enable: YESTIVX_TARGET_DSP2 Enable: YESTIVX_TARGET_DSP_C7_1 Enable: YES/************************************打印Target使能情况结束************************************/opencv创建图像(高*宽*通道数):5*16*1img.elemSize(): 1img.elemSize1(): 1img.step: 16img.step1(): 16———————————打印opencv创建的图像的所有像素———————————0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ———————————打印vxCreateImageFromHandle创建的图像的所有像素———————————/************************************打印图像像素值************************************/0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0/************************************打印图像像素值结束************************************/———————————打印vxNotNode输出图像的所有像素———————————/************************************打印图像像素值************************************/90, 30, 1, 1, 22, 0, 0, 0, 33, 0, 0, 0, 44, 0, 0, 00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0/************************************打印图像像素值结束************************************/ 30433.719841 s: VX_ZONE_INIT:[tivxHostDeInitLocal:107] De-Initialization Done for HOST !!! 30433.724260 s: VX_ZONE_INIT:[tivxDeInitLocal:193] De-Initialization Done !!!APP: Deinit … !!!REMOTE_SERVICE: Deinit … !!!REMOTE_SERVICE: Deinit … Done !!!IPC: Deinit … !!!IPC: DeInit … Done !!!MEM: Deinit … !!!DDR_SHARED_MEM: Alloc's: 1 alloc's of 80 bytes DDR_SHARED_MEM: Free's : 1 free's of 80 bytes DDR_SHARED_MEM: Open's : 0 allocs of 0 bytes DDR_SHARED_MEM: Total size: 536870912 bytes MEM: Deinit … Done !!!APP: Deinit … Done !!!

,

Annie Liu:

已将您的问题反馈给产品工程师,一旦有回复,回尽快告知您。

,

Cherry Zhou:

wang ling said:vx_imagepatch_addressing_t addr; addr.dim_x = width; addr.dim_y = height; addr.stride_x = (vx_uint32)img.elemSize(); addr.stride_y = (vx_uint32)img.step; addr.step_x = 1; addr.step_y = 1; addr.scale_x = VX_SCALE_UNITY; addr.scale_y = VX_SCALE_UNITY; void* ptr = img.data;

工程师从 vxCreateImage()和 handle 创建映像的唯一区别是您提供了上述值(尤其是 STRIDE_y)

输出可能会成为问题,可能由于提供的跨度错误。

您能否确认 STRIDE_y 是否正确? 理想情况下,应该是 width* mul_FACTOR,其中 mul_FACTOR (8位格式为1,16位格式为2,等等) 

,

wang ling:

我确认 STRIDE_y 是正确的!因为我从opencv创建的图像宽度为16,高度为5,像素格式为无符号8bit的灰度图像(即一个像素一个字节),那么像素间距为1字节,行间距的跨度当为16*1=16字节。
不知您说的从vxCreateImage()和handle创建映像的唯一区别是我提供了如下跨度有何问题?如有问题,那么您在通过handle创建图像后再对图像做vxNotNode取反操作后的输出结果是正常的吗?您是怎么通过handle来创建图像的呢?我有尝试过把opencv创建的图像通过imwrite保存后再通过tivx_utils_create_vximage_from_bmpfile()加载出来,再利用vxNotNode取反操作则结果是正确的呢。对此我还是比较疑惑,望不吝赐教,期待您的回复,谢谢。

vx_imagepatch_addressing_t addr;addr.dim_x = width;addr.dim_y = height;addr.stride_x = 1;  //像素间距为1个字节addr.stride_y = 16;//行间距为行宽度*像素字节数,即为16*1addr.step_x = 1;addr.step_y = 1;addr.scale_x = VX_SCALE_UNITY;addr.scale_y = VX_SCALE_UNITY;void* ptr = img.data;   
 
 
代码简化如下 :
 

void main(void){

void show_image_all_pixel(vx_image in_img);//声明打印图像像素点函数

vx_uint32 width = 16;vx_uint32 height = 5;

// 创建opencv图像Mat img(height,width,CV_8UC1,Scalar(0));   //创建宽度为16,高度为5,像素格式为无符号8bit的图像,初始化为0img(Range(1,5), Range(1,5)) = Scalar(255);   //将图像的第1~4行,1~4列赋值为255printf("opencv创建图像(高*宽*通道数):%d*%d*%d\n", img.rows, img.cols, img.channels());

// 利用opencv图像信息配置openvx图像地址结构vx_imagepatch_addressing_t addr;addr.dim_x = width;addr.dim_y = height;addr.stride_x = 1;  //像素间距为1个字节addr.stride_y = 16;//行间距为行宽度*像素字节数,即为16*1addr.step_x = 1;addr.step_y = 1;addr.scale_x = VX_SCALE_UNITY;addr.scale_y = VX_SCALE_UNITY;void* ptr = img.data;   //imwrite("image.bmp",img);   

// 创建上下文,输入图像vx_context context = vxCreateContext();// 创建图vx_graph graph = vxCreateGraph(context);

vx_image in_img;vx_status status = VX_SUCCESS;

// 从句柄中导入输入图像,打印图像属性in_img = vxCreateImageFromHandle(context, VX_DF_IMAGE_U8, &addr, &ptr, VX_MEMORY_TYPE_HOST);cout << "———————————打印vxCreateImageFromHandle创建的图像的所有像素———————————" << endl;show_image_all_pixel(in_img);   //打印显示图像像素点//创建输出图像vx_image out_img = vxCreateImage(context, width, height, VX_DF_IMAGE_U8);// 创建节点,图像取反操作vx_node n0 = vxNotNode(graph, in_img, out_img);// 验证图,保存图结构status = vxVerifyGraph(graph);// 调度图status = vxScheduleGraph(graph);status = vxWaitGraph(graph);

if (VX_SUCCESS == status){cout << "———————————打印vxNotNode输出图像的所有像素———————————" << endl;show_image_all_pixel(out_img);}

// 释放资源vxReleaseImage(&in_img);vxReleaseImage(&out_img);vxReleaseNode(&n0);vxReleaseGraph(&graph);vxReleaseContext(&context);}

void show_image_all_pixel(vx_image in_img){vx_uint32 width;vx_uint32 height;

vxQueryImage(in_img, (vx_enum)VX_IMAGE_WIDTH, &width, sizeof(vx_uint32));vxQueryImage(in_img, (vx_enum)VX_IMAGE_HEIGHT, &height, sizeof(vx_uint32));

vx_map_id map_id_in;vx_rectangle_t rect_in = {0, 0, width, height};vx_imagepatch_addressing_t map_addr_in;vx_uint8* map_ptr_in;vxMapImagePatch(in_img, &rect_in, 0, &map_id_in, &map_addr_in, (void **)&map_ptr_in, VX_READ_ONLY, VX_MEMORY_TYPE_HOST, VX_NOGAP_X);

printf("/************************************打印图像像素值************************************/\n");volatile vx_uint32 i,j,k;i=j=k=0;for(volatile vx_uint32 y = 0; y < map_addr_in.dim_y; y+=map_addr_in.step_y){j = (map_addr_in.stride_y*y*map_addr_in.scale_y)/VX_SCALE_UNITY;for (volatile vx_uint32 x = 0; x < map_addr_in.dim_x; x+=map_addr_in.step_x){i = j + (map_addr_in.stride_x*x*map_addr_in.scale_x)/VX_SCALE_UNITY;k++;if (0 == k%width){printf("%u\n", *(map_ptr_in+i));}else{printf("%u, ", *(map_ptr_in+i));}}}printf("/************************************打印图像像素值结束************************************/\n");vxUnmapImagePatch(in_img, map_id_in);}

************************************************************************日志*******************************************************************APP: Init … !!!MEM: Init … !!!MEM: Initialized DMA HEAP (fd=4) !!!MEM: Init … Done !!!IPC: Init … !!!IPC: Init … Done !!!REMOTE_SERVICE: Init … !!!REMOTE_SERVICE: Init … Done !!!30433.712534 s: GTC Frequency = 200 MHzAPP: Init … Done !!!30433.712892 s: VX_ZONE_INIT:Enabled30433.712904 s: VX_ZONE_ERROR:Enabled30433.712948 s: VX_ZONE_WARNING:Enabled30433.713889 s: VX_ZONE_INIT:[tivxInitLocal:130] Initialization Done !!!30433.715078 s: VX_ZONE_INIT:[tivxHostInitLocal:93] Initialization Done for HOST !!!———————————打印vxCreateImageFromHandle创建的图像的所有像素———————————/************************************打印图像像素值************************************/0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0/************************************打印图像像素值结束************************************/———————————打印vxNotNode输出图像的所有像素———————————/************************************打印图像像素值************************************/90, 30, 1, 1, 22, 0, 0, 0, 33, 0, 0, 0, 44, 0, 0, 00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0/************************************打印图像像素值结束************************************/30433.719841 s: VX_ZONE_INIT:[tivxHostDeInitLocal:107] De-Initialization Done for HOST !!!30433.724260 s: VX_ZONE_INIT:[tivxDeInitLocal:193] De-Initialization Done !!!APP: Deinit … !!!REMOTE_SERVICE: Deinit … !!!REMOTE_SERVICE: Deinit … Done !!!IPC: Deinit … !!!IPC: DeInit … Done !!!MEM: Deinit … !!!DDR_SHARED_MEM: Alloc's: 1 alloc's of 80 bytesDDR_SHARED_MEM: Free's : 1 free's of 80 bytesDDR_SHARED_MEM: Open's : 0 allocs of 0 bytesDDR_SHARED_MEM: Total size: 536870912 bytesMEM: Deinit … Done !!!APP: Deinit … Done !!!

,

Cherry Zhou:

wang ling said:我有尝试过把opencv创建的图像通过imwrite保存后再通过tivx_utils_create_vximage_from_bmpfile()加载出来,再利用vxNotNode取反操作则结果是正确的呢。

如果在通过此 API 进行写入和加载时得到正确的输出,您是否可以调用"vxMapImagePatch()"到由此生成的 vx_image 并从中读取 image_addr?

然后将此 image_addr 与您正在设置的以下值进行比较,看下是否相同? 

vx_imagepatch_addressing_t addr;addr.dim_x = width;addr.dim_y = height;addr.stride_x = 1;  //Pixel pitch is 1 byte addr.stride_y = 16;//Line spacing is line width * number of pixels bytes, which is 16 * 1 addr.step_x = 1;addr.step_y = 1;addr.scale_x = VX_SCALE_UNITY;addr.scale_y = VX_SCALE_UNITY;void* ptr = img.data;   

,

wang ling:

通过imwrite保存后再通过tivx_utils_create_vximage_from_bmpfile()加载出来的vx_image,调用vxMapImagePatch,并从中读取打印如下值

addr.dim_x = width;addr.dim_y = height;addr.stride_x = 1;  //Pixel pitch is 1 byte addr.stride_y = 16;//Line spacing is line width * number of pixels bytes, which is 16 * 1 addr.step_x = 1;addr.step_y = 1;addr.scale_x = VX_SCALE_UNITY;addr.scale_y = VX_SCALE_UNITY;

void* ptr = img.data;   除了最后一项图像地址外,其他与设定的值都是一样的,保存到本地再加载出来的图像通过vxMapImagePatch出来的地址 ,与opencv创建openvx图像时的地址本来就不一样吧,但这个不应该影响通过vxCreateImageFromHandle创建图后再做节点的取反操作的输出结果呀

,

wang ling:

另外我在通过in_image=vxCreateImageFromHandle(context,VX_DF_IAMGE_U8,&addr,&ptr,VX_MEMORY_TYPE_HOST)设置的mem_typ是VX_MEMORY_TYPE_HOST,但是当我通过vxQueryImage(in_image,(vx_enum)VX_IMAGE_MEMORY_TYPE,&memory_type,sizeof(vx_enum))查询并打印memory_type值却是VX_MEMORY_TYPE_NONE,这点也比较疑惑,是否最终节点的取反操作没有执行是与此处的memory_type没有设置上有关联吗?

期待您的回复,谢谢!!!

,

Cherry Zhou:

都已跟进给工程师,请关注英文论坛的答复。

赞(0)
未经允许不得转载:TI中文支持网 » SK-TDA4VM: opencv创建的图像在TIOVX中进行图像的相关处理
分享到: 更多 (0)