⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mydiblib.h

📁 本目录主要包括:文档和两个源代 其中源代码是识别程序的
💻 H
📖 第 1 页 / 共 4 页
字号:
#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 + -