?? 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 + -