VisionSDK UMat

本文深入探讨了VSDK中的UMat数据结构,它是图像处理的基本单元,与OpenCV的UMat相似但并非直接继承。文章详细讲解了UMat的创建、与Mat之间的转换,以及在不同内存银行的分配策略,提供了丰富的代码示例。

1.图像的基本操作单元

vsdk::UMat是VSDK中用于保存图像的数据结构,是整个图像相关处理的基本单元,该结构概念来源于OpenCV中的cv::UMat但并不是对cv::UMat的继承,所以虽然二者并不相同,但用法基本相同。

这种UMat和Mat结构从使用角度来看,就是将一张图像以矩阵的形式进行存储(内存中是线性的)和操作,每一个像素对应一个数值,类似于普通的RGB图像,像素值可以指定不同的数据类型(uchar、float、int、double)。

  • 构建vsdk::UMat需要指定大小和类型用于分配相应的存储空间
  • vsdk::UMat创建的buffer并不是虚拟内存空间映射,它使用了完全的DMA读取内存(关于这一点本人十分疑惑,因为由于这个特性我在编程编程中遇到多次不同程序读取到了同一张内存中的图片,这就导致了内存安全问题,A程序可以访问到B程序中的数据)
  • 与cv::UMat相同,用户不能对vsdk::UMat中的存储内容进行操作,如果要用处理器进行访问UMat数据,则需将vsdk::UMat转换成vsdk::Mat并在相应的参数中放入相应的flag
/* Standard allocation */
vsdk::UMat matrix0(HEIGHT, WIDTH, VSDK_CV_8UC3);

/* Allocation with forced memory bank
DDR0, DDR1, Single banked SRAM, Multi banked SRAM */
vsdk::UMat matrix1(HEIGHT, WIDTH, VSDK_CV_16SC1, vsdk::USAGE_DDR0);
vsdk::UMat matrix2(HEIGHT, WIDTH, VSDK_CV_32SC3, vsdk::USAGE_DDR1); 
vsdk::UMat matrix3(HEIGHT, WIDTH, VSDK_CV_8SC2, vsdk::USAGE_SSRAM); 
vsdk::UMat matrix4(HEIGHT, WIDTH, VSDK_MAKETYPE(CV_8S, 8), vsdk::USAGE_MSRAM);

2.UMat -> Mat

将vsdk::UMat转换为vsdk::Mat时,将会创建一个特殊的虚拟内存映射供处理器访问.

一个vsdk::UMat可以创建多个vsdk::Mat,但必须设置相同的cache,否则将创建一个空的矩阵,使用如果创建Mat时使用了不同的cache标志,之后就都是对空图像进行操作。

每一个Mat矩阵在创建和销毁都会增加和减少引用计数。

vsdk::UMat umat(HEIGHT, WIDTH, VSDK_CV_8UC3);

/* Standard mapping & access */
{
// OK
vsdk::Mat mat0 = umat.getMat(vsdk::ACCESS_RW | OAL_USAGE_CACHED);

// OK, creates second matrix, shared buffer!
vsdk::Mat mat1 = umat.getMat(vsdk::ACCESS_RW | OAL_USAGE_CACHED);

// NOT OK, fails because there are existing different mappings!
vsdk::Mat mat2 = umat.getMat(vsdk::ACCESS_RW | OAL_USAGE_NONCACHED);

// access of elements
int8_t *ptr = mat0.data;
mat0.at<vsdk::Vec3u>(j, i)[0] = VALUE; 
}
/* During the end block, all mats are destroyed, so the memory buffer is flushed */

{
// Now it's OK, it remaps the buffer since there is no cached mapping.
vsdk::Mat mat0 = umat.getMat(vsdk::ACCESS_RW | OAL_USAGE_NONCACHED); 
}

/* Direct access without keeping the mat */
umat.getMat(ACCESS_WRITE | OAL_USAGE_NONCACHED).at<uint8_t>(0) = VALUE;

3.各种转换

  • cv::Mat -> vsdk::UMat

vsdk::UMat vsdkumat(HEIGHT, WIDTH, VSDK_CV_8UC3); 
cv::Mat cvmat(HEIGHT, WIDTH, CV_8UC3);

vsdkumat = cvmat.getUMat(cv::ACCESS_READ);
  • cv::Mat -> vsdk::Mat

vsdk::Mat vsdkmat(HEIGHT, WIDTH, VSDK_CV_8UC3); 
cv::Mat cvmat(HEIGHT, WIDTH, CV_8UC3);

vsdkmat = cvmat;
  • vsdk::Mat -> cv::Mat

vsdk::Mat vsdkumat(HEIGHT, WIDTH, VSDK_CV_8UC3); 
cv::Mat cvmat(HEIGHT, WIDTH, VSDK_CV_8UC3);

cvmat = (cv::Mat)vsdkmat;
  • cv::Mat -> cv::UMat

cv::UMat cvumat(HEIGHT, WIDTH, CV_8UC3); 
cv::Mat cvmat(HEIGHT, WIDTH, CV_8UC3);

cvumat = cvmat.getUMat(cv::ACCESS_READ);
  • vsdk::UMat -> vsdk::Mat

vsdk::UMat vsdkumat(HEIGHT, WIDTH, VSDK_CV_8UC3); 
vsdk::Mat vsdkmat(HEIGHT, WIDTH, VSDK_CV_8UC3);

vsdkmat = vsdkumat.getMat(vsdk::ACCESS_RW | OAL_USAGE_CACHED);

4.UMat简单使用

// read the image via OpenCV, internally convert to vsdk UMat
// during conversion, the non-OAL memory is detected, UMat allocates OAL Memory and //copies data to be used in vsdk

vsdk::UMat image = cv::imread("in_color_256x256.png", CV_LOAD_IMAGE_COLOR).getUMat(cv::ACCESS_RW);

if (!image.empty()) {
    // Init the rest of ports
    vsdk::UMat out(image.rows, image.cols, VSDK_CV_8UC3);
    vsdk::UMat dataThreshold(1, 1, VSDK_CV_8UC1); 
    vsdk::UMat dataMarkColorChannel(1, 1, VSDK_CV_8UC1);

    // Init the algorithm parameters. Note the Mat is created just for this
    // call,
    // it's destroyed afterwards and flushed dataThreshold.getMat(OAL_USAGE_CACHED).at<unsigned char>(0) = THRESHOLD;           dataMarkColorChannel.getMat(OAL_USAGE_CACHED).at<unsigned char>(0) =

    // Init the ACF process
    APU_FAST9_COLOR process;
    lRetVal |= process.Initialize();
    lRetVal |= process.ConnectIO("INPUT", image); 
    lRetVal |= process.ConnectIO("THRESHOLD", dataThreshold); 
    lRetVal |= process.ConnectIO("MARK_COLOR_CHANNEL", dataMarkColorChannel);
    lRetVal |= process.ConnectIO("OUTPUT", out);
    // execute
    lRetVal |= process.Start();
    lRetVal |= process.Wait(); 
 
    // Save the output
    cv::imwrite("out_color_256x256.png", (cv::UMat)out);
 }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值