OpenVX™ 是一种开放的、免版税的标准,用于计算机视觉应用程序的跨平台加速。 OpenVX 支持性能和功耗优化的计算机视觉处理,这在嵌入式和实时用例中尤其重要,例如面部、身体和手势跟踪、智能视频监控、高级驾驶辅助系统 (ADAS)、对象和场景重建、增强现实、 目视检查、机器人技术等。
从图中可以看出使用OPENVX库可以直接和底层的处理器硬件计算相关联,效率比较高。
经常和项目开发人员沟通,很多开发人员习惯了使用CUDA ,更换GPU平台后很难适应。也有习惯使用Opencv加速库,基本都要求GPU支持OPENCV加速。很少人会直接使用Opencl和Openvx编程使用GPU加速。但是时间直接使用Opencl和Openvx编程使用GPU加速会比使用OPENCV效率高,但是直接使用Opencl和Openvx编程难度会更大,需要学习跟多的知识。个人认为AMD、INTEL 、高通等巨头一起搞出个Openvx,就是有意去挑战CUDA的地位,虽然现在还是差距比较大,很多人都不知道这个东西。
本文章不打算介绍过多的Openvx的环境搭建,只是对本人在学习Openvx编程过程中,记录一下个人的理解和说明。 有需求需要使用GPU进行图像旋转,GPU支持Openvx一开始搜索"rotation","rotate"关键字并没有找到相关Openvx的库函数。在网上搜索相关资料也较少,偶然间搜索到Intel有相关文章介绍,对开发有所启发。https://www.intel.com/content/www/us/en/develop/documentation/sample-color-copy/top/color-copy-pipeline/color-copy-pipeline-the-scan-pre-process-openvx-graph.html
Intel网站上没有介绍如何变成如何使用,查询到Openvx相关代码如下: https://www.khronos.org/registry/OpenVX/specs/1.1/html/d5/d5f/group__group__vision__function__warp__affine.html#ga20a2da1dbdb9caaf9d519840402b3a17
需要注意的是上面链接的“specs/1.1/”,该部分是Openvx版本信息如果版本不兼容代码可能不一致,需要确定编译环境的版本和程序兼容。
// x0 = a x + b y + c;
// y0 = d x + e y + f;
/*
{a, d}, // 'x' coefficients
{b, e}, // 'y' coefficients
{c, f}, // 'offsets'
*/
vx_float32 mat[3][2] = {
{1, -0.5}, // 'x' coefficients
{0.5, 1}, // 'y' coefficients
{-100, 100}, // 'offsets'
};
vx_matrix matrix=vxCreateMatrix(ContextVX,VX_TYPE_FLOAT32,2,3);//新建矩阵2row 3
vxCopyMatrix(matrix,mat,VX_WRITE_ONLY,VX_MEMORY_TYPE_HOST);//将数组拷贝到矩阵
status=vxuWarpAffine(ContextVX,imgObj[1],matrix,VX_INTERPOLATION_NEAREST_NEIGHBOR,imgObj[0]);
if(VX_SUCCESS!=status){
printf("vxuWarpAffine status %d \n",status);
}
//VX_INTERPOLATION_TYPE_NEAREST_NEIGHBOR-> VX_INTERPOLATION_NEAREST_NEIGHBOR
//输出值被定义为匹配中心最接近样本位置的源像素。
//VX_INTERPOLATION_TYPE_BILINEAR-> VX_INTERPOLATION_BILINEAR
//输出值由中心最接近样本位置的像素之间的双线性插值定义,由样本与像素中心的距离线性加权。 */
我们使用一个原始图像如下:
程序是通过vx_float32 mat[3][2] 的参数进行X,Y 轴的坐标对应变化的。他们的坐标关系在程序前由提示。实际上就是一个坐标系转换,如果值设置如果数组的 'x' coefficients, 'y' coefficients值设置较大,图像将会缩小,设置值较小图像将会拉大。坐标系X,Y的0点事左下角。
设置
vx_float32 mat[3][2] = {
{0, 1.5}, // ‘x’ coefficients
{1.5, 0}, // ‘y’ coefficients
{0, 0}, // ‘offsets’
};
程序中设置了图像点:
X(转换后点像素)=1.5Y (转换前点像素)
Y(转换后点像素)=1.5X (转换前点像素)
图像编程了一个90度旋转,缩小了1.5倍的图。
设置
vx_float32 mat[3][2] = {
{1, 0.5}, // ‘x’ coefficients
{0.5, 1}, // ‘y’ coefficients
{0, 0}, // ‘offsets’
};
程序中设置了图像点:
X(转换后点像素)=X+0.5*Y (转换前点像素)
Y(转换后点像素)=0.5X+Y (转换前点像素)
图像是个旋转30度的有所缩小的图。
设置
vx_float32 mat[3][2] = {
{1, 0.5}, // ‘x’ coefficients
{0.5, 1}, // ‘y’ coefficients
{-100, 100}, // ‘offsets’
};
程序中设置了图像点:
X(转换后点像素)=X+0.5*Y (转换前点像素)
Y(转换后点像素)=0.5X+Y (转换前点像素)
图像是个旋转30度,并X轴向右上平移100像素的有所缩小的图。
对于参数中的VX_INTERPOLATION_TYPE_NEAREST_NEIGHBOR输出值被定义为匹配中心最接近样本位置的源像素。和VX_INTERPOLATION_TYPE_BILINEAR输出值由中心最接近样本位置的像素之间的双线性插值定义,由样本与像素中心的距离线性加权。主要是影响图片的细节质量,使用VX_INTERPOLATION_BILINEAR的细节较为平滑,而另一种细节会有明显的锯齿效果。