OpenCL 圖像處理函數、圖像放縮和插值

1.OpenCL提供了大量可以在內核中運行的圖像處理函數,它們大致可以分爲以下三類:

1)Read functiongs--返回給定座標上的顏色取值;
(2)write functiongs-- 設定給定座標上的顏色取值;
(3)Information functions-- 提供關於圖像對象的信息,例如圖像的維度以及像素屬性;

圖像讀取函數是從圖像對象中讀取向量,他們各自的參數基本一樣。唯一的區別是函數返回的是浮點數向量還是整數向量,讀取的是二維圖像對象還是三維圖像對象。
讀取圖像數據的內核函數:

1.float4 read_imagef(image2d_t img,sampler_t sampler, int2/float2 coord)--以float4型向量的形式讀取二維圖像在coord位置的顏色數據;
2.int4 read_imagei(image2d_t img,sampler_t sampler, int2/float2 coord)--以int4型向量的形式讀取二維圖像在coord位置的顏色數據;
3.uint4 read_imagui(image2d_t img,sampler_t sampler, int2/float2 coord)--以uint4型向量的形式讀取二維圖像在coord位置的顏色數據;
4.float4 read_imagef(image3d_t img,sampler_t sampler, int4/float4 coord)--以float4型向量的形式讀取三維圖像在coord位置的顏色數據;
5.int4 read_imagei(image3d_t img,sampler_t sampler, int4/float4 coord)--以int4型向量的形式讀取三維圖像在coord位置的顏色數據;
6.uint4 read_imagui(image3d_t img,sampler_t sampler, int4/float4 coord)--以uint4型向量的形式讀取三維圖像在coord位置的顏色數據;

如果圖像對象是一個image2d_t類型,座標的格式就必須是int2型或float2型。
如果圖像對象是一個image3d_t類型,座標的格式就必須是int4型或float4型。
你想從名爲image的二維圖像對象中讀取座標爲(3,4)的顏色數據。如果希望顏色取值是float4型向量,函數調用爲:
float4 color = read_imagef(image, sampler, (int2)(3,4));
read_imagef函數的返回值範圍由image格式來確定。如果像素是無符號歸一化格式(CL_UNORM_INT8,CL_UNORM_INT16,CL_UNORM_INT101010,CLUNORM_SHORT565,或CL_UNORM_SHORT555),函數的返回值就必須在0.0和1.0之間。如果像素是有符號歸一化格式(CL_SNORM_INT8或CL_SNORM_INT16),read_imagef函數的返回值就必須在-0.5和0.5之間。如果像素的格式是CL_HALF_FLOAT或CL_FLOAT,函數的返回值將是正常的浮點數。
read_image函數返回的顏色向量:(通道順序 向量存儲(整數))

CL_R,CL_Rx --(R, 0, 0, 1)
CL_A--(0, 0, 0, A)
CL_RG,CL_RGx--(R, G, 0 ,1)
CL_RA--(R, 0, 0, A)
CL_RGB, CL_RGBx--(R, G, B, 1)
CL_RGBA,CL_BGRA, CL_ARGB--(R,G,B,A)
CL_INTENSITY--(I, I, I, I)
CL_LUMINANCE--(L, L, L, 1)

表中的數字全部都是整數,但如果向量是read_imagef函數的返回值,它的分量就是浮點數。如果,圖像對象的像素都是CL_RG格式,read_imagef函數所返回的向量將是[R, G, 0.0, 1.0],其中R和G分別表示的是像素的紅色和綠色分量。
將數據寫入圖像對象的內核函數:

1.void write_imagef(image2d_t img, int2 coord, float4 color)--將float4型顏色數據寫到二維圖像中coord所指定的位置。
2.void write_imagei(image2d_t img, int2 coord, int4 color)--將int4型顏色數據寫到二維圖像中coord所指定的位置。
3.void write_imageui(image2d_t img, int2 coord, uint4 color)--將uint4型顏色數據寫到二維圖像中coord所指定的位置。
4.void write_imagef(image3d_t img, int4 coord, float4 color)--將float4型顏色數據寫到三維圖像中coord所指定的位置。
5.void write_imagei(image3d_t img, int4 coord, int4 color)--將int4型顏色數據寫到三維圖像中coord所指定的位置。
6.void write_imageui(image3d_t img, int4 coord,uint4 color)--將uint4型顏色數據寫到三維圖像中coord所指定的位置。

默認情況下,並不支持將數據寫入到三維圖像對象中。這個功能需要通過cl_khr_3d_image_writes擴展來實現,因此,如果想要修改image3d_t對象中的數據,需要在內核中加入下面一行代碼,確認是否能有這個擴展:
#pragma OPENCL EXTENSION cl_khr_3d_image_writes: enable
爲了設定代寫的顏色數據。例如,如果像素的RGB分量 是[132,15,44], 你可以將像素數據寫到CL_RGB型圖像對象img中:
write_imageui(img, coord, (uint4)(132,15,44,0));
圖像信息函數
獲取推向信息的內核函數:

(1)int get_image_width(image2d_t/image3d_t image)--返回圖像的寬度;
(2)int get_image_height(image2d_t/image3d_t image)--返回圖像的高度;
(3)int get_image_depth(image3d_t image)--返回圖像的深度;
(4)int2 get_image_dim(image2d_t image)--以int2型向量的形式,返回二維圖像的寬度和高度;
(5)int4 get_image_dim(image3d_t image)--以int4型向量的形式,返回三維圖像的寬度、高度和深度;
(6)int get_image_channel_data_type(mage2d_t/image3d_t image)--返回圖像的通道數據類型(CLK_UNORM_INT8,CLK_SIGNED_INT32.等)
(7)int get_image_channel_order(image2d_t/image3d_t image)--返回圖像的通道(CLK_A,CLK_RGB,CLK_INTENSITY等)

注意內核並不接受採樣器作爲它的參數。所以,程序在內核函數之前,創建了以一個sampler_t型的sampler對象。

圖像放縮和插值:
圖像的放大是很重要的問題,因爲涉及到的是增加像素信息,而不是溢出已有的像素。如果NN的像素放大k倍,得到的圖像是kNkN大小的圖像。現在重要的問題是:如何獲取放大後的圖像中那(k的平方減一)N的平方個像素的顏色取值。
一種方法是重複原始圖像中的某些像素。稱爲最近鄰插值法。但是如果需要繪製穿過像素中心點的直線,並用這些直線來近似已知像素點之間的各點,這種方法也被稱爲雙線插值法,這種方法所需的工作量大,但相應的,產生的結果也更好。如果配置正確,採樣器可以告訴內核自動選擇最近鄰插值法(CL_FILTER_NEAREST),還是雙線性插值法(CLK_FILTER_LINEAR).
注意:像素插值法只有在圖像的座標是浮點數的前提下才能完成,如果圖像的座標是整數,得到的插值法結果將完全和其中某個像素的顏色一樣。

最近鄰插值(CL_FILTER_NEAREST):
如果相對於其他的像素點,待處理的點更靠近像素A,那麼,那個點上的採樣顏色就會被設爲像素A的顏色。這種方法可以用來放大圖像,處理得到的圖像只包含原來圖像的顏色。如果圖像被放大k倍,圖像上的每個點都會重複k次。
最近鄰插值法的運行速度很快,因爲它並不需要任何的數學計算。但如果用它來放大圖像,得到的結果會看起來粒狀化和像素點化(grainy和pixelated).放大後的圖像有一個問題,就是像素點取址之間的突變。即使是灰度圖像,也能明顯地看到汽車像素點之間顏色的非連續變化。

雙線性插值法CLK_FILTER_LINEAR):
如果一個點是在矩形圖像的兩個已有像素之間時,它採樣的顏色將被設爲兩個像素顏色的線性組合:

1)使用CLK_FILTER_LINEAR的前提是座標必須是浮點數;
(2)只有read_imagef函數有這個選項。如果將採樣器設爲CLK_FILTER_LINEAR,調用read_imageuior read_imagei函數,結果將是未定義的。
(3)有些OpenCL兼容設備並不支持雙線性插值。如果是那樣的話,就需要通過硬件模擬的方式來插值。

小結:
OpenCL標準定義了大量和圖像相關的數據類型和函數。如果一個內核處理圖像,它會將圖像數據作爲圖像對象(image2d_t型對象或image3d_t型對象)來讀入。爲了從圖像對象中讀取數據,內核需要一個sampler_t型對象。這個對象可以用來控制內核讀取座標,插值運算的方式。
OpenCL的圖像處理函數可以分爲三類:從圖像對象中讀取數據的函數,將數據寫入到圖像對象的函數,以及訪問和圖像有關的信息(例如圖像的大小,以及像素屬性)的函數。讀函數需要採樣器對象,而座標可以按整數或浮點數的形式給出。然而,寫函數卻要求的是整數座標。此外,三維圖像不能直接寫入到圖像對象中,除非設備支持cl_khr_3d_image_writer擴展。
可以對採樣器進行配置,設置相鄰像素之間顏色數據的插值方式,這也讓採樣器在圖像處理中扮演了一個頗爲重要的角色。OpenCL提供了兩種插值方法:最近鄰插值法CLK_FILTER_NEAREST以及雙線性插值法CLK_FILTER_LINEAR.當用最鄰近插值法來放縮圖像時,它會在原始圖像中重複像素信息。這種方法的又是是運行速度快,但如果採用雙線性插值法,能取得更好的插值效果。雙線性插值法通過使用直線連接兩個像素的中心,然後來計算相鄰像素之間的顏色取值。但是,這種插值方法只適用於座標和顏色取值都是浮點數的情況。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章