📄 splitproc.cpp
字号:
// ************************************************************************
// 文件名:SplitProc.cpp
//
// 图像分割处理函数库:
//
// RgnGrow() - 区域生长
// ContourDIB() - 轮廓提取
// TraceDIB() - 边界跟踪
// Sobel() - 索贝尔算子的边缘检测
// Roberts() - 罗伯特交叉算子的边缘检测
// Prewitt() - 蒲瑞维特算子的边缘检测
// Kirsch() - Kirsch算子的边缘检测
// Laplacian() - 拉普拉斯算子的边缘检测
// GuassLaplacian() - 高斯——拉普拉斯算子的边缘检测
// Hough() - 哈夫变换检测圆周(r = 40)
// Threshold() - 阀值化区域分割
//
//
// ************************************************************************
#include "stdafx.h"
#include "DIP_System.h"
#include "SplitProc.h"
#include "math.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CSplitProc
CSplitProc::CSplitProc()
{
}
CSplitProc::~CSplitProc()
{
}
BEGIN_MESSAGE_MAP(CSplitProc, CWnd)
//{{AFX_MSG_MAP(CSplitProc)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
////////////////////////////////////////////////////////////////////////////
// 功能模块开始 //
////////////////////////////////////////////////////////////////////////////
/*************************************************************************
*
* 函数名称:
* RgnGrow()
*
* 参数:
* HDIB hDIB - 待处理的DIB
* COLORREF clrSeed_I - 种子点一的RGB值
* COLORREF clrSeed_II- 种子点二的RGB值
*
* 返回值:
* void - 无返回值
*
* 说明:
* 该函数将彩色位图转化为灰度图像。
*
************************************************************************/
void CSplitProc::RgnGrow(HDIB hDIB, COLORREF clrSeed_I, COLORREF clrSeed_II)
{
// 循环变量
LONG i;
LONG j;
// 指向DIB的指针
LPBYTE lpDIB;
// 指向DIB象素指针
LPBYTE lpDIBBits;
// 计算种子点一的灰度值
unsigned char R_I = GetRValue(clrSeed_I);
unsigned char G_I = GetGValue(clrSeed_I);
unsigned char B_I = GetBValue(clrSeed_I);
float fY_I = (9798.0f * R_I + 19235.0f * G_I + 3735.0f * B_I) / 32768.0f;
// 计算种子点二的灰度值
unsigned char R_II = GetRValue(clrSeed_II);
unsigned char G_II = GetGValue(clrSeed_II);
unsigned char B_II = GetBValue(clrSeed_II);
float fY_II = (9798.0f * R_II + 19235.0f * G_II + 3735.0f * B_II) / 32768.0f;
// 锁定DIB
lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL) hDIB);
// 找到DIB图像象素起始位置
lpDIBBits = m_clsDIB.FindDIBBits(lpDIB);
// 判断是否是24-bpp位图
if (m_clsDIB.DIBBitCount(lpDIB) != 24)
{
// 提示用户
MessageBox("请先将其转换为24位色位图,再进行处理!", "系统提示" , MB_ICONINFORMATION | MB_OK);
// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);
// 返回
return;
}
// 更改光标形状
BeginWaitCursor();
// DIB的宽度
LONG lWidth = m_clsDIB.DIBWidth(lpDIB);
// DIB的高度
LONG lHeight = m_clsDIB.DIBHeight(lpDIB);
// 计算图像每行的字节数
LONG lLineBytes = WIDTHBYTES(lWidth * 24);
// 对各像素进行灰度转换
for (i = 0; i < lHeight; i ++)
{
for (j = 0; j < lLineBytes; j ++)
{
//获取各颜色分量
unsigned char R = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
j++;
unsigned char G = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
j++;
unsigned char B = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
//计算当前点灰度值
unsigned char Y = (9798 * R + 19235 * G + 3735 * B) / 32768;
if (abs(Y - fY_I) < abs(Y - fY_II))
{
//当前点同种子一灰度值比较接近
//将种子一的颜色赋给当前像素
*((unsigned char *)lpDIBBits + lLineBytes * i + j - 2) = R_I;
*((unsigned char *)lpDIBBits + lLineBytes * i + j - 1) = G_I;
*((unsigned char *)lpDIBBits + lLineBytes * i + j ) = B_I;
}
else
{
//当前点同种子二灰度值比较接近
//将种子二的颜色赋给当前像素
*((unsigned char *)lpDIBBits + lLineBytes * i + j - 2) = R_II;
*((unsigned char *)lpDIBBits + lLineBytes * i + j - 1) = G_II;
*((unsigned char *)lpDIBBits + lLineBytes * i + j ) = B_II;
}
}
}
// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);
// 恢复光标
EndWaitCursor();
}
/*************************************************************************
*
* 函数名称:
* Sobel()
*
* 参数:
* HDIB hDIB - 待处理的DIB
*
* 返回值:
* void - 无返回值
*
* 说明:
* 对图像进行索贝尔算子的边缘检测
*
************************************************************************/
void CSplitProc::Sobel(HDIB hDIB)
{
// 循环变量
LONG i;
LONG j;
LONG k;
LONG l;
// 指向DIB的指针
LPBYTE lpDIB;
// 指向DIB象素指针
LPBYTE lpDIBBits;
// 锁定DIB
lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL) hDIB);
// 找到DIB图像象素起始位置
lpDIBBits = m_clsDIB.FindDIBBits(lpDIB);
// 判断是否是24-bpp位图
if (m_clsDIB.DIBBitCount(lpDIB) != 24)
{
// 提示用户
MessageBox("请先将其转换为24位色位图,再进行处理!", "系统提示" , MB_ICONINFORMATION | MB_OK);
// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);
// 返回
return;
}
// 更改光标形状
BeginWaitCursor();
// DIB的宽度
LONG lWidth = m_clsDIB.DIBWidth(lpDIB);
// DIB的高度
LONG lHeight = m_clsDIB.DIBHeight(lpDIB);
// 计算图像每行的字节数
LONG lLineBytes = WIDTHBYTES(lWidth * 24);
// 不能用char,也不能用::strcpy()
unsigned char* m_temp;
m_temp=new unsigned char [lLineBytes * lHeight];
// 中间变量
int v_r_v, v_g_v, v_b_v, g_v;
int v_r_h, v_g_h, v_b_h, g_h;
// 复制图象数据到中间缓存
for (i = 0; i < lLineBytes * lHeight; i++)
m_temp[i] = *(lpDIBBits + i);
// 3X3 模版
for (i = 0; i < lWidth; i++) //被处理像素在i列
{
for (j = 0; j < lHeight; j++) //被处理像素在j行
{
v_r_v = v_g_v = v_b_v = v_r_h = v_g_h = v_b_h = 0;
for (k = i - 1; k < i + 2; k++) //3*3模版
{
for (l = j - 1; l < j + 2; l++)
{
// 防止内存溢出
if (k >= 0 && l >= 0 && k < lWidth && l < lHeight)
{
// 检测模版
if (k == i - 1)
{
if (l == j)
g_v = -2;
else
g_v = -1;
}
if (k == i + 1)
{
if (l == j)
g_v = 2;
else
g_v = 1;
}
if (k == i)
g_v = 0;
if (l == j - 1)
{
if (k == i)
g_h = 2;
else
g_h = 1;
}
if (l == j + 1)
{
if (k == i)
g_h = -2;
else
g_h = -1;
}
if (l == j)
g_h = 0;
v_r_v += *(lpDIBBits + l * lLineBytes + k * 3) * g_v;
v_r_h += *(lpDIBBits + l * lLineBytes + k * 3) * g_h;
v_g_v += *(lpDIBBits + l * lLineBytes + k * 3 + 1) * g_v;
v_g_h += *(lpDIBBits + l * lLineBytes + k * 3 + 1) * g_h;
v_b_v += *(lpDIBBits + l * lLineBytes + k * 3 + 2) * g_v;
v_b_h += *(lpDIBBits + l * lLineBytes + k * 3 + 2) * g_h;
}
}
}
m_temp[j * lLineBytes + i * 3] = (int)sqrt(v_r_v * v_r_v + v_r_h * v_r_h);
m_temp[j * lLineBytes + i * 3 + 1] = (int)sqrt(v_g_v * v_g_v + v_g_h * v_g_h);
m_temp[j * lLineBytes + i * 3 + 2] = (int)sqrt(v_b_v * v_b_v + v_b_h * v_b_h);
}
}
// 回存处理结果到DIB
for(i = 0; i < lLineBytes * lHeight; i++)
*(lpDIBBits + i) = m_temp[i];
// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);
// 释放内存
delete[] m_temp;
// 恢复光标
EndWaitCursor();
}
/*************************************************************************
*
* 函数名称:
* Prewitt()
*
* 参数:
* HDIB hDIB - 待处理的DIB
*
* 返回值:
* void - 无返回值
*
* 说明:
* 对图像进行蒲瑞维特算子的边缘检测
*
************************************************************************/
void CSplitProc::Prewitt(HDIB hDIB)
{
// 循环变量
LONG i;
LONG j;
LONG k;
LONG l;
// 指向DIB的指针
LPBYTE lpDIB;
// 指向DIB象素指针
LPBYTE lpDIBBits;
// 锁定DIB
lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL) hDIB);
// 找到DIB图像象素起始位置
lpDIBBits = m_clsDIB.FindDIBBits(lpDIB);
// 判断是否是24-bpp位图
if (m_clsDIB.DIBBitCount(lpDIB) != 24)
{
// 提示用户
MessageBox("请先将其转换为24位色位图,再进行处理!", "系统提示" , MB_ICONINFORMATION | MB_OK);
// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);
// 返回
return;
}
// 更改光标形状
BeginWaitCursor();
// DIB的宽度
LONG lWidth = m_clsDIB.DIBWidth(lpDIB);
// DIB的高度
LONG lHeight = m_clsDIB.DIBHeight(lpDIB);
// 计算图像每行的字节数
LONG lLineBytes = WIDTHBYTES(lWidth * 24);
// 不能用char,也不能用::strcpy()
unsigned char* m_temp;
m_temp = new unsigned char [lLineBytes * lHeight];
// 中间变量
int v_r_v, v_g_v, v_b_v, g_v;
int v_r_h, v_g_h, v_b_h, g_h;
// 复制图象数据到中间缓存
for (i = 0; i < lLineBytes * lHeight; i++)
m_temp[i] = *(lpDIBBits + i);
// 3X3 模版
for (i = 0; i < lWidth; i++) //被处理像素在i列
{
for (j = 0; j < lHeight; j++) //被处理像素在j行
{
v_r_v = v_g_v = v_b_v = v_r_h = v_g_h = v_b_h = 0;
for (k = i - 1; k < i + 2; k++) //3*3模版
{
for (l = j - 1; l < j + 2; l++)
{
// 防止内存溢出
if (k >= 0 && l >= 0 && k < lWidth && l < lHeight)
{
// 检测模版
if (k == i - 1)
g_v = -1;
if (k == i + 1)
g_v = 1;
if (k == i)
g_v = 0;
if (l == j - 1)
g_h = 1;
if (l == j + 1)
g_h = -1;
if (l == j)
g_h = 0;
v_r_v += *(lpDIBBits + l * lLineBytes + k * 3) * g_v;
v_r_h += *(lpDIBBits + l * lLineBytes + k * 3) * g_h;
v_g_v += *(lpDIBBits + l * lLineBytes + k * 3 + 1) * g_v;
v_g_h += *(lpDIBBits + l * lLineBytes + k * 3 + 1) * g_h;
v_b_v += *(lpDIBBits + l * lLineBytes + k * 3 + 2) * g_v;
v_b_h += *(lpDIBBits + l * lLineBytes + k * 3 + 2) * g_h;
}
}
}
m_temp[j * lLineBytes + i * 3] = (int)sqrt(v_r_v * v_r_v + v_r_h * v_r_h);
m_temp[j * lLineBytes + i * 3 + 1] = (int)sqrt(v_g_v * v_g_v + v_g_h * v_g_h);
m_temp[j * lLineBytes + i * 3 + 2] = (int)sqrt(v_b_v * v_b_v + v_b_h * v_b_h);
}
}
// 回存处理结果到DIB
for(i = 0; i < lLineBytes * lHeight; i++)
*(lpDIBBits + i) = m_temp[i];
// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);
// 释放内存
delete[] m_temp;
// 恢复光标
EndWaitCursor();
}
/*************************************************************************
*
* 函数名称:
* Roberts()
*
* 参数:
* HDIB hDIB - 待处理的DIB
*
* 返回值:
* void - 无返回值
*
* 说明:
* 对图像进行罗伯特交叉算子的边缘检测
*
************************************************************************/
void CSplitProc::Roberts(HDIB hDIB)
{
// 循环变量
LONG i;
LONG j;
LONG k;
LONG l;
// 指向DIB的指针
LPBYTE lpDIB;
// 指向DIB象素指针
LPBYTE lpDIBBits;
// 锁定DIB
lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL) hDIB);
// 找到DIB图像象素起始位置
lpDIBBits = m_clsDIB.FindDIBBits(lpDIB);
// 判断是否是24-bpp位图
if (m_clsDIB.DIBBitCount(lpDIB) != 24)
{
// 提示用户
MessageBox("请先将其转换为24位色位图,再进行处理!", "系统提示" , MB_ICONINFORMATION | MB_OK);
// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);
// 返回
return;
}
// 更改光标形状
BeginWaitCursor();
// DIB的宽度
LONG lWidth = m_clsDIB.DIBWidth(lpDIB);
// DIB的高度
LONG lHeight = m_clsDIB.DIBHeight(lpDIB);
// 计算图像每行的字节数
LONG lLineBytes = WIDTHBYTES(lWidth * 24);
// 不能用char,也不能用::strcpy()
unsigned char* m_temp;
m_temp = new unsigned char [lLineBytes * lHeight];
// 中间变量
int v_r_v, v_g_v, v_b_v, g_v;
int v_r_h, v_g_h, v_b_h, g_h;
// 复制图象数据到中间缓存
for (i = 0; i < lLineBytes * lHeight; i++)
m_temp[i] = *(lpDIBBits + i);
// 2X2 模版
for (i = 0; i < lWidth; i++) //被处理像素在i列
{
for (j = 0; j < lHeight; j++) //被处理像素在j行
{
v_r_v = v_g_v = v_b_v = v_r_h = v_g_h = v_b_h = 0;
for (k = i - 1; k < i + 1; k++) //2*2模版
{
for (l = j - 1; l < j + 1; l++)
{
// 防止内存溢出
if (k >= 0 && l >= 0 && k < lWidth && l < lHeight)
{
// 检测模版
if (k == i - 1 && l == j - 1)
g_v = 1;
else if (k == i && l == j)
g_v = -1;
else
g_v = 0;
if(k == i - 1 && l == j)
g_h = -1;
else if (k == i && l == j - 1)
g_h = 1;
else
g_h = 0;
v_r_v += *(lpDIBBits + l * lLineBytes + k * 3) * g_v;
v_r_h += *(lpDIBBits + l * lLineBytes + k * 3) * g_h;
v_g_v += *(lpDIBBits + l * lLineBytes + k * 3 + 1) * g_v;
v_g_h += *(lpDIBBits + l * lLineBytes + k * 3 + 1) * g_h;
v_b_v += *(lpDIBBits + l * lLineBytes + k * 3 + 2) * g_v;
v_b_h += *(lpDIBBits + l * lLineBytes + k * 3 + 2) * g_h;
}
}
}
m_temp[j * lLineBytes + i * 3] = (int)sqrt(v_r_v * v_r_v + v_r_h * v_r_h);
m_temp[j * lLineBytes + i * 3 + 1] = (int)sqrt(v_g_v * v_g_v + v_g_h * v_g_h);
m_temp[j * lLineBytes + i * 3 + 2] = (int)sqrt(v_b_v * v_b_v + v_b_h * v_b_h);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -