C++ HLSL實(shí)現(xiàn)簡(jiǎn)單的圖像處理功能
由于對(duì)于dxva2解碼得到的數(shù)據(jù)不宜copy回內(nèi)存給CPU處理,所以最好的辦法是在GPU上直接進(jìn)行處理。D3D的像素著色器能夠?qū)ο袼刂苯舆M(jìn)行操作,實(shí)現(xiàn)點(diǎn)運(yùn)算極其簡(jiǎn)單方便,簡(jiǎn)單的卷積運(yùn)算效果也非常好。但D3D9的限制也很多,對(duì)于過(guò)于復(fù)雜的圖像處理則顯得有些不能勝任。
1.點(diǎn)運(yùn)算
點(diǎn)運(yùn)算用HLSL非常容易實(shí)現(xiàn),幾乎是公式怎么寫(xiě),代碼就怎么寫(xiě)。以RGB轉(zhuǎn)灰度圖顯示為例:
texture Tex0 ;
int iFlag = 0 ;
float aValue= 0.0 ;
float bValue= 0.0 ;
sampler2D YTex =
sampler_state
{
Texture = <Tex0> ;
MipFilter = LINEAR ;
MinFilter = LINEAR ;
MagFilter = LINEAR ;
AddressU = CLAMP ;
AddressV = CLAMP ;
};
struct PS_INPUT
{
float2 uvCoords0 : TEXCOORD0 ;
};
float4 Main( PS_INPUT input ) : COLOR0
{
float4 yuvColor ;
//rgb to gray 不知道是不是這么顯示的,姑且這么認(rèn)為
float gray = tex2D( YTex, input.uvCoords0 ).r * 0.299 + tex2D( YTex, input.uvCoords0 ).g * 0.587 + tex2D( YTex, input.uvCoords0 ).b * 0.114 ;
float s = 0 ;
if(iFlag == 0)
{
s = aValue * gray + bValue/255 ;
}
else if(iFlag == 1)
{
s = aValue * log(1+gray) ;
}
else if(iFlag == 2)
{
s = aValue * pow(abs(gray),bValue) ;
}
yuvColor.r = s ;
yuvColor.g = s ;
yuvColor.b = s ;
yuvColor.a = 1.0 ;
return yuvColor ;
}
點(diǎn)運(yùn)算如此簡(jiǎn)單是因?yàn)镚PU是并行運(yùn)算的,我個(gè)人認(rèn)為可以看成是每一個(gè)像素點(diǎn)(BGRA)對(duì)應(yīng)一個(gè)線(xiàn)程,這大概就是OpenCL中所謂的數(shù)據(jù)并行。這是一個(gè)非常簡(jiǎn)單的程序,指令數(shù)少,程序結(jié)構(gòu)也很簡(jiǎn)單,shader 的版本用2.0就可以輕松編過(guò)。
2.卷積運(yùn)算舉例
指令數(shù)較多的情況2.0版本的shader就搞不定了,上3.0版本可以做一些簡(jiǎn)單的卷積運(yùn)算。以中值濾波為例:
texture Tex0 ;
matrix WorldMatrix;
matrix ViewMatrix;
matrix ProjMatrix;
sampler2D YTex =
sampler_state
{
Texture = <Tex0> ;
MipFilter = LINEAR ;
MinFilter = LINEAR ;
MagFilter = LINEAR ;
AddressU = CLAMP ;
AddressV = CLAMP ;
};
struct VS_INPUT
{
float4 pos : POSITION;
float4 color : COLOR0;
float2 tex : TEXCOORD0;
};
//
struct VS_OUTPUT
{
float4 pos : POSITION;
float4 color : COLOR0;
float2 tex : TEXCOORD0;
};
float2 g_v4ScreenSize;
int ksize = 1 ;
float fLeft = -1.0f ;
float fTop = -1.0f ;
float fRight = -1.0f ;
float fBottom = -1.0f ;
//--------------------------------- BurTechnique --------------------------------------
VS_OUTPUT MainVS_Screen( VS_INPUT In )
{
VS_OUTPUT Out = ( VS_OUTPUT )0;
float4x4 matWorldView = mul(WorldMatrix,ViewMatrix);
float4x4 matProject = mul(matWorldView,ProjMatrix);
Out.pos = mul(In.pos,matProject);
Out.tex = In.tex;
Out.color = In.color;
return Out;
}
float4 MainPS_Screen( VS_INPUT In ) : COLOR0
{
float4 outColor = tex2D( YTex, In.tex ).rgba ;
if(ksize <= 1 || ksize%2 == 0)
{
return outColor ;
}
if( ksize > 11 || ksize < 3)
{
return outColor ;
}
if(!(In.tex.x < fRight && In.tex.y < fBottom && In.tex.x > fLeft && In.tex.y > fTop))
{
return outColor ;
}
// 紋理大小
float2 TexSize = float2( g_v4ScreenSize.x , g_v4ScreenSize.y );
float x_off = 1.0f / TexSize.x;
float y_off = 1.0f / TexSize.y;
float2 fX0Y0 = In.tex - float2(x_off * ksize/2, y_off*ksize/2) ;
float3 sum = {0.0f, 0.0f, 0.0f} ;
if(ksize >= 3)
{
sum += tex2D( YTex , fX0Y0 + float2(x_off * 0, y_off*0)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 0, y_off*1)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 0, y_off*2)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 1, y_off*0)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 1, y_off*1)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 1, y_off*2)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 2, y_off*0)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 2, y_off*1)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 2, y_off*2)).rgb;
}
if(ksize >= 5)
{
sum += tex2D( YTex , fX0Y0 + float2(x_off * 3, y_off*0)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 3, y_off*1)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 3, y_off*2)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 3, y_off*3)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 3, y_off*4)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 4, y_off*0)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 4, y_off*1)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 4, y_off*2)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 4, y_off*3)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 4, y_off*4)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 0, y_off*3)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 1, y_off*3)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 2, y_off*3)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 0, y_off*4)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 1, y_off*4)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 2, y_off*4)).rgb;
}
if(ksize >= 7)
{
sum += tex2D( YTex , fX0Y0 + float2(x_off * 5, y_off*0)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 5, y_off*1)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 5, y_off*2)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 5, y_off*3)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 5, y_off*4)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 5, y_off*5)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 5, y_off*6)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 6, y_off*0)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 6, y_off*1)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 6, y_off*2)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 6, y_off*3)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 6, y_off*4)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 6, y_off*5)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 6, y_off*6)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 0, y_off*5)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 1, y_off*5)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 2, y_off*5)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 3, y_off*5)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 4, y_off*5)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 0, y_off*6)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 1, y_off*6)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 2, y_off*6)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 3, y_off*6)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 4, y_off*6)).rgb;
}
if(ksize >= 9)
{
sum += tex2D( YTex , fX0Y0 + float2(x_off * 7, y_off*0)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 7, y_off*1)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 7, y_off*2)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 7, y_off*3)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 7, y_off*4)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 7, y_off*5)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 7, y_off*6)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 7, y_off*7)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 7, y_off*8)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 8, y_off*0)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 8, y_off*1)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 8, y_off*2)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 8, y_off*3)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 8, y_off*4)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 8, y_off*5)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 8, y_off*6)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 8, y_off*7)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 8, y_off*8)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 0, y_off*7)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 1, y_off*7)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 2, y_off*7)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 3, y_off*7)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 4, y_off*7)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 5, y_off*7)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 6, y_off*7)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 0, y_off*8)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 1, y_off*8)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 2, y_off*8)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 3, y_off*8)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 4, y_off*8)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 5, y_off*8)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 6, y_off*8)).rgb;
}
if(ksize >= 11)
{
sum += tex2D( YTex , fX0Y0 + float2(x_off * 9, y_off*0)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 9, y_off*1)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 9, y_off*2)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 9, y_off*3)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 9, y_off*4)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 9, y_off*5)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 9, y_off*6)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 9, y_off*7)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 9, y_off*8)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 9, y_off*9)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 9, y_off*10)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 10, y_off*0)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 10, y_off*1)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 10, y_off*2)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 10, y_off*3)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 10, y_off*4)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 10, y_off*5)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 10, y_off*6)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 10, y_off*7)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 10, y_off*8)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 10, y_off*9)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 10, y_off*10)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 0, y_off*9)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 1, y_off*9)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 2, y_off*9)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 3, y_off*9)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 4, y_off*9)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 5, y_off*9)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 6, y_off*9)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 7, y_off*9)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 8, y_off*9)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 0, y_off*10)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 1, y_off*10)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 2, y_off*10)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 3, y_off*10)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 4, y_off*10)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 5, y_off*10)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 6, y_off*10)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 7, y_off*10)).rgb;
sum += tex2D( YTex , fX0Y0 + float2(x_off * 8, y_off*10)).rgb;
}
outColor = float4(sum/(ksize*ksize),1.0f);
return outColor ;
}
//--------------------------- 技術(shù)---------------------------
technique BurTechnique
{
pass P0
{
LightEnable[0] = false;
VertexShader = compile vs_3_0 MainVS_Screen();
PixelShader = compile ps_3_0 MainPS_Screen();
}
}
由于3.0版本的shader似乎不允許pixel shader單獨(dú)出現(xiàn),所以我從點(diǎn)運(yùn)算用像素著色器實(shí)現(xiàn)改為用特效來(lái)實(shí)現(xiàn)。HLSL語(yǔ)法中有if語(yǔ)句,也有for語(yǔ)句,可是這個(gè)程序卻不厭其煩的把所有的都給列出來(lái)來(lái),而沒(méi)有使用for循環(huán)。這是因?yàn)樵趯?shí)際使用中發(fā)現(xiàn)有一些限制,比如if語(yǔ)句的if(A>B),A與B中必須有一個(gè)是常量,就像上面見(jiàn)到的那種形式;for循環(huán)中間的判斷也是如此,只是在第二層j循環(huán)中可以是第一層循環(huán)的i,即不可以
for(int i=0;i<ksize;i++)
{
for(int j=0;j<ksize1;j++)
{
..........
}
}
以上代碼的ksize與ksize1都必須為常數(shù),例外的情況是ksize1可以為第一層循環(huán)的 i 。這個(gè)問(wèn)題不知道后續(xù)版本的shader有沒(méi)有,反正我當(dāng)前使用的版本有。
另外有一個(gè)需要注意的地方是指令數(shù),2.0版本的shader支持的指令數(shù)相當(dāng)少,3.0版本則要多好多,我最長(zhǎng)寫(xiě)到了400多條快500條時(shí)才導(dǎo)致編譯失敗。 還有一個(gè)需要提醒的是3.0版本的shader只支持D3D 9.0C以后的。如果要求做更為復(fù)雜的圖像處理,可以的話(huà)建議上D3D11,compute shader雖然我沒(méi)用過(guò),但從介紹來(lái)說(shuō),應(yīng)該可以處理一些更為復(fù)雜的圖像處理。
以上就是本文的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,同時(shí)也希望多多支持我們!
上一篇:C/C++靜態(tài)類(lèi)和this指針詳解及實(shí)例代碼
欄 目:C語(yǔ)言
下一篇:C++ 11實(shí)現(xiàn)檢查是否存在特定的成員函數(shù)
本文標(biāo)題:C++ HLSL實(shí)現(xiàn)簡(jiǎn)單的圖像處理功能
本文地址:http://www.jygsgssxh.com/a1/Cyuyan/1748.html
您可能感興趣的文章
- 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
- 01-10數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)-用棧實(shí)現(xiàn)表達(dá)式求值的方法詳解
- 01-10使用OpenGL實(shí)現(xiàn)3D立體顯示的程序代碼
- 01-10深入理解C++中常見(jiàn)的關(guān)鍵字含義
- 01-10求斐波那契(Fibonacci)數(shù)列通項(xiàng)的七種實(shí)現(xiàn)方法
- 01-10C語(yǔ)言 解決不用+、-、&#215;、&#247;數(shù)字運(yùn)算符做加法
- 01-10使用C++實(shí)現(xiàn)全排列算法的方法詳解
- 01-10c++中inline的用法分析
- 01-10用C++實(shí)現(xiàn)DBSCAN聚類(lèi)算法
- 01-10深入全排列算法及其實(shí)現(xiàn)方法


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 04-02c語(yǔ)言函數(shù)調(diào)用后清空內(nèi)存 c語(yǔ)言調(diào)用
- 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
- 04-02c語(yǔ)言的正則匹配函數(shù) c語(yǔ)言正則表達(dá)
- 04-02c語(yǔ)言用函數(shù)寫(xiě)分段 用c語(yǔ)言表示分段
- 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)
- 04-02c語(yǔ)言編寫(xiě)函數(shù)冒泡排序 c語(yǔ)言冒泡排
- 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
- 04-02c語(yǔ)言分段函數(shù)怎么求 用c語(yǔ)言求分段
- 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎
- 04-02c語(yǔ)言調(diào)用函數(shù)求fibo C語(yǔ)言調(diào)用函數(shù)求
隨機(jī)閱讀
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-10delphi制作wav文件的方法
- 01-11Mac OSX 打開(kāi)原生自帶讀寫(xiě)NTFS功能(圖文
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 04-02jquery與jsp,用jquery
- 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 01-10C#中split用法實(shí)例總結(jié)


