图像处理常用算法GPU实现二:基于微分的边缘检测
2017-08-14 16:40
786 查看
[cpp] view
plain copy
/********************************
* Author: rabbit729
* E-mail: wlq_729@163.com
* Date: 2012-09-23
* Description: 图像的边缘检测
********************************/
#include <d3dx9.h>
//-----------------------------------------------------------------------------
// Desc: 全局变量
//-----------------------------------------------------------------------------
LPDIRECT3D9 g_pD3D = NULL; //Direct3D对象
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; //Direct3D设备对象
LPDIRECT3DTEXTURE9 g_pTextureScreen = NULL; //待处理图片
ID3DXEffect* g_pEffect = NULL; //效果指针
//常量句柄
D3DXHANDLE hTechScreen = NULL; //Effect句柄
D3DXHANDLE hTexScreen = NULL; //纹理句柄
D3DXHANDLE hViewPortWidthInv = NULL; //视口宽倒数句柄
D3DXHANDLE hViewPortHeightInv = NULL; //视口高倒数句柄
LPDIRECT3DVERTEXBUFFER9 g_pScreenSpaceQuad = NULL; //背板VB
const int WIDTH = 465;
const int HEIGHT = 669;
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_TEX1)
struct Vertex
{
Vertex(){}
Vertex(float x, float y, float z, float w)
{
_x = x; _y = y; _z = z; _w = w;
}
float _x, _y, _z, _w;
static const DWORD FVF;
};
const DWORD Vertex::FVF = D3DFVF_XYZW;
//-----------------------------------------------------------------------------
// Desc: 设置世界矩阵
//-----------------------------------------------------------------------------
VOID SetWorldMatrix()
{
//创建并设置世界矩阵
D3DXMATRIXA16 matWorld, matRotateX, matRotateY;
D3DXMATRIXA16 matScale;
D3DXMatrixIdentity(&matScale);
matScale._11 = matScale._22 = matScale._33 = 0.5f;
D3DXMatrixIdentity(&matWorld);
D3DXMatrixIdentity(&matRotateX);
D3DXMatrixIdentity(&matRotateY);
D3DXMatrixRotationX( &matRotateX, D3DX_PI / 3.0 );
D3DXMatrixRotationY( &matRotateY, -D3DX_PI / 8.0 );
D3DXMatrixMultiply(&matWorld, &matRotateX, &matRotateY);
D3DXMatrixMultiply(&matWorld, &matScale, &matWorld);
g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
}
//-----------------------------------------------------------------------------
// Desc: 设置观察矩阵和投影矩阵
//-----------------------------------------------------------------------------
VOID SetViewAndProjMatrix()
{
//创建并设置观察矩阵
D3DXVECTOR3 vEyePt( 0.0f, 0.0f,-250.0f );
D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
D3DXMATRIXA16 matView;
D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
//创建并设置投影矩阵
D3DXMATRIXA16 matProj;
D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 1000.0f );
g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
}
//-----------------------------------------------------------------------------
// Desc: 初始化Direct3D
//-----------------------------------------------------------------------------
HRESULT InitD3D( HWND hWnd )
{
//创建Direct3D对象, 该对象用于创建Direct3D设备对象
if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
return E_FAIL;
//设置D3DPRESENT_PARAMETERS结构, 准备创建Direct3D设备对象
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
//创建Direct3D设备对象
if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &g_pd3dDevice ) ) )
{
return E_FAIL;
}
//创建Effect
ID3DXBuffer* errBuffer = NULL;
if (FAILED(D3DXCreateEffectFromFile(g_pd3dDevice, L"edgedetect.fx", NULL, NULL, D3DXSHADER_DEBUG | D3DXSHADER_SKIPOPTIMIZATION, NULL, &g_pEffect, &errBuffer)))
{
if (errBuffer)
{
MessageBox(0, (LPCTSTR)errBuffer->GetBufferPointer(), 0, 0);
errBuffer->Release();
}
return E_FAIL;
}
//获取常量句柄
hTechScreen = g_pEffect->GetTechniqueByName("Screen");
hTexScreen = g_pEffect->GetParameterByName(0, "TexScreen");
hViewPortWidthInv = g_pEffect->GetParameterByName(0, "viewport_inv_width");
hViewPortHeightInv = g_pEffect->GetParameterByName(0, "viewport_inv_height");
//设置环境光
g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0xffffffff );
//设置观察矩阵和投影矩阵
SetViewAndProjMatrix();
return S_OK;
}
//-----------------------------------------------------------------------------
// Desc: 创建场景图形
//-----------------------------------------------------------------------------
HRESULT InitGeometry()
{
// 创建屏幕板
g_pd3dDevice->CreateVertexBuffer(
6 * sizeof(Vertex),
D3DUSAGE_WRITEONLY,
Vertex::FVF,
D3DPOOL_MANAGED,
&g_pScreenSpaceQuad,
0);
Vertex* vertices;
g_pScreenSpaceQuad->Lock(0, 0, (void**)&vertices, 0);
vertices[0] = Vertex(-1.0f, 1.0f, 0.5f, 1.0f);
vertices[1] = Vertex(1.0f, 1.0f, 0.5f, 1.0f);
vertices[2] = Vertex( 1.0f, -1.0f, 0.5f, 1.0f);
vertices[3] = Vertex(-1.0f, 1.0f, 0.5f, 1.0f);
vertices[4] = Vertex( 1.0f, -1.0f, 0.5f, 1.0f);
vertices[5] = Vertex( -1.0f, -1.0f, 0.5f, 1.0f);
g_pScreenSpaceQuad->Unlock();
//加载纹理
HRESULT hr = D3DXCreateTextureFromFile(g_pd3dDevice, L"meinv.jpg", &g_pTextureScreen);
if (FAILED(hr))
{
return E_FAIL;
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Desc: 释放创建的对象
//-----------------------------------------------------------------------------
VOID Cleanup()
{
if (g_pScreenSpaceQuad != NULL)
{
g_pScreenSpaceQuad->Release();
}
if (g_pTextureScreen != NULL)
{
g_pTextureScreen->Release();
}
if (g_pEffect != NULL)
{
g_pEffect->Release();
}
//释放Direct3D设备对象
if( g_pd3dDevice != NULL )
g_pd3dDevice->Release();
//释放Direct3D对象
if( g_pD3D != NULL )
g_pD3D->Release();
}
VOID RenderScreen()
{
//将RenderTarget作为纹理
g_pEffect->SetTexture(hTexScreen, g_pTextureScreen);
float fWidthInv = 1.0f / WIDTH;
float fHeightInv = 1.0f / HEIGHT;
g_pEffect->SetFloat(hViewPortWidthInv, fWidthInv);
g_pEffect->SetFloat(hViewPortHeightInv, fHeightInv);
g_pd3dDevice->SetStreamSource(0, g_pScreenSpaceQuad, 0, sizeof(Vertex));
g_pd3dDevice->SetFVF(Vertex::FVF);
// 设置要使用的Technique
g_pEffect->SetTechnique(hTechScreen);
UINT numPasses = 0;
g_pEffect->Begin(&numPasses, 0);
for (int i = 0; i < numPasses; i++)
{
g_pEffect->BeginPass(i);
g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
g_pEffect->EndPass();
}
g_pEffect->End();
}
//-----------------------------------------------------------------------------
// Desc: 渲染场景
//-----------------------------------------------------------------------------
VOID Render()
{
// 获取backbuffer
LPDIRECT3DSURFACE9 pBackbuffer;
g_pd3dDevice->GetRenderTarget(0, &pBackbuffer);
//开始渲染场景
if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
{
//设回backbuffer
g_pd3dDevice->SetRenderTarget(0, pBackbuffer);
RenderScreen();
//场景渲染结束
g_pd3dDevice->EndScene();
}
//在屏幕上显示场景
g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}
//-----------------------------------------------------------------------------
// Desc: 窗口过程, 处理消息
//-----------------------------------------------------------------------------
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
switch( msg )
{
case WM_DESTROY:
Cleanup();
PostQuitMessage( 0 );
return 0;
}
return DefWindowProc( hWnd, msg, wParam, lParam );
}
//-----------------------------------------------------------------------------
// Desc: 入口函数
//-----------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{
//注册窗口类
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
L"ClassName", NULL };
RegisterClassEx( &wc );
//创建窗口
HWND hWnd = CreateWindow( L"ClassName", L"图像二值化",
WS_OVERLAPPEDWINDOW, 200, 100, WIDTH, HEIGHT,
GetDesktopWindow(), NULL, wc.hInstance, NULL );
//初始化Direct3D
if( SUCCEEDED( InitD3D( hWnd ) ) )
{
//创建场景图形
if( SUCCEEDED( InitGeometry() ) )
{
//显示窗口
ShowWindow( hWnd, SW_SHOWDEFAULT );
UpdateWindow( hWnd );
//进入消息循环
MSG msg;
ZeroMemory( &msg, sizeof(msg) );
while( msg.message!=WM_QUIT )
{
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
Render(); //渲染场景
}
}
}
}
UnregisterClass( L"ClassName", wc.hInstance );
return 0;
}
Effect代码:
[cpp] view
plain copy
/********************************
* Author: rabbit729
* E-mail: wlq_729@163.com
* Date: 2011-09-03
********************************/
//------------------------------
// 顶点着色器
//------------------------------
float viewport_inv_width;
float viewport_inv_height;
struct VS_OUTPUTSCREEN {
float4 Pos: POSITION;
float2 texCoord: TEXCOORD0;
};
VS_OUTPUTSCREEN vs_mainPassScreen(float4 Pos: POSITION){
VS_OUTPUTSCREEN Out;
Out.Pos = float4(Pos.xy, 0, 1);
Out.texCoord.x = 0.5 * (1 + Pos.x - viewport_inv_width);
Out.texCoord.y = 0.5 * (1 - Pos.y - viewport_inv_height);
return Out;
}
//------------------------------
// 像素着色器
//------------------------------
Texture2D TexScreen;
sampler2D TexMapScreen {
Texture = <TexScreen>;
};
//Laplacian算子盒1
const float4 samples1[5] = {
0.0, 1.0, 0.0, -1.0,
-1.0, 0.0, 0.0, -1.0,
0.0, 0.0, 0.0, 4.0,
1.0, 0.0, 0.0, -1.0,
0.0, 1.0, 0.0, -1.0
};
//Laplacian算子盒2
const float4 samples2[9] = {
-1.0, -1.0, 0.0, -1.0,
0.0, -1.0, 0.0, -1.0,
1.0, 1.0, 0.0, -1.0,
-1.0, 0.0, 0.0, -1.0,
0.0, 0.0, 0.0, 8.0,
1.0, 0.0, 0.0, -1.0,
-1.0, 1.0, 0.0, -1.0,
0.0, 1.0, 0.0, -1.0,
1.0, 1.0, 0.0, -1.0
};
//Laplacian算子盒3
const float4 samples3[9] = {
-1.0, -1.0, 0.0, 1.0,
0.0, -1.0, 0.0, -2.0,
1.0, 1.0, 0.0, 1.0,
-1.0, 0.0, 0.0, -2.0,
0.0, 0.0, 0.0, 4.0,
1.0, 0.0, 0.0, -2.0,
-1.0, 1.0, 0.0, 1.0,
0.0, 1.0, 0.0, -2.0,
1.0, 1.0, 0.0, 1.0
};
float4 ps_mainPassScreen(float2 texCoord: TEXCOORD0) : COLOR
{
//return float4(Intensity.xxx,col.a);
float4 col = float4(0, 0, 0, 0);
for(int i = 0; i < 5; i++)
{
col += samples1[i].w * tex2D(TexMapScreen, texCoord + float2(samples1[i].x*viewport_inv_width,
samples1[i].y*viewport_inv_height));
}
//为了突出显示,此处将结果乘2
return 2.0 * col;
}
//------------------------------
// 效果框架
//------------------------------
technique Screen
{
pass P0
{
VertexShader = compile vs_3_0 vs_mainPassScreen();
PixelShader = compile ps_3_0 ps_mainPassScreen();
}
}
结果:
原图:
处理结果1,采用Laplacin算子1
处理结果2,采用Laplacin算子2
处理结果3,采用Laplacin算子3
说明:
1.可以采用将图像先进行灰度化后再进行边缘检测;
2.关于边缘检测还有其他的算子盒,大家可以根据需要选取不同的算子盒,通过上面的实验可以看出,不同的算子盒适合不同的场景,结果也不同。
http://blog.csdn.net/rabbit729/article/details/8009218
plain copy
/********************************
* Author: rabbit729
* E-mail: wlq_729@163.com
* Date: 2012-09-23
* Description: 图像的边缘检测
********************************/
#include <d3dx9.h>
//-----------------------------------------------------------------------------
// Desc: 全局变量
//-----------------------------------------------------------------------------
LPDIRECT3D9 g_pD3D = NULL; //Direct3D对象
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; //Direct3D设备对象
LPDIRECT3DTEXTURE9 g_pTextureScreen = NULL; //待处理图片
ID3DXEffect* g_pEffect = NULL; //效果指针
//常量句柄
D3DXHANDLE hTechScreen = NULL; //Effect句柄
D3DXHANDLE hTexScreen = NULL; //纹理句柄
D3DXHANDLE hViewPortWidthInv = NULL; //视口宽倒数句柄
D3DXHANDLE hViewPortHeightInv = NULL; //视口高倒数句柄
LPDIRECT3DVERTEXBUFFER9 g_pScreenSpaceQuad = NULL; //背板VB
const int WIDTH = 465;
const int HEIGHT = 669;
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_TEX1)
struct Vertex
{
Vertex(){}
Vertex(float x, float y, float z, float w)
{
_x = x; _y = y; _z = z; _w = w;
}
float _x, _y, _z, _w;
static const DWORD FVF;
};
const DWORD Vertex::FVF = D3DFVF_XYZW;
//-----------------------------------------------------------------------------
// Desc: 设置世界矩阵
//-----------------------------------------------------------------------------
VOID SetWorldMatrix()
{
//创建并设置世界矩阵
D3DXMATRIXA16 matWorld, matRotateX, matRotateY;
D3DXMATRIXA16 matScale;
D3DXMatrixIdentity(&matScale);
matScale._11 = matScale._22 = matScale._33 = 0.5f;
D3DXMatrixIdentity(&matWorld);
D3DXMatrixIdentity(&matRotateX);
D3DXMatrixIdentity(&matRotateY);
D3DXMatrixRotationX( &matRotateX, D3DX_PI / 3.0 );
D3DXMatrixRotationY( &matRotateY, -D3DX_PI / 8.0 );
D3DXMatrixMultiply(&matWorld, &matRotateX, &matRotateY);
D3DXMatrixMultiply(&matWorld, &matScale, &matWorld);
g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
}
//-----------------------------------------------------------------------------
// Desc: 设置观察矩阵和投影矩阵
//-----------------------------------------------------------------------------
VOID SetViewAndProjMatrix()
{
//创建并设置观察矩阵
D3DXVECTOR3 vEyePt( 0.0f, 0.0f,-250.0f );
D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
D3DXMATRIXA16 matView;
D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
//创建并设置投影矩阵
D3DXMATRIXA16 matProj;
D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 1000.0f );
g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
}
//-----------------------------------------------------------------------------
// Desc: 初始化Direct3D
//-----------------------------------------------------------------------------
HRESULT InitD3D( HWND hWnd )
{
//创建Direct3D对象, 该对象用于创建Direct3D设备对象
if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
return E_FAIL;
//设置D3DPRESENT_PARAMETERS结构, 准备创建Direct3D设备对象
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
//创建Direct3D设备对象
if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &g_pd3dDevice ) ) )
{
return E_FAIL;
}
//创建Effect
ID3DXBuffer* errBuffer = NULL;
if (FAILED(D3DXCreateEffectFromFile(g_pd3dDevice, L"edgedetect.fx", NULL, NULL, D3DXSHADER_DEBUG | D3DXSHADER_SKIPOPTIMIZATION, NULL, &g_pEffect, &errBuffer)))
{
if (errBuffer)
{
MessageBox(0, (LPCTSTR)errBuffer->GetBufferPointer(), 0, 0);
errBuffer->Release();
}
return E_FAIL;
}
//获取常量句柄
hTechScreen = g_pEffect->GetTechniqueByName("Screen");
hTexScreen = g_pEffect->GetParameterByName(0, "TexScreen");
hViewPortWidthInv = g_pEffect->GetParameterByName(0, "viewport_inv_width");
hViewPortHeightInv = g_pEffect->GetParameterByName(0, "viewport_inv_height");
//设置环境光
g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0xffffffff );
//设置观察矩阵和投影矩阵
SetViewAndProjMatrix();
return S_OK;
}
//-----------------------------------------------------------------------------
// Desc: 创建场景图形
//-----------------------------------------------------------------------------
HRESULT InitGeometry()
{
// 创建屏幕板
g_pd3dDevice->CreateVertexBuffer(
6 * sizeof(Vertex),
D3DUSAGE_WRITEONLY,
Vertex::FVF,
D3DPOOL_MANAGED,
&g_pScreenSpaceQuad,
0);
Vertex* vertices;
g_pScreenSpaceQuad->Lock(0, 0, (void**)&vertices, 0);
vertices[0] = Vertex(-1.0f, 1.0f, 0.5f, 1.0f);
vertices[1] = Vertex(1.0f, 1.0f, 0.5f, 1.0f);
vertices[2] = Vertex( 1.0f, -1.0f, 0.5f, 1.0f);
vertices[3] = Vertex(-1.0f, 1.0f, 0.5f, 1.0f);
vertices[4] = Vertex( 1.0f, -1.0f, 0.5f, 1.0f);
vertices[5] = Vertex( -1.0f, -1.0f, 0.5f, 1.0f);
g_pScreenSpaceQuad->Unlock();
//加载纹理
HRESULT hr = D3DXCreateTextureFromFile(g_pd3dDevice, L"meinv.jpg", &g_pTextureScreen);
if (FAILED(hr))
{
return E_FAIL;
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Desc: 释放创建的对象
//-----------------------------------------------------------------------------
VOID Cleanup()
{
if (g_pScreenSpaceQuad != NULL)
{
g_pScreenSpaceQuad->Release();
}
if (g_pTextureScreen != NULL)
{
g_pTextureScreen->Release();
}
if (g_pEffect != NULL)
{
g_pEffect->Release();
}
//释放Direct3D设备对象
if( g_pd3dDevice != NULL )
g_pd3dDevice->Release();
//释放Direct3D对象
if( g_pD3D != NULL )
g_pD3D->Release();
}
VOID RenderScreen()
{
//将RenderTarget作为纹理
g_pEffect->SetTexture(hTexScreen, g_pTextureScreen);
float fWidthInv = 1.0f / WIDTH;
float fHeightInv = 1.0f / HEIGHT;
g_pEffect->SetFloat(hViewPortWidthInv, fWidthInv);
g_pEffect->SetFloat(hViewPortHeightInv, fHeightInv);
g_pd3dDevice->SetStreamSource(0, g_pScreenSpaceQuad, 0, sizeof(Vertex));
g_pd3dDevice->SetFVF(Vertex::FVF);
// 设置要使用的Technique
g_pEffect->SetTechnique(hTechScreen);
UINT numPasses = 0;
g_pEffect->Begin(&numPasses, 0);
for (int i = 0; i < numPasses; i++)
{
g_pEffect->BeginPass(i);
g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
g_pEffect->EndPass();
}
g_pEffect->End();
}
//-----------------------------------------------------------------------------
// Desc: 渲染场景
//-----------------------------------------------------------------------------
VOID Render()
{
// 获取backbuffer
LPDIRECT3DSURFACE9 pBackbuffer;
g_pd3dDevice->GetRenderTarget(0, &pBackbuffer);
//开始渲染场景
if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
{
//设回backbuffer
g_pd3dDevice->SetRenderTarget(0, pBackbuffer);
RenderScreen();
//场景渲染结束
g_pd3dDevice->EndScene();
}
//在屏幕上显示场景
g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}
//-----------------------------------------------------------------------------
// Desc: 窗口过程, 处理消息
//-----------------------------------------------------------------------------
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
switch( msg )
{
case WM_DESTROY:
Cleanup();
PostQuitMessage( 0 );
return 0;
}
return DefWindowProc( hWnd, msg, wParam, lParam );
}
//-----------------------------------------------------------------------------
// Desc: 入口函数
//-----------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{
//注册窗口类
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
L"ClassName", NULL };
RegisterClassEx( &wc );
//创建窗口
HWND hWnd = CreateWindow( L"ClassName", L"图像二值化",
WS_OVERLAPPEDWINDOW, 200, 100, WIDTH, HEIGHT,
GetDesktopWindow(), NULL, wc.hInstance, NULL );
//初始化Direct3D
if( SUCCEEDED( InitD3D( hWnd ) ) )
{
//创建场景图形
if( SUCCEEDED( InitGeometry() ) )
{
//显示窗口
ShowWindow( hWnd, SW_SHOWDEFAULT );
UpdateWindow( hWnd );
//进入消息循环
MSG msg;
ZeroMemory( &msg, sizeof(msg) );
while( msg.message!=WM_QUIT )
{
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
Render(); //渲染场景
}
}
}
}
UnregisterClass( L"ClassName", wc.hInstance );
return 0;
}
Effect代码:
[cpp] view
plain copy
/********************************
* Author: rabbit729
* E-mail: wlq_729@163.com
* Date: 2011-09-03
********************************/
//------------------------------
// 顶点着色器
//------------------------------
float viewport_inv_width;
float viewport_inv_height;
struct VS_OUTPUTSCREEN {
float4 Pos: POSITION;
float2 texCoord: TEXCOORD0;
};
VS_OUTPUTSCREEN vs_mainPassScreen(float4 Pos: POSITION){
VS_OUTPUTSCREEN Out;
Out.Pos = float4(Pos.xy, 0, 1);
Out.texCoord.x = 0.5 * (1 + Pos.x - viewport_inv_width);
Out.texCoord.y = 0.5 * (1 - Pos.y - viewport_inv_height);
return Out;
}
//------------------------------
// 像素着色器
//------------------------------
Texture2D TexScreen;
sampler2D TexMapScreen {
Texture = <TexScreen>;
};
//Laplacian算子盒1
const float4 samples1[5] = {
0.0, 1.0, 0.0, -1.0,
-1.0, 0.0, 0.0, -1.0,
0.0, 0.0, 0.0, 4.0,
1.0, 0.0, 0.0, -1.0,
0.0, 1.0, 0.0, -1.0
};
//Laplacian算子盒2
const float4 samples2[9] = {
-1.0, -1.0, 0.0, -1.0,
0.0, -1.0, 0.0, -1.0,
1.0, 1.0, 0.0, -1.0,
-1.0, 0.0, 0.0, -1.0,
0.0, 0.0, 0.0, 8.0,
1.0, 0.0, 0.0, -1.0,
-1.0, 1.0, 0.0, -1.0,
0.0, 1.0, 0.0, -1.0,
1.0, 1.0, 0.0, -1.0
};
//Laplacian算子盒3
const float4 samples3[9] = {
-1.0, -1.0, 0.0, 1.0,
0.0, -1.0, 0.0, -2.0,
1.0, 1.0, 0.0, 1.0,
-1.0, 0.0, 0.0, -2.0,
0.0, 0.0, 0.0, 4.0,
1.0, 0.0, 0.0, -2.0,
-1.0, 1.0, 0.0, 1.0,
0.0, 1.0, 0.0, -2.0,
1.0, 1.0, 0.0, 1.0
};
float4 ps_mainPassScreen(float2 texCoord: TEXCOORD0) : COLOR
{
//return float4(Intensity.xxx,col.a);
float4 col = float4(0, 0, 0, 0);
for(int i = 0; i < 5; i++)
{
col += samples1[i].w * tex2D(TexMapScreen, texCoord + float2(samples1[i].x*viewport_inv_width,
samples1[i].y*viewport_inv_height));
}
//为了突出显示,此处将结果乘2
return 2.0 * col;
}
//------------------------------
// 效果框架
//------------------------------
technique Screen
{
pass P0
{
VertexShader = compile vs_3_0 vs_mainPassScreen();
PixelShader = compile ps_3_0 ps_mainPassScreen();
}
}
结果:
原图:
处理结果1,采用Laplacin算子1
处理结果2,采用Laplacin算子2
处理结果3,采用Laplacin算子3
说明:
1.可以采用将图像先进行灰度化后再进行边缘检测;
2.关于边缘检测还有其他的算子盒,大家可以根据需要选取不同的算子盒,通过上面的实验可以看出,不同的算子盒适合不同的场景,结果也不同。
http://blog.csdn.net/rabbit729/article/details/8009218
相关文章推荐
- 图像处理常用算法GPU实现二:基于微分的边缘检测
- 图像处理常用算法GPU实现三:基于模板匹配的边缘检测
- 图像处理常用算法GPU实现三:基于模板匹配的边缘检测
- 图像处理常用算法GPU实现四:基于中值滤波的二值图像平滑
- 图像处理常用算法GPU实现四:基于中值滤波的二值图像平滑
- 【图像处理】 常用边缘检测算法对比分析
- 数字图像处理常用算法实现-霍夫线检测
- 图像处理常用算法GPU实现一:图像二值化
- 图像处理常用算法GPU实现五:图像对比度增强
- 图像处理常用算法GPU实现一:图像二值化
- 图像边缘检测(Canny 算法)的Java实现
- 图像sobel、laplacian、canny边缘检测算法基础实现
- 五种基于RGB色彩空间统计的皮肤检测算法 分类: 视频图像处理 2015-07-24 10:18 48人阅读 评论(0) 收藏
- 常用图像边缘检测、增强MATLAB实现
- 图像处理之基础---肤色检测算法 - 基于不同颜色空间简单区域划分的皮肤检测算法
- <<一种基于δ函数的图象边缘检测算法>>一文算法的实现。
- 基于GPU平台利用CUDA加速图像处理算法 实时处理高清图像
- 基于贝叶斯决策的彩色图像中皮肤区域检测算法研究与实现
- 图像边缘检测(Canny 算法)的Java实现
- 图像处理算法4——Sobel 边缘检测算子