c++ HLSL实现简单的图像处理功能

  

由于对于dxva2解码得到的数据不回宜副本内存给CPU处理,所以最好的办法是在GPU上直接进行处理.D3D的像素着色器能够对像素直接进行操作,实现点运算极其简单方便,简单的卷积运算效果也非常好。但d3d 9的限制也很多,对于过于复杂的图像处理则显得有些不能胜任。

  

<强> 1。点运算

  

点运算用HLSL非常容易实现,几乎是公式怎么写,代码就怎么写。以RGB转灰度图显示为例:

        纹理Tex0;   int iFlag=0;   浮动aValue=https://www.yisu.com/zixun/0.0;   浮动bValue=0.0;   sampler2D YTex=sampler_state   {   纹理=;   MipFilter=线性;   MinFilter=线性;   MagFilter=线性;      AddressU=夹;   AddressV=夹;   };   struct PS_INPUT   {   float2 uvCoords0: TEXCOORD0;   };   float4主要(PS_INPUT输入):COLOR0   {   float4 yuvColor;//rgb灰色不知道是不是这么显示的,姑且这么认为   浮灰=tex2D (YTex、输入。uvCoords0)。r * 0.299 + tex2D (YTex输入。uvCoords0)。g * 0.587 + tex2D (YTex输入。uvCoords0)。b * 0.114;   浮动s=0;   如果(iFlag==0)   {   s=aValue *灰色+ bValue/255;   }   else if (iFlag==1)   {   s=aValue *日志(1 +灰色);   }   else if (iFlag==2)   {   s=aValue *战俘(abs(灰色)、bValue);   }   yuvColor。r=s;   yuvColor。g=s;   yuvColor。b=s;   yuvColor。一个=1.0;   返回yuvColor;   }   之前      

点运算如此简单是因为GPU是并行运算的,我个人认为可以看成是每一个像素点(BGRA)对应一个线程,这大概就是OpenCL中所谓的数据并行。这是一个非常简单的程序,指令数少,程序结构也很简单、材质的版本用2.0就可以轻松编过。

  

<强> 2。卷积运算举例

  

指令数较多的情况2.0版本的材质就搞不定了,上3.0版本可以做一些简单的卷积运算。以中值滤波为例:

        纹理Tex0;   矩阵WorldMatrix;   矩阵ViewMatrix;   矩阵ProjMatrix;   sampler2D YTex=sampler_state   {   纹理=& lt; Tex0>;   MipFilter=线性;   MinFilter=线性;   MagFilter=线性;   AddressU=夹;   AddressV=夹;   };   struct VS_INPUT   {   float4 pos:位置;   float4颜色:COLOR0;   float2特克斯:TEXCOORD0;   };//struct VS_OUTPUT   {   float4 pos:位置;   float4颜色:COLOR0;   float2特克斯:TEXCOORD0;   };   float2 g_v4ScreenSize;   int ksize=1;   浮动fLeft f=-1.0;   浮动fTop f=-1.0;   浮动恐惧f=-1.0;   浮动fBottom f=-1.0;//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - BurTechnique - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -   VS_OUTPUT MainVS_Screen (VS_INPUT)   {   VS_OUTPUT=(VS_OUTPUT) 0;   float4x4 matWorldView=mul (WorldMatrix ViewMatrix);   float4x4 matProject=mul (matWorldView ProjMatrix);   出去了。pos=mul (In.pos matProject);   出去了。特克斯=In.tex;   出去了。颜色=In.color;   返回;   }   float4 MainPS_Screen (VS_INPUT): COLOR0   {   float4 outColor=tex2D (YTex。特克斯)。rgba;   如果(ksize & lt;=1 | | ksize % 2==0)   {   返回outColor;   }   如果(ksize比;11 | | ksize & lt;3)   {   返回outColor;   }   如果(! (In.tex。x & lt;恐惧,,In.tex。y & lt;fBottom,,In.tex。x比;fLeft,,In.tex。y比;fTop))   {   返回outColor;   }//纹理大小   float2 TexSize=float2 (g_v4ScreenSize。x, g_v4ScreenSize。y);   浮动x_off=1.0 f/TexSize.x;   浮动y_off=1.0 f/TexSize.y;   float2 fX0Y0=L乜怂? float2 (x_off * ksize/2, y_off * ksize/2);   float3金额={0.0 0.0 0.0 f, f, f};   如果(ksize祝辞=3)   {   和+=tex2D (YTex fX0Y0 + float2 (x_off * 0, y_off * 0)) .rgb;   和+=tex2D (YTex fX0Y0 + float2 (x_off * 0, y_off * 1)) .rgb;   和+=tex2D (YTex fX0Y0 + float2 (x_off * 0, y_off * 2)) .rgb;   和+=tex2D (YTex fX0Y0 + float2 (x_off * 1, y_off * 0)) .rgb;   和+=tex2D (YTex fX0Y0 + float2 (x_off * 1, y_off * 1) .rgb;   和+=tex2D (YTex fX0Y0 + float2 (x_off * 1, y_off * 2) .rgb;   和+=tex2D (YTex fX0Y0 + float2 (x_off * 2, y_off * 0)) .rgb;   和+=tex2D (YTex fX0Y0 + float2 (x_off * 2, y_off * 1) .rgb;   和+=tex2D (YTex fX0Y0 + float2 (x_off * 2, y_off * 2) .rgb;   }   如果(ksize祝辞=5)   {   和+=tex2D (YTex fX0Y0 + float2 (x_off * 3, y_off * 0)) .rgb;   和+=tex2D (YTex fX0Y0 + float2 (x_off * 3, y_off * 1)) .rgb;   和+=tex2D (YTex fX0Y0 + float2 (x_off * 3, y_off * 2)) .rgb;   和+=tex2D (YTex fX0Y0 + float2 (x_off * 3, y_off * 3) .rgb;   和+=tex2D (YTex fX0Y0 + float2 (y_off x_off * 3 * 4) .rgb;   和+=tex2D (YTex fX0Y0 + float2 (x_off * 4, y_off * 0)) .rgb;   和+=tex2D (YTex fX0Y0 + float2 (x_off * 4, y_off * 1) .rgb;   和+=tex2D (YTex fX0Y0 + float2 (x_off * 4, y_off * 2)) .rgb;   和+=tex2D (YTex fX0Y0 + float2 (x_off * 4, y_off * 3)) .rgb;   和+=tex2D (YTex fX0Y0 + float2 (x_off * 4, y_off * 4) .rgb;   和+=tex2D (YTex fX0Y0 + float2 (x_off * 0, y_off * 3)) .rgb;   和+=tex2D (YTex fX0Y0 + float2 (x_off * 1, y_off * 3)) .rgb;   和+=tex2D (YTex fX0Y0 + float2 (x_off * 2, y_off * 3) .rgb;   和+=tex2D (YTex fX0Y0 + float2 (x_off * 0, y_off * 4)) .rgb;   和+=tex2D (YTex fX0Y0 + float2 (x_off * 1, y_off * 4)) .rgb;   和+=tex2D (YTex fX0Y0 + float2 (x_off * 2, y_off * 4) .rgb;   }   如果(ksize祝辞=7)   {   和+=tex2D (YTex fX0Y0 + float2 (x_off * 5, y_off * 0)) .rgb;   和+=tex2D (YTex fX0Y0 + float2 (y_off x_off * 5 * 1)) .rgb;   和+=tex2D (YTex fX0Y0 + float2 (x_off * 5, y_off * 2)) .rgb;   和+=tex2D (YTex fX0Y0 + float2 (y_off x_off * 5 * 3)) .rgb;   和+=tex2D (YTex fX0Y0 + float2 (y_off x_off * 5 * 4)) .rgb;   和+=tex2D (YTex fX0Y0 + float2 (y_off x_off * 5 * 5)) .rgb;   和+=tex2D (YTex fX0Y0 + float2 (y_off x_off * 5 * 6)) .rgb;   和+=tex2D (YTex fX0Y0 + float2 (x_off * 6, y_off * 0)) .rgb;   和+=tex2D (YTex fX0Y0 + float2 (y_off x_off * 6日* 1)).rgb;   和+=tex2D (YTex fX0Y0 + float2 (x_off * 6, y_off * 2)) .rgb;   和+=tex2D (YTex fX0Y0 + float2 (x_off * 6, y_off * 3)) .rgb;   和+=tex2D (YTex fX0Y0 + float2 (x_off * 6, y_off * 4)) .rgb;   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null

c++ HLSL实现简单的图像处理功能