发明内容
本发明的目的在于克服上述已有技术的不足,提出一种用GPU通过分块实现快速小波变换的方法。本发明通过将图像分块并存入共享内存中,实现高速的数据存取。为了保证结果的正确性,本发明将每个图像块按其周围实际像素进行了扩展。本发明确保每个图像块的行变换与列变换都在共享内存中完成,避免数据在变换过程中与全局内存的交互。
为了实现上述目的,本发明的方法包括如下步骤:
(1)拷贝原始图像:
在图形处理单元GPU中分配两块全局内存A和B,将原始图像拷贝到全局内存A中;
(2)数据分块:
将原始图像按照二维网格的方式分成宽24像素、高24像素的图像块;
(3)数据扩展:
将每个图像块向其四周方向各延伸四个像素,处于边缘不能延伸的,则进行对称扩展,得到扩展图像块;
(4)拷贝数据到共享内存:
4a)在图形处理单元GPU中分配与扩展图像块个数相同的block,每个block对应一个扩展图像块;
4b)为每个block分配大小为33乘32的共享内存以及32乘32个线程;
4c)将每个扩展图像块拷贝到与其对应的block的共享内存中,每个线程完成一个像素点的拷贝,并将共享内存中每一行的最后一个存储空间保留不用;
(5)行变换:
对于每个block,使用其中的32个线程对共享内存中的数据进行行变换,每个线程完成扩展像素块的一行数据的变换;
(6)列变换:
对于每个block,使用其中的32个线程对共享内存中的数据进行列变换,每个线程完成扩展像素块的一列数据的变换;
(7)取消数据扩展:
对于每个block,将变换后的扩展图像块上下各四行、左右各四列的数据排除,得到一个24乘24的数据块;
(8)拷贝数据块:
8a)将每个block的数据块拷贝到全局内存B中,拷贝的过程中进行尺度变换;
8b)待所有的block拷贝完成后,将全局内存B中的数据拷贝至主机内存中,释放图形处理单元GPU中的两块全局内存A和B。
本发明与现有技术相比较,具有如下优点:
第一,由于本发明采用了重叠的扩展图像块来对原始图像进行分别处理,克服了现有技术简单地对图像分块导致的结果不精确的问题,使得本发明可以保证小波变换结果的准确性。
第二,由于本发明在图形处理单元GPU的高速共享内存中处理扩展图像块,使得每个图像块的数据都具有了更高的存取速度。
第三,由于本发明中行变换和列变换都在共享内存中进行,有效地避免了现有技术将行变换后的数据送回全局内存的操作,节省了处理时间。
第四,由于本发明采用了扩展图像块与扩展图像块之间、每个扩展图像块内部各个像素之间的并行处理,因此可以达到更快的处理速度。
第五,由于本发明将数据的对称扩展过程隐藏在数据的拷贝过程中,从而避免了大部分线程等待某个线程进行对称扩展操作的情况。
具体实施方式
本发明采用计算统一设备架构(Compute Unified Device Architecture CUDA)语言,可以在NVIDIA的任何一款支持计算统一设备架构CUDA的图形处理单元GPU设备上实现。
参照图1,本发明可通过以下步骤实现:
步骤1,在图形处理单元GPU中分配两段全局内存用于存放原始图像和变换后的小波系数,分别记为A,B,将原始图像拷贝到内存区域A中。在图形处理单元GPU中分配全局内存使用计算统一设备架构CUDA语言提供的函数cudaMalloc2D实现;数据从计算机主机内存到图形处理单元GPU全局内存的拷贝使用计算统一设备架构CUDA语言提供的函数cudaMemcpy2D来实现。
步骤2,将原始图像按照二维网格的方式分成宽度为24像素,高度为24像素的图像块。根据原始图像的宽度和高度,可以通过下式计算出宽度方向上图像块的个数和高度方向上图像块的个数,进而计算出总的像素块的个数:
T=M*N
其中,M表示宽度方向上图像块的个数,W表示原始图像的宽度,N表示高度方向上图像块的个数,H表示原始图像的高度,T表示总的图像块的个数,/表示保留小数的除法的符号,表示将除法结果向上取整的符号,*表示整数乘法的符号。
由于原始图像的宽度和高度不一定是24的整数倍,所以在最右方或最下方有可能存在宽度或高度不是24的图像块。对这些图像进行对称扩展,使其成为24乘24大小的图像块。
步骤3,将每个图像块向其四周各个方向各延伸四个像素构成扩展图像块。由于最左边的图像块无法向左延伸,对这些图像块的所有行向左对称扩展。由于类似的原因,最右边的图像块所有行向右对称扩展,最上面的图像块所有列向上对称扩展,最下面的图像块所有列向下对称扩展。这种获得扩展图像块的方法可以保证基于分块的小波变换和基于行和列的小波变换产生相同结果,同时还可以避免分块效应。扩展图像块的大小为32乘32。
步骤4,通过以下步骤实现将扩展图像块拷贝到共享内存。
第一步,在图形处理单元GPU中分配与图像块个数相同的block,每个block对应一个扩展图像块。
第二步,为每个block分配大小为33乘32的共享内存以及32乘32个线程。
第三步,将每个扩展图像块拷贝到与其对应的block的共享内存中,每个线程完成一个像素点的拷贝,并将共享内存中每一行的最后一个存储空间保留不用。
本发明是通过将共享内存的宽度设为33,来获得更高的共享内存访问速度的。在图形处理单元GPU中每个block的共享内存被分成了32个bank,而不同的bank中的数据可以被同时访问。因此在设计每个扩展图像块存储方式的时候,应当满足两个条件:第一,同一行的不同数据应存放在不同的bank中;第二,同一列的不同数据应当存放在不同的bank中。由于相邻的存储单元属于不同的bank,同一行的32个数据便处于不同的bank中。对共享内存每一行最后一个存储空间保留不用,使共享内存的宽度变为33,可以保证每一列的元素处于不同的bank中。
步骤5,行变换。
对于每个block,使用32个线程对共享内存中的数据进行行变换。由于32个线程同时处理扩展图像块的32行数据,当每一行中的一个数据被处理时,和这个数据同一列的其他行的数据也会被其他线程同时处理。步骤4中设计的存储格式有效保证了每一列数据访问的效率。
行变换的提升过程如下所示:
其中,d代表行变换的奇数项,s代表行变换的偶数项,α,β,γ,δ代表上述四步中各步提升过程的提升因子,其具体值分别为α=-1.586134342059924,β=-0.052980118572961,γ=0.882911075530934,δ=0.443506852043971。上式中各字符的下标l=0,1,...,15表示s或d的第l项,上标表示提升次数。
因为本步骤处理的是已经扩展的图像块,因此,行变换不再需要对称扩展。另外,本步骤只进行了提升的变换,尺度的变换在步骤8中进行。
步骤6,列变换。
对于每个block,使用32个线程对共享内存中的数据进行列变换。由于32个线程同时处理扩展图像块的32行数据,当每一列中的一个数据被处理时,与该数据同一行的其他列的数据也会被其他线程同时处理。步骤4中设计的存储格式有效保证了每一行数据的访问效率。
列变换的提升过程与上述步骤5中行变换的提升过程完全相同,只需要把行数据替换为列数据。因为此步骤处理的是已经扩展的图像块,列变换不再需要对称扩展。另外,此步骤只进行了提升的变换,尺度的变换在步骤8中进行。
步骤7,取消数据扩展。
对于每个block,将变换后的扩展图像块上下各四行、左右各四列的数据排除,得到一个24乘24的数据块。
步骤8,拷贝数据块到主机内存。通过以下步骤实现:
第一步,将每个block的数据块拷贝到全局内存B中,拷贝的过程中进行尺度变换。根据数据块中的任一点在原始图像中对应的位置,可以通过下式计算出数据块中该点在全局内存B中所对应的位置:
其中,U表示数据块中该点在全局内存B中所对应位置的行数,I表示数据块中该点在原始图像中对应位置的行数,H表示原始图像的高度,V表示数据块中该点在全局内存B中所对应位置的列数,J表示数据块中该点在原始图像中对应位置的列数,W表示原始图像的宽度,/表示保留小数的除法的符号,
表示将除法结果向上取整的符号,+表示整数加法的符号。
数据块中该点在拷贝过程中所进行的尺度变换,根据该点在原始图像中对应位置的行数I、列数J的奇偶性,分如下情况进行处理:
若数据块中该点在原始图像中对应位置的行数I为偶数、列数J为偶数,则数据块中该点在拷贝到全局内存B中对应的存储位置时应除以K2,K=1.230174104914001;
若数据块中该点在原始图像中对应位置的行数I为奇数、列数J为奇数,则数据块中该点在拷贝到全局内存B中对应的存储位置时应乘以K2,K=1.230174104914001;
其他情况下,不进行尺度变换。
第二步,待所有的block拷贝完成后,将全局内存B中的数据拷贝至主机内存中,释放图形处理单元GPU中的两块全局内存。数据从图形处理单元GPU全局内存到计算机主机内存的拷贝使用计算统一设备架构CUDA提供的函数cudaMemcpy2D来实现;释放图形处理单元GPU的全局内存使用计算统一设备架构CUDA提供的函数cudaFree来实现。
本发明通过以上步骤,实现了并行、高速的小波变换。