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);
}