📄 bmpproc.cpp
字号:
// BmpProc.cpp : implementation file
//
#include "stdafx.h"
#include "神经网络作业.h"
#include "BmpProc.h"
#include "神经网络作业Doc.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CBmpProc
CBmpProc::CBmpProc()
{
}
CBmpProc::~CBmpProc()
{
}
BEGIN_MESSAGE_MAP(CBmpProc, CWnd)
//{{AFX_MSG_MAP(CBmpProc)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CBmpProc message handlers
void CBmpProc::ToGray(HDIB hDIB)
{
LPBYTE lpDIB;
// 由DIB句柄得到DIB指针并锁定DIB
lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL)hDIB);
// 指向DIB象素数据区的指针
LPBYTE lpDIBBits;
// 指向DIB象素的指针
BYTE * lpSrc;
// 图像宽度
LONG lWidth;
// 图像高度
LONG lHeight;
// 图像每行的字节数
LONG lLineBytes;
// 指向BITMAPINFO结构的指针(Win3.0)
LPBITMAPINFO lpbmi;
// 指向BITMAPCOREINFO结构的指针
LPBITMAPCOREINFO lpbmc;
// 获取指向BITMAPINFO结构的指针(Win3.0)
lpbmi = (LPBITMAPINFO)lpDIB;
// 获取指向BITMAPCOREINFO结构的指针
lpbmc = (LPBITMAPCOREINFO)lpDIB;
// 灰度映射表
BYTE bMap[256];
// 计算灰度映射表(保存各个颜色的灰度值),并更新DIB调色板
int i,j;
for (i = 0; i < 256; i ++)
{
// 计算该颜色对应的灰度值
bMap[i] = (BYTE)(0.299 * lpbmi->bmiColors[i].rgbRed +
0.587 * lpbmi->bmiColors[i].rgbGreen +
0.114 * lpbmi->bmiColors[i].rgbBlue + 0.5);
// 更新DIB调色板红色分量
lpbmi->bmiColors[i].rgbRed = i;
// 更新DIB调色板绿色分量
lpbmi->bmiColors[i].rgbGreen = i;
// 更新DIB调色板蓝色分量
lpbmi->bmiColors[i].rgbBlue = i;
// 更新DIB调色板保留位
lpbmi->bmiColors[i].rgbReserved = 0;
}
// 找到DIB图像象素起始位置
lpDIBBits =m_clsDIB.FindDIBBits(lpDIB);;
// DIB的宽度
lWidth = m_clsDIB.DIBWidth(lpDIB);
// DIB的高度
lHeight = m_clsDIB.DIBHeight(lpDIB);
// 计算图像每行的字节数
lLineBytes = WIDTHBYTES(lWidth * 8);
// 更换每个象素的颜色索引(即按照灰度映射表换成灰度值)
//逐行扫描
for(i = 0; i < lHeight; i++)
{
//逐列扫描
for(j = 0; j < lWidth; j++)
{
// 指向DIB第i行,第j个象素的指针
lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;
// 变换
*lpSrc = bMap[*lpSrc];
}
}
//解除锁定
::GlobalUnlock ((HGLOBAL)hDIB);
}
void CBmpProc::ConvertToWBlk(HDIB hDIB)
{
// 指向DIB的指针
LPBYTE lpDIB;
// 由DIB句柄得到DIB指针并锁定DIB
lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL)hDIB);
// 指向DIB象素数据区的指针
LPBYTE lpDIBBits;
// 指向DIB象素的指针
BYTE * lpSrc;
// 图像宽度
LONG lWidth;
// 图像高度
LONG lHeight;
// 图像每行的字节数
LONG lLineBytes;
// 找到DIB图像象素起始位置
lpDIBBits = m_clsDIB.FindDIBBits(lpDIB);
// 获取图像宽度
lWidth = m_clsDIB.DIBWidth(lpDIB);
// 获取图像高度
lHeight = m_clsDIB.DIBHeight(lpDIB);
// 计算图像每行的字节数
lLineBytes = WIDTHBYTES(lWidth * 8);
// 更换每个象素的颜色索引(即按照灰度映射表换成灰度值)
int i,j;
//逐行扫描
for(i = 0; i < lHeight; i++)
{
//逐列扫描
for(j = 0; j < lWidth; j++)
{
// 指向DIB第i行,第j个象素的指针
lpSrc = (unsigned char*)lpDIBBits + lLineBytes * i + j;
// 二值化处理
//大于220,设置为255,即白点
if(*lpSrc>220) *lpSrc=255;
//否则设置为0,即黑点
else *lpSrc=0;
}
}
//解除锁定
::GlobalUnlock((HGLOBAL)hDIB);
}
void CBmpProc::Sharp(HDIB hDIB)
{
// 指向DIB的指针
LPBYTE lpDIB=(LPBYTE) ::GlobalLock((HGLOBAL)hDIB);
// 指向DIB象素指针
LPBYTE lpDIBBits;
// 找到DIB图像象素起始位置
lpDIBBits = m_clsDIB.FindDIBBits(lpDIB);
//获取图像的宽度
LONG lWidth= m_clsDIB.DIBWidth (lpDIB);
//获取图像的长度
LONG lHeight= m_clsDIB.DIBHeight (lpDIB);
// 阈值
BYTE bThre = 2;
// 调用GradSharp()函数进行梯度板锐化
// 指向源图像的指针
unsigned char* lpSrc;
unsigned char* lpSrc1;
unsigned char* lpSrc2;
// 循环变量
LONG i;
LONG j;
// 图像每行的字节数
LONG lLineBytes;
// 中间变量
BYTE bTemp;
// 计算图像每行的字节数
lLineBytes = WIDTHBYTES(lWidth * 8);
// 每行
for(i = 0; i < lHeight; i++)
{
// 每列
for(j = 0; j < lWidth; j++)
{
// 指向DIB第i行,第j个象素的指针
lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;
// 指向DIB第i+1行,第j个象素的指针
lpSrc1 = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 2 - i) + j;
// 指向DIB第i行,第j+1个象素的指针
lpSrc2 = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j + 1;
//计算梯度值
bTemp = abs((*lpSrc)-(*lpSrc1)) + abs((*lpSrc)-(*lpSrc2));
// 判断是否小于阈值
if (bTemp < 255)
{
// 判断是否大于阈值,对于小于情况,灰度值不变。
if (bTemp >= bThre)
{
// 直接赋值为bTemp
*lpSrc = bTemp;
}
}
else
{
// 直接赋值为255
*lpSrc = 255;
}
}
}
//最后还要处理一下图像中最下面那行
for(j = 0; j < lWidth; j++)
{
//指向最下边一行,第j个象素的指针
lpSrc = (unsigned char*)lpDIBBits + lLineBytes * 0 + j;
//将此位置的象素设置为255,即白点
*lpSrc=255;
}
//解除锁定
::GlobalUnlock ((HGLOBAL)hDIB);
}
void CBmpProc::Denoise(HDIB hDIB)
{
// 指向DIB的指针
LPBYTE lpDIB=(LPBYTE) ::GlobalLock((HGLOBAL)hDIB);
// 指向DIB象素指针
LPBYTE lpDIBBits;
// 找到DIB图像象素数据区的起始位置
lpDIBBits = m_clsDIB.FindDIBBits(lpDIB);
//获得图像的长度
LONG lWidth= m_clsDIB.DIBWidth (lpDIB);
//获得图像的高度
LONG lHeight= m_clsDIB.DIBHeight (lpDIB);
//设置判定噪声的长度阈值为15
//即如果与考察点相连接的黑点的数目小于15则认为考察点是噪声点
int length=15;
// 循环变量
m_lianXuShu=0;
LONG i;
LONG j;
LONG k;
// 图像每行的字节数
LONG lLineBytes;
// 计算图像每行的字节数
lLineBytes = WIDTHBYTES(lWidth * 8);
LPSTR lpSrc;
//开辟一块用来存放标志的内存数组
LPBYTE lplab = new BYTE[lHeight * lWidth];
//开辟一块用来保存离散判定结果的内存数组
bool *lpTemp = new bool[lHeight * lWidth];
//初始化标志数组
for (i=0;i<lHeight*lWidth;i++)
{
//将所有的标志位设置为非
lplab[i] = false;
}
//用来存放离散点的坐标的数组
CPoint lab[21];
//为循环变量赋初始值
k=0;
//扫描整个图像
//逐行扫描
for(i =0;i<lHeight;i++)
{
//逐行扫描
for(j=0;j<lWidth;j++)
{
//先把标志位置false
for(k=0;k<m_lianXuShu;k++)
lplab[lab[k].y * lWidth + lab[k].x] = false;
//连续数置0
m_lianXuShu =0;
//进行离散性判断
lpTemp[i*lWidth+j] = DeleteScaterJudge(lpDIBBits,(WORD)lLineBytes,lplab,lWidth,lHeight,j,i,lab,length);
}
}
//扫描整个图像,把离散点填充成白色
//逐行扫描
for(i = 0;i<lHeight;i++)
{
//逐列扫描
for(j=0;j<lWidth;j++)
{
//查看标志位,如果为非则将此点设为白点
if(lpTemp[i*lWidth+j] == false)
{
//指向第i行第j个象素的指针
lpSrc=(char*)lpDIBBits + lLineBytes * i + j;
//将此象素设为白点
*lpSrc=BYTE(255);
}
}
}
//解除锁定
::GlobalUnlock ((HGLOBAL)hDIB);
}
bool CBmpProc::DeleteScaterJudge(LPBYTE lpDIBBits, WORD lLineBytes, LPBYTE lplab, int lWidth, int lHeight, int x, int y, CPoint lab[], int lianXuShu)
{
//如果连续长度满足要求,说明不是离散点,返回
if(m_lianXuShu>=lianXuShu)
return TRUE;
//长度加一
m_lianXuShu++;
//设定访问标志
lplab[lWidth * y +x] = true;
//保存访问点坐标
lab[m_lianXuShu-1].x = x;
lab[m_lianXuShu-1].y = y;
//象素的灰度值
int gray;
//指向象素的指针
LPSTR lpSrc;
//长度判定
//如果连续长度满足要求,说明不是离散点,返回
if(m_lianXuShu>=lianXuShu)
return TRUE;
//下面进入递归
else
{
//考察上下左右以及左上、右上、左下、右下八个方向
//如果是黑色点,则调用函数自身进行递归
//考察下面点
lpSrc=(char*)lpDIBBits + lLineBytes * (y-1) + x;
//传递灰度值
gray=*lpSrc;
//如果点在图像内、颜色为黑色并且没有被访问过
if(y-1 >=0 && gray == 0 && lplab[(y-1)*lWidth+x] == false)
//进行递归处理
DeleteScaterJudge(lpDIBBits,lLineBytes,lplab,lWidth,lHeight,x,y-1,lab,lianXuShu);
//判断长度
//如果连续长度满足要求,说明不是离散点,返回
if(m_lianXuShu>=lianXuShu)
return TRUE;
//左下点
lpSrc=(char*)lpDIBBits + lLineBytes * (y-1) + x-1;
//传递灰度值
gray=*lpSrc;
//如果点在图像内、颜色为黑色并且没有被访问过
if(y-1 >=0 && x-1 >=0 && gray== 0 && lplab[(y-1)*lWidth+x-1] == false)
//进行递归处理
DeleteScaterJudge(lpDIBBits,lLineBytes,lplab,lWidth,lHeight,x-1,y-1,lab,lianXuShu);
//判断长度
//如果连续长度满足要求,说明不是离散点,返回
if(m_lianXuShu>=lianXuShu)
return TRUE;
//左边
lpSrc=(char*)lpDIBBits + lLineBytes * y + x-1;
//传递灰度值
gray=*lpSrc;
//如果点在图像内、颜色为黑色并且没有被访问过
if(x-1 >=0 && gray== 0 && lplab[y*lWidth+x-1] == false)
//进行递归处理
DeleteScaterJudge(lpDIBBits,lLineBytes,lplab,lWidth,lHeight,x-1,y,lab,lianXuShu);
//判断长度
//如果连续长度满足要求,说明不是离散点,返回
if(m_lianXuShu>=lianXuShu)
return TRUE;
//左上
lpSrc=(char*)lpDIBBits + lLineBytes * (y+1) + x-1;
//传递灰度值
gray=*lpSrc;
//如果点在图像内、颜色为黑色并且没有被访问过
if(y+1 <lHeight && x-1 >= 0 && gray == 0 && lplab[(y+1)*lWidth+x-1] == false)
//进行递归处理
DeleteScaterJudge(lpDIBBits,lLineBytes,lplab,lWidth,lHeight,x-1,y+1,lab,lianXuShu);
//判断长度
//如果连续长度满足要求,说明不是离散点,返回
if(m_lianXuShu>=lianXuShu)
return TRUE;
//上面
lpSrc=(char*)lpDIBBits + lLineBytes * (y+1) + x;
//传递灰度值
gray=*lpSrc;
//如果点在图像内、颜色为黑色并且没有被访问过
if(y+1 < lHeight && gray == 0 && lplab[(y+1)*lWidth+x] == false)
//进行递归处理
DeleteScaterJudge(lpDIBBits,lLineBytes,lplab,lWidth,lHeight,x,y+1,lab,lianXuShu);
//判断长度
//如果连续长度满足要求,说明不是离散点,返回
if(m_lianXuShu>=lianXuShu)
return TRUE;
//右上
lpSrc=(char*)lpDIBBits + lLineBytes * (y+1) + x+1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -