?? mydiblib.h
字號(hào):
#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);
//對(duì)分割后的位圖進(jìn)行尺寸標(biāo)準(zhǔn)歸一化
void StdDIBbyRect(HDIB hDIB, int tarWidth, int tarHeight);
//整體斜率調(diào)整
void SlopeAdjust(HDIB hDIB);
//去除離散噪聲點(diǎn)
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色位圖轉(zhuǎn)為灰度圖
void Convert256toGray(HDIB hDIB);
//細(xì)化
void Thinning(HDIB hDIB);
//對(duì)位圖進(jìn)行分割.返回一個(gè)存儲(chǔ)著每塊分割區(qū)域的鏈表
CRectLink CharSegment(HANDLE hDIB);
//緊縮、重排調(diào)整
HDIB AutoAlign(HDIB hDIB);
//判斷是否是離散噪聲點(diǎn)
bool DeleteScaterJudge(LPSTR lpDIBBits,WORD lLineBytes, LPBYTE lplab, int lWidth, int lHeight, int x, int y, CPoint lab[], int lianXuShu);
//對(duì)圖像進(jìn)行模板操作
HDIB Template(HDIB hDIB,double * tem ,int tem_w,int tem_h,double xishu);
//對(duì)圖像進(jìn)行中值濾波
HDIB MidFilter(HDIB hDIB,int tem_w,int tem_h);
//對(duì)圖像進(jìn)行直方圖均衡
void Equalize(HDIB hDIB);
/***********************************implementation*************************************/
/*********************************** ************************************
函數(shù)名稱:DisplayDIB
參數(shù):
CDC* pDC -指向當(dāng)前設(shè)備上下文(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;
//設(shè)置目標(biāo)客戶區(qū)輸出大小尺寸
rcDest = rcDIB;
//CDC* pDC=GetDC();
ClearAll(pDC);
//在客戶區(qū)顯示圖像
//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);
}
/*******************************************
*
* 函數(shù)名稱:
* AutoAlign()
*
* 參數(shù):
* HDIB hDIB -原圖像的句柄
*
* 返回值
* HDIB -緊縮排列后的新圖像的句柄
*
* 功能:
* 將經(jīng)過(guò)了標(biāo)準(zhǔn)化處理的字符進(jìn)行規(guī)整的排列,以方便下一步的處理
*
* 說(shuō)明:
* 緊縮排列的操作必須在標(biāo)準(zhǔn)化操作之后進(jìn)行
*
********************************************************/
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);
//獲取標(biāo)準(zhǔn)化的寬度
int w=m_charRect.front ().Width() ;
//獲取標(biāo)準(zhǔn)化的高度
int h=m_charRect.front ().Height() ;
//建立一個(gè)新的圖像正好能夠?qū)?biāo)準(zhǔn)化的字符并排放置
HDIB hNewDIB=::NewDIB (digicount*w,h,8);
//指向新的圖像的指針
BYTE* lpNewDIB=(BYTE*) ::GlobalLock((HGLOBAL)hNewDIB);
//指向象素起始位置的指針
BYTE* lpNewDIBBits=(BYTE*)::FindDIBBits((char*)lpNewDIB);
//指向象素的指針
BYTE* lpDst=lpNewDIBBits;
//計(jì)算原圖像每行的字節(jié)數(shù)
LONG lLineBytes=(lWidth+3)/4*4;
//計(jì)算新圖像每行的字節(jié)數(shù)
LONG lLineBytesnew =(digicount*w+3)/4*4;
//將新的圖像初始化為白色
memset(lpDst,(BYTE)255,lLineBytesnew * h);
//映射操作的坐標(biāo)變量
int i_src,j_src;
//循環(huán)變量
int i,j;
//統(tǒng)計(jì)字符個(gè)數(shù)的變量
int counts=0;
//存放位置信息的結(jié)構(gòu)體
CRect rect,rectnew;
//清空一個(gè)新的鏈表來(lái)存放新的字符位置信息
m_charRectCopy.clear ();
//從頭至尾逐個(gè)掃描原鏈表的各個(gè)結(jié)點(diǎn)
while(!m_charRect.empty() )
{
//從表頭上得到一個(gè)矩形框
rect=m_charRect.front ();
//將這個(gè)矩形框從鏈表上刪除
m_charRect.pop_front ();
//計(jì)算新的矩形框的位置信息
//左邊界
rectnew.left =counts*w;
//右邊界
rectnew.right =(counts+1)*w;
//上邊界
rectnew.top =0;
//下邊界
rectnew.bottom =h;
//將獲得的新的矩形框插入到新的鏈表中
m_charRectCopy.push_back (rectnew);
//將原矩形框內(nèi)的象素映射到新的矩形框中
for(i=0;i<h;i++)
{
for(j=counts*w;j<(counts+1)*w;j++)
{
//計(jì)算映射坐標(biāo)
i_src=rect.top +i;
j_src=rect.left +j-counts*w;
//進(jìn)行象素的映射
lpSrc=(BYTE *)lpDIBBits + lLineBytes * i_src + j_src;
lpDst=(BYTE *)lpNewDIBBits + lLineBytesnew * i + j;
*lpDst=*lpSrc;
}
}
//字符個(gè)數(shù)加1
counts++;
}
//將獲得的新的鏈表復(fù)制到原鏈表中,以方便下一次的調(diào)用
m_charRect=m_charRectCopy;
//解除鎖定
::GlobalUnlock (hDIB);
::GlobalUnlock (hNewDIB);
return hNewDIB;
}
/**************************************************
* 函數(shù)名稱:
* ThinnerHilditch
*
* 參數(shù):
* void* image -二值化圖像矩陣前景色為1背景色為0
* unsigned longlx -圖像的寬度
* unsigned longly -圖像的高度
*
* 返回值
* 無(wú)
*
*函數(shù)功能:
* 對(duì)輸入的圖像進(jìn)行細(xì)化,輸出細(xì)化后的圖像
***********************************************************/
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);
}
/**************************************************
* 函數(shù)名稱:
* ThinnerRosenfeld
*
* 參數(shù):
* void* image -二值化圖像矩陣前景色為1背景色為0
* unsigned longlx -圖像的寬度
* unsigned longly -圖像的高度
*
* 返回值
* 無(wú)
*
*函數(shù)功能:
* 對(duì)輸入的圖像進(jìn)行細(xì)化,輸出細(xì)化后的圖像
***********************************************************/
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;
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -