VisionWorks学习之 opencv和VisionWorks Primitives不同点

VisionWorks学习之 opencv和VisionWorks Primitives不同点


下面来看一下opencv和VisionWorks原语的一些不同的地方,算法运算时二者的舍入有些区别,,滤波算法二者对边界的处理不一样,颜色转换使用的颜色标准不一样,VisionWorks需要指定一下颜色空间。自定义卷积有一些区别,积分图像visionWorks计算的小一点,不算边界。然后注意的就是单应矩阵二者差一个转置。下面详细来看一下区别。

算术运算

对于 加法、减法、乘法运行,opencv总是使用SATURATE(饱和)策略,VisionWorks使用SATURATE或者WRAP策略。对于乘法操作,OpenCV始终使用ROUND_TO_NEAREST_EVEN(舍入到偶数)舍入策略,而VisionWorks允许在ROUND_TO_NEAREST_EVEN and ROUND_TO_ZERO (舍入到偶数舍入和舍入到零)舍入策略之间进行选择。

AccumulateWeighted visionworks原语舍入为零,而cv::addWeighted舍入为最接近的值。

滤波操作

VisionWorks图像过滤器(Box3x3、Gaussian3x3等)使用默认VX_BORDER_MODE_UNDEFINED,这意味着边界上的像素可能计算不准确。opencv总是使用一些边界外推方法。使用VX_BORDER_MODE_CONSTANT的方法和cv::BORDER_CONSTANT使用一样的处理方法,使用VX_BORDER_MODE_REPLICATE和cv::BORDER_REPLICATE使用一样的处理方法,VisionWorks没有cv::BORDER_REFLECT, cv::BORDER_REFLECT101 以及 cv::BORDER_WRAP.类似项。

颜色转换

VisionWorks默认使用BT.709颜色空间,而OpenCV使用BT.601如果没有显式地将bt.601用于visionworks图像,则在rgb[x]>Gray转换中会产生不同的结果。

cv::Mat cv_src = cv::imread(fileName, cv::IMREAD_COLOR);
cv::cvtColor(cv_src, cv_src, cv::COLOR_BGR2RGB);
// OpenCV
cv::Mat cv_dst_original;
cv::cvtColor(cv_src, cv_dst_original, cv::COLOR_RGB2GRAY);
// VisionWorks
cv::Mat cv_dst_nvx(cv_src.size(), CV_8UC1);
vx_image vx_src = nvx_cv::createVXImageFromCVMat(context, cv_src);
vx_image vx_dst = nvx_cv::createVXImageFromCVMat(context, cv_dst_nvx);
vx_enum color_space = VX_COLOR_SPACE_BT601_625;
vxSetImageAttribute(vx_src, VX_IMAGE_ATTRIBUTE_SPACE, &color_space, sizeof(color_space));
vxSetImageAttribute(vx_dst, VX_IMAGE_ATTRIBUTE_SPACE, &color_space, sizeof(color_space));
vxuColorConvert(context, vx_src, vx_dst);
vxReleaseImage(&vx_src);
vxReleaseImage(&vx_dst);

自定义卷积

OpenCV cv::filter2D函数和VisionWorks卷积原语使用不同的公式。
在这里插入图片描述
为了导入使用cv::filter2d的opencv代码,必须反转内核并将其转换为16s类型:

cv::Mat cv_src = cv::imread(fileName, cv::IMREAD_GRAYSCALE);
cv::Mat cv_kernel = getFilterKernel();
// OpenCV code
cv::Mat cv_dst_original(cv_src.size(), cv_src.type());
cv::filter2D(cv_src, cv_dst_original, CV_8U, cv_kernel, cv::Point(-1, -1), 0, cv::BORDER_REPLICATE);
// VisionWorks code
cv::Mat cv_dst_nvx(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_nvx);
vx_uint32 conv_scale = 1024;
cv::Mat vx_kernel;
cv::flip(cv_kernel, vx_kernel, -1);
vx_kernel.convertTo(vx_kernel, CV_16S, conv_scale);
vx_convolution conv = vxCreateConvolution(context, vx_kernel.cols, vx_kernel.rows);
vxWriteConvolutionCoefficients(conv, vx_kernel.ptr<vx_int16>());
vxSetConvolutionAttribute(conv, VX_CONVOLUTION_ATTRIBUTE_SCALE, &conv_scale, sizeof(conv_scale));
vx_border_t border;
border.mode = VX_BORDER_MODE_REPLICATE;
vxSetContextAttribute(context, VX_CONTEXT_ATTRIBUTE_IMMEDIATE_BORDER_MODE, &border, sizeof(border));
vxuConvolve(context, vx_src, conv, vx_dst);
vxReleaseImage(&vx_src);
vxReleaseImage(&vx_dst);
vxReleaseConvolution(&conv);

图像积分

在这里插入图片描述

图像扭曲

VisionWorks WarpAffine and WarpPerspective原语的行为类似于具有cv::WARP_INVERSE_MAP标志的cv::warpAffine and cv::warpPerspective,要将cv::warpAffine or cv::warpPerspective 调用移植到visionworks,必须对转换矩阵进行转置:

// x1 = a * x + b * y + c;
// y1 = d * x + e * y + f;
cv::Mat cv_src = cv::imread(fileName, cv::IMREAD_GRAYSCALE);
// OpenCV
float cv_mat_data[2][3] = {
    {a, b, c},
    {d, e, f}
};
cv::Mat cv_mat(2 /* rows */, 3 /* cols */, CV_32FC1, cv_mat_data);
cv::Mat cv_dst_original;
cv::warpAffine(cv_src, cv_dst_original, cv_mat, cv_src.size(), cv::INTER_LINEAR | cv::WARP_INVERSE_MAP);
// VisionWorks
vx_image vx_src = nvx_cv::createVXImageFromCVMat(context, cv_src);
vx_image vx_dst_1 = vxCreateImage(context, cv_src.cols, cv_src.rows, VX_DF_IMAGE_U8);
vx_float32 vx_mat_data[3][2] = { //这个是cv_mat_data的转置
    {a, d}, // 'x' coefficients
    {b, e}, // 'y' coefficients
    {c, f}, // 'offsets'
};
vx_matrix vx_mat_1 = vxCreateMatrix(context, VX_TYPE_FLOAT32, 2 /* cols */, 3 /* rows */);
vxWriteMatrix(vx_mat_1, vx_mat_data);
vxuWarpAffine(context, vx_src, vx_mat_1, VX_INTERPOLATION_TYPE_BILINEAR, vx_dst_1);
// or
vx_image vx_dst_2 = vxCreateImage(context, cv_src.cols, cv_src.rows, VX_DF_IMAGE_U8);
vx_matrix vx_mat_2 = nvx_cv::cloneCVMatToVXMatrix(context, cv_mat.t());
vxuWarpAffine(context, vx_src, vx_mat_2, VX_INTERPOLATION_TYPE_BILINEAR, vx_dst_2);

Homography

visionworks FindHomography原语返回Homography matrix,这个矩阵适用于visionworks WarpPerspective原语的格式。所以要在opencv中使用单应矩阵(Homography matrix),必须对其进行转置:

vx_matrix vx_H = vxCreateMatrix(context, VX_TYPE_FLOAT32, 3, 3);
nvxuFindHomography(context, srcPoints, dstPoints, vx_H, NVX_FIND_HOMOGRAPHY_METHOD_RANSAC,
                   3.0f, 2000, 10, 0.995f, 0.45f, nullptr);
cv::Mat cv_H;
nvx_cv::copyVXMatrixToCVMat(vx_H, cv_H);
cv_H = cv_H.t(); //使用之前需要转置一下
cv::warpPerspective(cv_src, cv_dst, cv_H, cv_dst.size());

这里主要还是说的是Opencv和VisionWorks交互的时候注意的事项。后面两个图像扭曲和单应矩阵两者差一个转置,使用时注意一下即可。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值