📄 mydiblib.h
字号:
#include "dibapi.h"
#include <iostream>
#include <deque>
#include <math.h>
using namespace std;
typedef deque<CRect> CRectLink;
typedef deque<HDIB> HDIBLink;
//声明一些必要的全局变量
int w_sample=8;
int h_sample=16;
bool fileloaded;
bool gyhinfoinput;
bool gyhfinished;
int digicount;
int m_lianXuShu;
CRectLink m_charRectCopy;
CRectLink m_charRect;
HDIBLink m_dibRect;
HDIBLink m_dibRectCopy;
HDIB m_hDIB;
CString strPathName;
CString strPathNameSave;
/********************************function declaration*************************************/
//清楚屏幕
void ClearAll(CDC* pDC);
//在屏幕上显示位图
void DisplayDIB(CDC* pDC,HDIB hDIB);
//对分割后的位图进行尺寸标准归一化
void StdDIBbyRect(HDIB hDIB, int tarWidth, int tarHeight);
//整体斜率调整
void SlopeAdjust(HDIB hDIB);
//去除离散噪声点
void RemoveScatterNoise(HDIB hDIB);
//梯度锐化
void GradientSharp(HDIB hDIB);
//画框
void DrawFrame(CDC* pDC,HDIB hDIB, CRectLink charRect,unsigned int linewidth,COLORREF color);
//将灰度图二值化
void ConvertGrayToWhiteBlack(HDIB hDIB);
//将256色位图转为灰度图
void Convert256toGray(HDIB hDIB);
//细化
void Thinning(HDIB hDIB);
//对位图进行分割.返回一个存储着每块分割区域的链表
CRectLink CharSegment(HANDLE hDIB);
//紧缩、重排调整
HDIB AutoAlign(HDIB hDIB);
//判断是否是离散噪声点
bool DeleteScaterJudge(LPSTR lpDIBBits,WORD lLineBytes, LPBYTE lplab, int lWidth, int lHeight, int x, int y, CPoint lab[], int lianXuShu);
//对图像进行模板操作
HDIB Template(HDIB hDIB,double * tem ,int tem_w,int tem_h,double xishu);
//对图像进行中值滤波
HDIB MidFilter(HDIB hDIB,int tem_w,int tem_h);
//对图像进行直方图均衡
void Equalize(HDIB hDIB);
/***********************************implementation*************************************/
/*********************************** ************************************
函数名称:DisplayDIB
参数:
CDC* pDC -指向当前设备上下文(Divice Context)的指针
HDIB hDIB -要显示的位图的句柄
**********************************************************************/
void DisplayDIB(CDC* pDC,HDIB hDIB)
{
BYTE* lpDIB=(BYTE*)::GlobalLock((HGLOBAL)hDIB);
// 获取DIB宽度和高度
int cxDIB = ::DIBWidth((char*) lpDIB);
int cyDIB = ::DIBHeight((char*)lpDIB);
CRect rcDIB,rcDest;
rcDIB.top = rcDIB.left = 0;
rcDIB.right = cxDIB;
rcDIB.bottom = cyDIB;
//设置目标客户区输出大小尺寸
rcDest = rcDIB;
//CDC* pDC=GetDC();
ClearAll(pDC);
//在客户区显示图像
//for(int ii=0;ii<10;ii++)
::PaintDIB(pDC->m_hDC,rcDest,hDIB,rcDIB,NULL);
::GlobalUnlock((HGLOBAL)hDIB);
}
void ClearAll(CDC *pDC)
{
CRect rect;
//GetClientRect(&rect);
rect.left =0;rect.top =0;rect.right =2000;rect.bottom =1000;
CPen pen;
pen.CreatePen (PS_SOLID,1,RGB(255,255,255));
pDC->SelectObject (&pen);
pDC->Rectangle (&rect);
::DeleteObject (pen);
}
/*******************************************
*
* 函数名称:
* AutoAlign()
*
* 参数:
* HDIB hDIB -原图像的句柄
*
* 返回值
* HDIB -紧缩排列后的新图像的句柄
*
* 功能:
* 将经过了标准化处理的字符进行规整的排列,以方便下一步的处理
*
* 说明:
* 紧缩排列的操作必须在标准化操作之后进行
*
********************************************************/
HDIB AutoAlign(HDIB hDIB)
{
//指向图像的指针
BYTE* lpDIB=(BYTE*)::GlobalLock ((HGLOBAL)hDIB);
//指向象素起始位置的指针
BYTE* lpDIBBits=(BYTE*)::FindDIBBits ((char*)lpDIB);
//指向象素的指针
BYTE* lpSrc;
//获取图像的宽度
LONG lWidth=::DIBWidth ((char*)lpDIB);
//获取图像的高度
LONG lHeight=::DIBHeight ((char*)lpDIB);
//获取标准化的宽度
int w=m_charRect.front ().Width() ;
//获取标准化的高度
int h=m_charRect.front ().Height() ;
//建立一个新的图像正好能够将标准化的字符并排放置
HDIB hNewDIB=::NewDIB (digicount*w,h,8);
//指向新的图像的指针
BYTE* lpNewDIB=(BYTE*) ::GlobalLock((HGLOBAL)hNewDIB);
//指向象素起始位置的指针
BYTE* lpNewDIBBits=(BYTE*)::FindDIBBits((char*)lpNewDIB);
//指向象素的指针
BYTE* lpDst=lpNewDIBBits;
//计算原图像每行的字节数
LONG lLineBytes=(lWidth+3)/4*4;
//计算新图像每行的字节数
LONG lLineBytesnew =(digicount*w+3)/4*4;
//将新的图像初始化为白色
memset(lpDst,(BYTE)255,lLineBytesnew * h);
//映射操作的坐标变量
int i_src,j_src;
//循环变量
int i,j;
//统计字符个数的变量
int counts=0;
//存放位置信息的结构体
CRect rect,rectnew;
//清空一个新的链表来存放新的字符位置信息
m_charRectCopy.clear ();
//从头至尾逐个扫描原链表的各个结点
while(!m_charRect.empty() )
{
//从表头上得到一个矩形框
rect=m_charRect.front ();
//将这个矩形框从链表上删除
m_charRect.pop_front ();
//计算新的矩形框的位置信息
//左边界
rectnew.left =counts*w;
//右边界
rectnew.right =(counts+1)*w;
//上边界
rectnew.top =0;
//下边界
rectnew.bottom =h;
//将获得的新的矩形框插入到新的链表中
m_charRectCopy.push_back (rectnew);
//将原矩形框内的象素映射到新的矩形框中
for(i=0;i<h;i++)
{
for(j=counts*w;j<(counts+1)*w;j++)
{
//计算映射坐标
i_src=rect.top +i;
j_src=rect.left +j-counts*w;
//进行象素的映射
lpSrc=(BYTE *)lpDIBBits + lLineBytes * i_src + j_src;
lpDst=(BYTE *)lpNewDIBBits + lLineBytesnew * i + j;
*lpDst=*lpSrc;
}
}
//字符个数加1
counts++;
}
//将获得的新的链表复制到原链表中,以方便下一次的调用
m_charRect=m_charRectCopy;
//解除锁定
::GlobalUnlock (hDIB);
::GlobalUnlock (hNewDIB);
return hNewDIB;
}
/**************************************************
* 函数名称:
* ThinnerHilditch
*
* 参数:
* void* image -二值化图像矩阵前景色为1背景色为0
* unsigned longlx -图像的宽度
* unsigned longly -图像的高度
*
* 返回值
* 无
*
*函数功能:
* 对输入的图像进行细化,输出细化后的图像
***********************************************************/
void ThinnerHilditch(void *image, unsigned long lx, unsigned long ly)
{
char *f, *g;
char n[10];
unsigned int counter;
short k, shori, xx, nrn;
unsigned long i, j;
long kk, kk11, kk12, kk13, kk21, kk22, kk23, kk31, kk32, kk33, size;
size = (long)lx * (long)ly;
g = (char *)malloc(size);
if(g == NULL)
{
// printf("error in allocating memory!\n");
return;
}
f = (char *)image;
for(i=0; i<lx; i++)
{
for(j=0; j<ly; j++)
{
kk=i*ly+j;
if(f[kk]!=0)
{
f[kk]=1;
g[kk]=f[kk];
}
}
}
counter = 1;
do
{
counter++;
shori = 0;
for(i=0; i<lx; i++)
{
for(j=0; j<ly; j++)
{
kk = i*ly+j;
if(f[kk]<0)
f[kk] = 0;
g[kk]= f[kk];
}
}
for(i=1; i<lx-1; i++)
{
for(j=1; j<ly-1; j++)
{
kk=i*ly+j;
if(f[kk]!=1)
continue;
kk11 = (i-1)*ly+j-1;
kk12 = kk11 + 1;
kk13 = kk12 + 1;
kk21 = i*ly+j-1;
kk22 = kk21 + 1;
kk23 = kk22 + 1;
kk31 = (i+1)*ly+j-1;
kk32 = kk31 + 1;
kk33 = kk32 + 1;
if((g[kk12]&&g[kk21]&&g[kk23]&&g[kk32])!=0)
continue;
nrn = g[kk11] + g[kk12] + g[kk13] + g[kk21] + g[kk23] +
g[kk31] + g[kk32] + g[kk33];
if(nrn <= 1)
{
f[kk22] = 2;
continue;
}
n[4] = f[kk11];
n[3] = f[kk12];
n[2] = f[kk13];
n[5] = f[kk21];
n[1] = f[kk23];
n[6] = f[kk31];
n[7] = f[kk32];
n[8] = f[kk33];
n[9] = n[1];
xx = 0;
for(k=1; k<8; k=k+2)
{
if((!n[k])&&(n[k+1]||n[k+2]))
xx++;
}
if(xx!=1)
{
f[kk22] = 2;
continue;
}
if(f[kk12] == -1)
{
f[kk12] = 0;
n[3] = 0;
xx = 0;
for(k=1; k<8; k=k+2)
{
if((!n[k])&&(n[k+1]||n[k+2]))
xx++;
}
if(xx != 1)
{
f[kk12] = -1;
continue;
}
f[kk12] = -1;
n[3] = -1;
}
if(f[kk21]!=-1)
{
f[kk22] = -1;
shori = 1;
continue;
}
f[kk21] = 0;
n[5] = 0;
xx = 0;
for(k=1; k<8; k=k+2)
{
if((!n[k])&&(n[k+1]||n[k+2]))
{
xx++;
}
}
if(xx == 1)
{
f[kk21] = -1;
f[kk22] = -1;
shori =1;
}
else
f[kk21] = -1;
}
}
}while(shori);
free(g);
}
/**************************************************
* 函数名称:
* ThinnerRosenfeld
*
* 参数:
* void* image -二值化图像矩阵前景色为1背景色为0
* unsigned longlx -图像的宽度
* unsigned longly -图像的高度
*
* 返回值
* 无
*
*函数功能:
* 对输入的图像进行细化,输出细化后的图像
***********************************************************/
void ThinnerRosenfeld(void *image, unsigned long lx, unsigned long ly)
{
char *f, *g;
char n[10];
char a[5] = {0, -1, 1, 0, 0};
char b[5] = {0, 0, 0, 1, -1};
char nrnd, cond, n48, n26, n24, n46, n68, n82, n123, n345, n567, n781;
short k, shori;
unsigned long i, j;
long ii, jj, kk, kk1, kk2, kk3, size;
size = (long)lx * (long)ly;
g = (char *)malloc(size);
if(g==NULL)
{
printf("error in alocating mmeory!\n");
return;
}
f = (char *)image;
for(kk=0l; kk<size; kk++)
{
g[kk] = f[kk];
}
do
{
shori = 0;
for(k=1; k<=4; k++)
{
for(i=1; i<lx-1; i++)
{
ii = i + a[k];
for(j=1; j<ly-1; j++)
{
kk = i*ly + j;
if(!f[kk])
continue;
jj = j + b[k];
kk1 = ii*ly + jj;
if(f[kk1])
continue;
kk1 = kk - ly -1;
kk2 = kk1 + 1;
kk3 = kk2 + 1;
n[3] = f[kk1];
n[2] = f[kk2];
n[1] = f[kk3];
kk1 = kk - 1;
kk3 = kk + 1;
n[4] = f[kk1];
n[8] = f[kk3];
kk1 = kk + ly - 1;
kk2 = kk1 + 1;
kk3 = kk2 + 1;
n[5] = f[kk1];
n[6] = f[kk2];
n[7] = f[kk3];
nrnd = n[1] + n[2] + n[3] + n[4]
+n[5] + n[6] + n[7] + n[8];
if(nrnd<=1)
continue;
cond = 0;
n48 = n[4] + n[8];
n26 = n[2] + n[6];
n24 = n[2] + n[4];
n46 = n[4] + n[6];
n68 = n[6] + n[8];
n82 = n[8] + n[2];
n123 = n[1] + n[2] + n[3];
n345 = n[3] + n[4] + n[5];
n567 = n[5] + n[6] + n[7];
n781 = n[7] + n[8] + n[1];
if(n[2]==1 && n48==0 && n567>0)
{
if(!cond)
continue;
g[kk] = 0;
shori = 1;
continue;
}
if(n[6]==1 && n48==0 && n123>0)
{
if(!cond)
continue;
g[kk] = 0;
shori = 1;
continue;
}
if(n[8]==1 && n26==0 && n345>0)
{
if(!cond)
continue;
g[kk] = 0;
shori = 1;
continue;
}
if(n[4]==1 && n26==0 && n781>0)
{
if(!cond)
continue;
g[kk] = 0;
shori = 1;
continue;
}
if(n[5]==1 && n46==0)
{
if(!cond)
continue;
g[kk] = 0;
shori = 1;
continue;
}
if(n[7]==1 && n68==0)
{
if(!cond)
continue;
g[kk] = 0;
shori = 1;
continue;
}
if(n[1]==1 && n82==0)
{
if(!cond)
continue;
g[kk] = 0;
shori = 1;
continue;
}
if(n[3]==1 && n24==0)
{
if(!cond)
continue;
g[kk] = 0;
shori = 1;
continue;
}
cond = 1;
if(!cond)
continue;
g[kk] = 0;
shori = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -