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