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。

  1. 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);
  1. 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數據類型

  1. 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);
  1. 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);
``
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章