由于對(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ù)雜的圖像處理則顯得有些不能勝任。
創(chuàng)新互聯(lián)堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的青龍網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!
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è)線程,這大概就是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ù)雜的圖像處理,可以的話建議上D3D11,compute shader雖然我沒(méi)用過(guò),但從介紹來(lái)說(shuō),應(yīng)該可以處理一些更為復(fù)雜的圖像處理。
以上就是本文的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,同時(shí)也希望多多支持創(chuàng)新互聯(lián)!
新聞名稱:C++HLSL實(shí)現(xiàn)簡(jiǎn)單的圖像處理功能
本文網(wǎng)址:http://muchs.cn/article42/ihdhhc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制開(kāi)發(fā)、用戶體驗(yàn)、網(wǎng)站營(yíng)銷(xiāo)、做網(wǎng)站、商城網(wǎng)站、網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)