?? mydiblib.h
字號:
}
}
for(i=0; i<lx; i++)
{
for(j=0; j<ly; j++)
{
kk = i*ly + j;
f[kk] = g[kk];
}
}
}
}while(shori);
free(g);
}
/*************************************************
*
* 函數名稱:
* CharSegment()
*
* 參數:
* HDIB hDIB -原圖像的句柄
*
* 返回值:
* CRectLink -存放被分割的各個字符位置信息的鏈表
*
* 功能:
* 將圖像中待識別的字符逐個分離出來并返回存放各個字符的位置信息的鏈表
*
* 說明:
* 此函數只能對2值化后的圖像進行處理
*
*********************************************************/
CRectLink CharSegment(HANDLE hDIB)
{
//清空用來保存每個字符區域的鏈表
CRectLink charRect1,charRect2;
charRect1.clear();
charRect2.clear();
// 指向DIB的指針
LPSTR lpDIB=(LPSTR) ::GlobalLock((HGLOBAL)hDIB);
// 指向DIB象素指針
LPSTR lpDIBBits;
// 找到DIB圖像象素起始位置
lpDIBBits = ::FindDIBBits(lpDIB);
//指向象素的的指針
BYTE* lpSrc;
//圖像的長度和寬度
int height,width;
//獲取圖像的寬度
width=(int)::DIBWidth(lpDIB);
//獲取圖像的長度
height=(int)::DIBHeight(lpDIB);
//計算圖像每行的字節數
LONG lLineBytes = WIDTHBYTES(width * 8);
//定義上下邊界兩個變量
int top,bottom;
//象素的灰度值
int gray;
//設置循環變量
int i,j;
//用來統計圖像中字符個數的計數器
digicount=0;
//從上往下掃描,找到上邊界
//行
for (i=0;i<height;i++)
{
//列
for (j=0;j<width;j++)
{
// 指向圖像第i行,第j個象素的指針
lpSrc = (unsigned char*)lpDIBBits + lLineBytes * i + j;
//獲得該點的灰度值
gray = *(lpSrc);
//看是否為黑點
if (gray == 0)
{
//若為黑點,把此點作為字符大致的最高點
top = i;
//對i強行賦值以中斷循環
i=height;
//跳出循環
break;
}
//如果該點不是黑點,繼續循環
}
}
//從下往上掃描,找下邊界
//行
for (i = height-1;i>=0;i--)
{
//列
for (j=0;j<width;j++)
{
// 指向圖像第i行,第j個象素的指針
lpSrc = (unsigned char*)lpDIBBits + lLineBytes * i + j;
//獲取該點的灰度值
gray = *(lpSrc);
//判斷是否為黑點
if (gray == 0)
{
//若為黑點,把此點作為字符大致的最低點
bottom = i;
//對i強行賦值以中斷循環
i=-1;
//跳出循環
break;
}
//如果該點不是黑點,繼續循環
}
}
//lab 用作是否進入一個字符分割的標志
bool lab = false;
//表明掃描一列中是否發現黑色點
bool black = false;
//存放位置信息的結構體
CRect rect;
//計數器置零
digicount=0;
//行
for (i=0;i<width;i++)
{
//開始掃描一列
black=false;
for (j=0;j<height;j++)
{
// 指向圖像第i行,第j個象素的指針
lpSrc = (unsigned char*)lpDIBBits + lLineBytes * j + i;
//獲取該點的灰度值
gray = *(lpSrc);
//判斷是否為黑點
if (gray == 0)
{
//如果發現黑點,設置標志位
black=true;
//如果還沒有進入一個字符的分割
if(lab==false)
{
//設置左側邊界
rect.left = i;
//字符分割開始
lab = true;
}
//如果字符分割已經開始了
else
//跳出循環
break;
}
}
//如果已經掃到了最右邊那列,說明整副圖像掃描完畢。退出
if(i==(width-1))
//退出整個循環
break;
//如果到此black仍為false,說明掃描了一列,都沒有發現黑點。表明當前字符分割結束
if(lab==true&&black==false)
{
//將位置信息存入結構體中
//設置右邊界
rect.right =i;
//設置上邊界
rect.top =top;
//設置下邊界
rect.bottom =bottom;
//將框外括一個象素,以免壓到字符
rect.InflateRect (1,1);
//將這個結構體插入存放位置信息的鏈表1的后面
charRect1.push_back (rect);
//設置標志位,開始下一次的字符分割
lab=false;
//字符個數統計計數器加1
digicount++;
}
//進入下一列的掃描
}
//再將矩形輪廓矩形的top和bottom精確化
//將鏈表1賦值給鏈表2
charRect2=charRect1;
//將鏈表2的內容清空
charRect2.clear ();
//建立一個新的存放位置信息的結構體
CRect rectnew;
//對于鏈表1從頭至尾逐個進行掃描
while(!charRect1.empty())
{
//從鏈表1頭上得到一個矩形
rect= charRect1.front();
//從鏈表1頭上面刪掉一個
charRect1.pop_front();
//計算更加精確的矩形區域
//獲得精確的左邊界
rectnew.left =rect.left-1 ;
//獲得精確的右邊界
rectnew.right =rect.right+1 ;
//通過獲得的精確左右邊界對上下邊境重新進行精確定位
// 由下而上掃描計算上邊界
//行
for(i=rect.top ;i<rect.bottom ;i++)
{
//列
for(j=rect.left ;j<rect.right ;j++)
{
// 指向圖像第i行,第j個象素的指針
lpSrc = (unsigned char*)lpDIBBits + lLineBytes * i + j;
//如果這個象素是黑點
if (*lpSrc == 0)
{
//設置上邊界
rectnew.top = i-1;
//對i進行強制定義以跳出循環
i=rect.bottom ;
//跳出循環
break;
}
}
}
//由下而上掃描計算下邊界
//行
for(i=rect.bottom-1 ;i>=rect.top ;i--)
{
//列
for(j=rect.left ;j<rect.right ;j++)
{
// 指向圖像第i行,第j個象素的指針
lpSrc = (unsigned char*)lpDIBBits + lLineBytes * i + j;
//該點如果為黑點
if (*lpSrc == 0)
{
//設置下邊界
rectnew.bottom = i+1;
//對i進行強制定義以跳出循環
i=-1;
//跳出循環
break;
}
}
}
//將得到的新的準確的位置信息從后面插到鏈表2的尾上
charRect2.push_back (rectnew);
}
//將鏈表2 傳遞給鏈表1
charRect1=charRect2;
//解除鎖定
::GlobalUnlock(hDIB);
//將鏈表1返回
return charRect1;
}
/****************************************************************
* 函數名稱:
* Convert256toGray()
*
* 參數:
* HDIB hDIB -圖像的句柄
*
* 返回值:
* 無
*
* 功能:
* 將256色位圖轉化為灰度圖
*
***************************************************************/
void Convert256toGray(HDIB hDIB)
{
LPSTR lpDIB;
// 由DIB句柄得到DIB指針并鎖定DIB
lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)hDIB);
// 指向DIB象素數據區的指針
LPSTR 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 = ::FindDIBBits(lpDIB);
// 獲取圖像寬度
lWidth = ::DIBWidth(lpDIB);
// 獲取圖像高度
lHeight = ::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);
}
/******************************************************************
*
* 函數名稱ConvertGrayToWhiteBlack()
*
* 參數 :HDIB hDIB -原圖的句柄
*
* 返回值:無
*
* 功能: ConvertGrayToWhiteBlack函數采用硬閾值的方法,實現將圖像二值化的功能。
*
* 說明:
要求待處理的圖片為256色
************************************************************************/
void ConvertGrayToWhiteBlack(HDIB hDIB)
{
// 指向DIB的指針
LPSTR lpDIB;
// 由DIB句柄得到DIB指針并鎖定DIB
lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)hDIB);
// 指向DIB象素數據區的指針
LPSTR lpDIBBits;
// 指向DIB象素的指針
BYTE * lpSrc;
// 圖像寬度
LONG lWidth;
// 圖像高度
LONG lHeight;
// 圖像每行的字節數
LONG lLineBytes;
// 找到DIB圖像象素起始位置
lpDIBBits = ::FindDIBBits(lpDIB);
// 獲取圖像寬度
lWidth = ::DIBWidth(lpDIB);
// 獲取圖像高度
lHeight = ::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);
}
/*****************************************************************
*
* 函數名稱
* DeleteScaterJudge()
*
* 參數:
* LPSTR lpDIBBits -指向象素起始位置的指針
* WORD lLineBytes -圖像每行的字節數
* LPBYTE lplab -標志位數組
* int lWidth -圖像的寬度
* int lHeight -圖像的高度
* int x -當前點的橫坐標
* int y -當前點的縱坐標
* CPoint lab[] -存放議考察過的連續點坐標
* int lianXuShu -離散點的判定長度
*
* 返回值:
* Bool -是離散點返回false 不是離散點返回true
*
* 功能:
* 利用遞歸算法統計連續點的個數,通過閾值來判定是否為離散點
*
* 說明:
* 只能對2值圖像進行處理
******************************************************************/
bool DeleteScaterJudge(LPSTR 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)
//進行遞歸處理
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -