由于对于dxva2解码得到的数据不宜copy回内存给CPU处理,所以最好的办法是在GPU上直接进行处理。D3D的像素着色器能够对像素直接进行操作,实现点运算极其简单方便,简单的卷积运算效果也非常好。但D3D9的限制也很多,对于过于复杂的图像处理则显得有些不能胜任。
1.点运算
点运算用HLSL非常容易实现,几乎是公式怎么写,代码就怎么写。以RGB转灰度图显示为例:
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 不知道是不是这么显示的,姑且这么认为 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 ; }
点运算如此简单是因为GPU是并行运算的,我个人认为可以看成是每一个像素点(BGRA)对应一个线程,这大概就是OpenCL中所谓的数据并行。这是一个非常简单的程序,指令数少,程序结构也很简单,shader 的版本用2.0就可以轻松编过。
2.卷积运算举例
指令数较多的情况2.0版本的shader就搞不定了,上3.0版本可以做一些简单的卷积运算。以中值滤波为例:
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 ; } //--------------------------- 技术--------------------------- 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单独出现,所以我从点运算用像素着色器实现改为用特效来实现。HLSL语法中有if语句,也有for语句,可是这个程序却不厌其烦的把所有的都给列出来来,而没有使用for循环。这是因为在实际使用中发现有一些限制,比如if语句的if(A>B),A与B中必须有一个是常量,就像上面见到的那种形式;for循环中间的判断也是如此,只是在第二层j循环中可以是第一层循环的i,即不可以
for(int i=0;i<ksize;i++) { for(int j=0;j<ksize1;j++) { .......... } }
以上代码的ksize与ksize1都必须为常数,例外的情况是ksize1可以为第一层循环的 i 。这个问题不知道后续版本的shader有没有,反正我当前使用的版本有。
另外有一个需要注意的地方是指令数,2.0版本的shader支持的指令数相当少,3.0版本则要多好多,我最长写到了400多条快500条时才导致编译失败。 还有一个需要提醒的是3.0版本的shader只支持D3D 9.0C以后的。如果要求做更为复杂的图像处理,可以的话建议上D3D11,compute shader虽然我没用过,但从介绍来说,应该可以处理一些更为复杂的图像处理。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持小牛知识库!
本文向大家介绍Android简单实现画图功能,包括了Android简单实现画图功能的使用技巧和注意事项,需要的朋友参考一下 如何在图片上画画呢?这里写了一个demo,供大家参考 一、先看一眼工程结构 工程结构: 二、自定义view 这个自定义view实现了保留轨迹的功能,代码如下 三、主页面布局文件 主页面布局文件 四、主Activity代码 五、效果 运行效果图如下 六、疑问 当线条变粗时,线条
本文向大家介绍java简单实现八叉树图像处理代码示例,包括了java简单实现八叉树图像处理代码示例的使用技巧和注意事项,需要的朋友参考一下 一晃工作有段时间了,第一次写博客,有点不知道怎么写,大家将就着看吧,说的有什么不正确的也请大家指正。 最近工作中用到了一个图像压缩的功能。找了一些工具,没有太好的选择。最后选了一个叫jdeli的,奈何效率又成了问题。我迫于无奈就只能研究了下它的源码,却发现自己
我已经在处理中编写了一个算法来执行以下操作: 由于某种原因,这个算法会立即冻结。我在里面放了打印语句,显示它甚至在试图加载图像之前就冻结了。考虑到我已经编写了另一个非常相似的算法,并且执行起来没有并发症,这让我特别困惑。另一种算法读取图像,对指定大小的每块瓷砖的颜色取平均值,然后在用平均颜色取平均值的区域上打印矩形,有效地使图像像素化。两种算法都加载图像并检查其每个像素。这个算法的主要区别在于它没
本文向大家介绍Yii 使用intervention/image拓展实现图像处理功能,包括了Yii 使用intervention/image拓展实现图像处理功能的使用技巧和注意事项,需要的朋友参考一下 一:安装intervention/image拓展 composer require intervention/image 二:上传文件 同时实现单图上传和多图上传 三:添加水印 1:添加文字水印 添加
本文向大家介绍C语言实现简单图书管理系统,包括了C语言实现简单图书管理系统的使用技巧和注意事项,需要的朋友参考一下 目前为止跟着学校进度学习C语言大概半年左右,基础学习只学到了指针,学得非常浅。说实话,起初对C语言的印象———只是一个学习计算机语言的敲门砖,对具体C语言如何应用等,非常迷茫。直到大一下半学期的高级语言设计课程之后,试过dos运行的图形化界面的完整小程序,才发现C语言的魅力。 ok,
本文向大家介绍C#图像处理之图像平移的方法,包括了C#图像处理之图像平移的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了C#图像处理之图像平移的方法。分享给大家供大家参考。具体如下: 希望本文所述对大家的C#程序设计有所帮助。