//图像预处理第6步:分割,并在分割出来的字符外面画框以标识void CChildView::OnImgprcDivide() { m_charRect=CharSegment(m_hDIB); //在屏幕上显示位图 CDC* pDC=GetDC(); DisplayDIB(pDC,m_hDIB); DrawFrame(pDC,m_hDIB,m_charRect,2,RGB(20,60,200));}
/*************************************************** 函数名称:* 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=0;i--) { //列 for (j=0;j =rect.top ;i--) { //列 for(j=rect.left ;j
/*********************************** ************************************函数名称: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 DrawFrame(CDC* pDC,HDIB hDIB, CRectLink charRect,unsigned int linewidth,COLORREF color){ CPen pen; pen.CreatePen (PS_SOLID,linewidth,color); pDC->SelectObject (&pen); ::SelectObject (*pDC,GetStockObject(NULL_BRUSH)); CRect rect,rect2; BYTE* lpDIB=(BYTE*)::GlobalLock ((HGLOBAL)hDIB); while(!charRect.empty()) { //从表头上得到一个矩形 rect2=rect= charRect.front(); //从链表头上面删掉一个 charRect.pop_front(); //注意,这里原先的rect是相对于图像原点(左下角)的, //而在屏幕上绘图时,要转换以客户区为原点的坐标 rect.top =::DIBHeight ((char*)lpDIB)-rect2.bottom; rect.bottom =::DIBHeight ((char*)lpDIB)-rect2.top ; pDC->Rectangle (&rect); } ::GlobalUnlock ((HGLOBAL)hDIB);}
运行效果: