OpenCL 通用编程与优化(17)
9.3.3绝对差和(SAD)和平方差和(SSD)
块匹配操作度量目标图像中的块与参考图像中的参考块的相关性(或相似性)。有两个误差度量用于测量两个图像块的相关性:绝对差值之和(SAD)和平方差值之和(SSD)。
假设有两个候选块A和B,我们想知道哪个块最匹配块R。通过计算A和R之间,以及B和R之间的SAD,我们可以选择导致误差最小的块,或SAD值最小的块。这可以推广到搜索参考块R跨越N个目标块的最小SAD值。这两个功能的定义如下:
float4 qcom_block_match_sadf(image2d_t target_image, sampler_t sampler,
float2 coord, uint2 region, image2d_t reference_image, uint2
reference_coord);
float4 qcom_block_match_ssdf(image2d_t target_image, sampler_t sampler,
float2 coord,uint2 region, image2d_t reference_image, uint2
reference_coord);
这两个函数与本节中的卷积和盒滤波器操作具有相似的要求。此外,分别指定图像上的目标块和参考块大小的区域和rebice_coord必须是整数。有关更多细节和代码示例,请参阅Adreno OpenCL SDK文档。
9.3.4双极滤波器
除了在OpenCL标准中定义的过滤模式,如CLK_FILTER_LINEAR或CLK_FILTER_NEAREST,在新的Adrenogpu中添加了一个名为CL_FILTER_BICUBIC_QCOM的新过滤模式,允许开发人员使用硬件加速的双边插值。要使用这个特性,在内核中需要一个名为cl_qcom_filter_bicubic启用的实用功能。使用滤波模式QCOM_CLK_FILTER_BICUBIC,图像读取函数read_imagef返回4x4平方的图像元素的加权平均值。给定一个二维图像的输入坐标(x,y),得到的4x4方块如下:
Let
x0 = (int) floor(x - 1.5f);
x1 = x0 + 1;
x2 = x1 + 1;
x3 = x2 + 1;
and
y0 = (int) floor(y - 1.5f);
y1 = y0 + 1;
y2 = y1 + 1;
y3 = y2 + 1;
and
a = frac(x - 0.5f);
b = frac(y - 0.5f);
where frac(x) denotes the fractional part of x and is computed as x - floor(x). Then,
the weights are calculated as follows:
w_u0 = - 0.5f * a + 1.0f * (a * a) - 0.5f * (a * a * a);
w_u1 = 1.0f - 2.5f * (a * a) +1.5f * (a * a * a);
w_u2 = 0.5f * a + 2.0f * (a * a) - 1.5f * (a * a * a);
w_u3 = - 0.5f * (a * a) + 0.5f * (a * a * a);
and
w_v0 = - 0.5f * b + 1.0f * (b * b) - 0.5f * (b * b * b);
w_v1 = 1.0f - 2.5f * (b * b) + 1.5f * (b * b * b);
w_v2 = 0.5f * b + 2.0f * (b * b) - 1.5f * (b * b * b);
w_v3 = -0.5f * (b * b) + 0.5f * (b * b * b);
计算出的图像元素值如下:
refOut = ((t00*w_v0 + t01*w_v1+ t02*w_v2 + t03*w_v3) * w_u0 +
(t10*w_v0 + t11*w_v1+ t12*w_v2 + t13*w_v3) * w_u1 +
(t20*w_v0 + t21*w_v1+ t22*w_v2 + t23*w_v3) * w_u2 +
(t30*w_v0 + t31*w_v1+ t32*w_v2 + t33*w_v3) * w_u3);
其中,txy是二维图像中位置(x、y)处的图像元素。如果上述方程中选择的任何一个txy是指图像之外的位置,则使用边框颜色作为txy的颜色值。有关如何使用此特性的示例,请参阅规范扩展。
双曲面算法的内置硬件加速度精度有限。因此,在使用应用程序时,检查其精度要求是很重要的。
9.3.5增强型矢量图像操作
在标准的OpenCL中,图像读写函数,如read_imagef/write_imagef,并且在一个操作中只能读写一个像素(一个或多个组件,取决于图像格式)。这个扩展引入了一组新的OpenCL内置函数,它允许在单个操作中读取和写一组OpenCL图像元素。它们允许应用程序跨多个图像元素读取或写出单个组件。因此,它们被称为矢量图像操作,并可以提供潜在的性能增益和易于开发。
内置函数跨一系列输入图像格式,它们的名称表示返回值的数据类型及其访问模式。
9.3.5.1 2x2读取
qcom_read_imageX_2x2操作从输入图像中读取出以2x2向量形式存在的四个元素:
float4 qcom_read_imagef_2x2(image2D_t image, sampler_t sampler, float2
coord, int compid);
half4 qcom_read_imageh_2x2(image2D_t image, sampler_t sampler, float2
coord, int compid);
uint4 qcom_read_imageui_2x2(image2D_t image, sampler_t sampler, float2
coord, int compid);
int4 qcom_read_imagei_2x2(image2D_t image, sampler_t sampler, float2
coord, int compid);
由指定的基点是这个向量的左上角。元素[0]是左下角的元素。四个输出元素从2x2向量中的元素[0]开始按逆时针方向排列。具体来说,元素[1]为右下角,元素[2]为右上角,元素[3]为左上角(基点),如图9-5所示。
图9-5 2x2矢量图像读取
9.3.5.2 4x1读取
qcom_read_imageX_4x1操作从输入图像中读取出以4x1向量形式存在的四个元素:
float4 qcom_read_imagef_4x1(image2d_t image, sampler_t sampler, float2
coord, int compid);
half4 qcom_read_imageh_4x1(image2d_t image, sampler_t sampler, float2
coord, int compid);
uint4 qcom_read_imageui_4x1(image2d_t image, sampler_t sampler, float2
coord, int compid);
int4 qcom_read_imagei_4x1(image2d_t image, sampler_t sampler, float2
coord, int compid);
将element[0]表示为位于基点<坐标系>处的元素。这四个输出元素从4x1向量中的element[0]开始,从左到右依次排序。具体地说,element[0]是最左边的元素,其次是element[1]、element[2]和element[3]。
图9-6 4x1矢量图像读取