圖像旋轉(zhuǎn)
源代碼需要在clEnqueueNDRangeKernel函數(shù)執(zhí)行之后注釋掉
waitForEventAndRelease() //或者//
clWaitForEvents(1,&ev)
因為wait函數(shù)在結(jié)束時釋放了ev谒拴,而下一個函數(shù)cl的功能其實和wait類似尝江,也要訪問ev變量,所以如果兩個函數(shù)串行執(zhí)行英上,后執(zhí)行的那個會找不到那個變量茂装,相當于訪問空指針怠蹂,會報段錯誤。
實驗結(jié)果:
CPU旋轉(zhuǎn)的結(jié)果
用OpenCL進行旋轉(zhuǎn)的結(jié)果
邊緣檢測
CPU
需要和旋轉(zhuǎn)一樣調(diào)用cv.h少态,方法是將編譯語句-o命名和-lOpenCL中間加一個調(diào)用
`pkg-config --cflags --libs opencv`
然后方法是直接調(diào)用sobel函數(shù),參數(shù)分別為
sobel(Mat類型輸入易遣,輸出彼妻,輸出圖像深度,x方向差分階數(shù),y方向...豆茫,核大小侨歉,縮放因子,delta值揩魂,邊界模式)
深度ddepth取CV_16S幽邓;核大小默認3可調(diào),縮放因子默認1火脉,delta默認0牵舵,邊界模式默認BORDER_DEFAULT。
如果做x方向上的sobel運算倦挂,則x方向差分階數(shù)=1畸颅,y方向=0.
反之亦然。
將兩個反向的結(jié)果做近似處理方援,即調(diào)用addweighted()函數(shù)没炒,指數(shù)設為0.5,作類似求勾股的操作犯戏。得到每個元素的梯度送火,輸出即是被強化后的邊緣。
OpenCL方面的運算我參考了https://software.intel.com/en-us/INDE-OpenCL-Sobel,這里的思路是:
__kernel void Sobel_v1_uchar (__global uchar *pSrcImage, __global uchar *pDstImage)
{
uint dstYStride = get_global_size(0);
uint dstIndex = get_global_id(1) * dstYStride + get_global_id(0);
uint srcYStride = dstYStride + 32;
uint srcIndex = get_global_id(1) * srcYStride + get_global_id(0) + 16;
uint a, b, c;
uint d, /*center*/ f;
uint g, h, i;
// Read data in
a = pSrcImage[srcIndex-1]; b = pSrcImage[srcIndex]; c = pSrcImage[srcIndex+1];
srcIndex += srcYStride;
d = pSrcImage[srcIndex-1]; /*center*/ f = pSrcImage[srcIndex+1];
srcIndex += srcYStride;
g = pSrcImage[srcIndex-1]; h = pSrcImage[srcIndex]; i = pSrcImage[srcIndex+1];
uint xVal = a* 1 + c*-1 +
d* 2 + /*center*/ f*-2 +
g* 1 + i*-1;
uint yVal = a* 1 + b* 2 + c* 1 +
/*center*/
g*-1 + h*-2 + i*-1;
// Write data out
pDstImage[dstIndex] = min((uint)255, (uint)sqrt(xVal*xVal + yVal*yVal));
}
仿照平時對圖像處理的方法先匪,一個workitem處理一個像素种吸,對每一個像素周圍的3x3區(qū)域的每個像素點進行兩個方向上的卷積處理,然后再平方后求和開方胚鸯。