【OPENVX】vx_image 与 cv::Mat 相互转换

  • 头文件
    #include <stdio.h>
    #include <stdlib.h>
    #include <opencv2/opencv.hpp>
    #include "VX/vx.h"
    
    // 函数名称
    #ifdef DEBUG
    #define DEBUG_FUNCTION_NAME(void)                                                     \
        {                                                                                 \
            printf("================================================================\n"); \
            printf("%s\n", __func__);                                                     \
        }
    
    #define DEBUG_LOG(format, ...)                                                      \
        {                                                                               \
            printf("[%s:%d->%s] " format, __FILE__, __LINE__, __func__, ##__VA_ARGS__); \
        }
    #else
    #define DEBUG_FUNCTION_NAME(void)
    #define DEBUG_LOG(format, ...)
    #endif
    
    static inline vx_image vxCvMatToVxImage(const vx_context context, const cv::Mat &cv_image)
    {
        DEBUG_FUNCTION_NAME();
    
        // 图像类型
        vx_df_image vx_image_type;
        switch (cv_image.type())
        {
        case CV_8UC1:
            vx_image_type = VX_DF_IMAGE_U8;
            break;
        case CV_8UC3:
            vx_image_type = VX_DF_IMAGE_RGB;
            break;
        default:
            DEBUG_LOG("Format %d not supported\n", vx_image_type);
    
            return NULL;
        }
    
        // 图像属性
        int width = cv_image.cols;
        int height = cv_image.rows;
    
        // 创建图像
        vx_image image = vxCreateImage(context, width, height, vx_image_type);
    
        // 区域
        vx_rectangle_t patch;
        patch.start_x = 0;
        patch.start_y = 0;
        patch.end_x = width;
        patch.end_y = height;
    
        vx_map_id map_id;
        vx_imagepatch_addressing_t addr;
        unsigned char *ptr;
        vx_status status = vxMapImagePatch(image, &patch, 0, &map_id, &addr, (void **)&ptr, VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST, VX_NOGAP_X);
        if (status != VX_SUCCESS)
        {
            DEBUG_LOG("vxMapImagePatch returned error with code %d\n", status);
            return NULL;
        }
    
        if (addr.stride_x != 1 && addr.stride_x != 3)
        {
            DEBUG_LOG("addressing structure not supported, stride_x = %d\n", addr.stride_x);
            return NULL;
        }
    
        for (int y = 0; y < height; y++)
        {
            unsigned char *ptr_y = ptr + y * addr.stride_y;
            memcpy(ptr_y, cv_image.ptr(y), addr.stride_y);
        }
    
        status = vxUnmapImagePatch(image, map_id);
        if (status != VX_SUCCESS)
        {
            DEBUG_LOG("vxUnmapImagePatch failed...\n");
            return NULL;
        }
    
        return image;
    }
    
    static inline int vxVxImageToCvMat(const vx_image image, cv::Mat &cv_image)
    {
        DEBUG_FUNCTION_NAME();
    
        // 图像属性
        vx_uint32 width = 0;
        vx_uint32 height = 0;
        ERROR_CHECK_STATUS(vxQueryImage(image, VX_IMAGE_WIDTH, &width, sizeof(width)));
        ERROR_CHECK_STATUS(vxQueryImage(image, VX_IMAGE_HEIGHT, &height, sizeof(height)));
    
        // 图像类型
        vx_df_image image_type;
        ERROR_CHECK_STATUS(vxQueryImage(image, VX_IMAGE_FORMAT, &image_type, sizeof(image_type)));
    
        int cv_image_type;
        switch (image_type)
        {
        case VX_DF_IMAGE_U8:
            cv_image_type = CV_8UC1;
            break;
        case VX_DF_IMAGE_RGB:
            cv_image_type = CV_8UC3;
            break;
        default:
            DEBUG_LOG("Format %d not supported\n", cv_image_type);
            return -1;
        }
    
        // 区域
        vx_rectangle_t patch = {0, 0, width, height};
        vx_map_id map_id;
        vx_imagepatch_addressing_t addr;
        unsigned char *ptr;
        vx_status status = vxMapImagePatch(image, &patch, 0, &map_id, &addr, (void **)&ptr, VX_READ_ONLY, VX_MEMORY_TYPE_HOST, VX_NOGAP_X);
        if (status != VX_SUCCESS)
        {
            DEBUG_LOG("vxMapImagePatch returned error with code %d\n", status);
            return -1;
        }
    
        if (addr.stride_x != 1 && addr.stride_x != 3)
        {
            DEBUG_LOG("addressing structure not supported, stride_x = %d\n", addr.stride_x);
            return -1;
        }
    
        cv_image = cv::Mat(height, width, cv_image_type);
        for (int y = 0; y < height; y++)
        {
            unsigned char *ptr_y = ptr + y * addr.stride_y;
            memcpy(cv_image.ptr(y), ptr_y, addr.stride_y);
        }
    
        status = vxUnmapImagePatch(image, map_id);
        if (status != VX_SUCCESS)
        {
            DEBUG_LOG("vxUnmapImagePatch failed...\n");
            return -1;
        }
    
        return 0;
    }
    
    static inline vx_image ReadImage(vx_context context, const char *file_name)
    {
        cv::Mat mat = cv::imread(file_name, cv::IMREAD_ANYCOLOR);
        return vxCvMatToVxImage(context, mat);
    }
    
    static inline void SaveImage(vx_image image, const char *file_name)
    {
        cv::Mat mat;
        int ret = vxVxImageToCvMat(image, mat);
        if (!ret)
            cv::imwrite(file_name, mat);
    }
    
    static inline void DisplayImage(vx_image image, const char *window_name, int time = 0)
    {
        cv::Mat mat;
        int ret = vxVxImageToCvMat(image, mat);
        if (!ret)
        {
            cv::namedWindow(window_name, cv::WINDOW_NORMAL);
            cv::resizeWindow(window_name, 800, 600);
            cv::imshow(window_name, mat);
            cv::waitKey(time);
        }
    }
    
  • 测试
    int main(int argc, char* argv[])
    {
        vx_context context = vxCreateContext();
        vx_image image = ReadImage(context, "./images/image.jpg");
        DisplayImage(image, "test");
        SaveImage(image, "test.png");
    
        return EXIT_SUCCESS;
    }
    
  • 效果
    在这里插入图片描述
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhy29563

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值