VisionWorks學習之 如何和Opencv交互使用
VisionWorks使用的openVX的擴展,使graph模型,使用方法和習慣上有些不同,Opencv我們經常使用,而且功能很強大,今天來看一下VisionWorks和Opencv如何交叉使用。
首先要了解的就是opencv和OpenVX的數據如何轉換。
數據轉換
VisionWorks已經提供了一個輔助轉換的頭文件 `nvx_opencv_interop.hpp,裏面包含一些轉換工具。
#include <NVX/nvx.h>
#include <NVX/nvx_opencv_interop.hpp>
#include <opencv2/opencv.hpp>
Opencv 數據到OpenVX數據類型轉換
opencv 中所有的數據交互使用的都是cv::Mat, cv::Mat 可以 轉換成vx_matrix 和vx_image。
- Copy cv::Mat to vx_matrix
cv::Mat fundamMat = cv::findFundamentalMat(points1, points2);
vx_matrix vx_fundamMat_1 = vxCreateMatrix(context,VX_TYPE_FLOAT64,3,3);
nvx_cv::CopyCVMatToVXMatrix(fundamMat,vx_fundamMat_1);
//方法二:
vx_matrix vx_fundamMat_2 = nvx_cv::cloneCVMatToVXMatrix(context,fundamMat);
- import cv::Mat or cv::gpu::GpuMat to vx_image
下面的代碼示例演示如何在沒有內存拷貝的情況下將cv::Mat對象導入vx_image對象。vx_image對象指向與cv::Mat相同的像素。代碼在內部使用vxCreateImageFromHandle函數,具有以下限制條件:
- 在vx_image 被釋放之前 cv::Mat 不能先被釋放
- 不允許應用程序直接訪問導入的cv::Mat對象。它必須使用vxMapImagePatch/vxUnmapImagePatch函數。
- 在vx_image被銷燬後,內存的所有權被轉移回源cv::Mat,並且cv::Mat包含最新的像素數據。
下面看一下示例代碼
cv::Mat cv_src = cv::imread(fileNameSrc, cv::IMREAD_GRAYSCALE);
cv::Mat cv_dst(cv_src.size(), cv_src.type());
vx_image vx_src = nvx_cv::createVXImageFromCVMat(context, cv_src);
vx_image vx_dst = nvx_cv::createVXImageFromCVMat(context, cv_dst);
//這之後就不能直接訪問cv::Mat了
vxuBox3x3(context, vx_src, vx_dst);
vxReleaseImage(&vx_src);
vxReleaseImage(&vx_dst);
//VX 釋放了就可以訪問了
cv::imwrite(fileNameDst, cv_dst);
cv_src.release();
cv_dst.release();
cv::Gpu::GpuMat有相同的限制
cv::gpu::GpuMat cv_gpumat(480, 640, CV_8UC1);
vx_image vx_img = nvx_cv::createVXImageFromCVGpuMat(context, cv_gpumat);
// use vx_img
vxReleaseImage(&vx_img);
OpenVX 數據類型轉爲Opencv數據類型
- Copy vx_matrix to cv::Mat
下面的代碼示例演示如何將vx_matrix對象複製到cv::Mat對象中。由於它是副本,cv::Mat對象完全獨立於源vx_matrix對象。
vx_matrix vx_H = vxCreateMatrix(context, VX_TYPE_FLOAT32, 3, 3);
nvxuFindHomography(context, srcPoints, dstPoints, vx_H,
NVX_FIND_HOMOGRAPHY_METHOD_RANSAC, 3, 2000, 10, 0.995, 0.45, NULL);
cv::Mat cv_H;
nvx_cv::copyVXMatrixToCVMat(vx_H, cv_H);
- Map vx_image into cv::Mat or cv::gpu::GpuMat
下面的代碼示例演示如何將vx_image對象映射到cv::Mat對象而不做內存複製。mat對象指向與vx_image對象相同的像素。 nvx_cv::VXImageToCVMatMapper類在內部使用vxMapImagePatch方法,具有以下限制:
- 在調用 nvx_cv::VXImageToCVMatMapper析構函數之前,不能銷燬vx_image對象,因爲析構函數取消映射修補程序。
- 僅只讀模式支持同時映射。
vx_image vx_img = vxCreateImage(context, 640, 480, VX_DF_IMAGE_U8);
{
vx_uint32 plane_index = 0;
vx_rectangle_t rect = {
0u, 0u,
640u, 480u
};
nvx_cv::VXImageToCVMatMapper map(vx_img, plane_index, &rect, VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST);
cv::Mat cv_img = map.getMat();
cv::randu(cv_img, 0, 255);
// nvx_cv::ImageToMatMapper destructor will call unmap internally
}
//這裏之前不能釋放vx_image
// use vx_img
vxReleaseImage(&vx_img);
vx_image 映射到 cv::gpu::GpuMat object
vx_image vx_img = vxCreateImage(context, 640, 480, VX_DF_IMAGE_U8);
{
vx_uint32 plane_index = 0;
vx_rectangle_t rect = {
0u, 0u,
640u, 480u
};
nvx_cv::VXImageToCVMatMapper map(vx_img, plane_index, &rect, VX_WRITE_ONLY, NVX_MEMORY_TYPE_CUDA);
cv::gpu::GpuMat cv_gpuimg = map.getGpuMat();
cv_gpuimg.setTo(cv::Scalar::all(0));
// nvx_cv::ImageToMatMapper destructor will call unmap internally
//這裏對析構函數
}
//這裏之前不能釋放vx_image
// use vx_img
vxReleaseImage(&vx_img);
``