//图像预处理第5步:倾斜度调整 void CChildView::OnImgprcAdjustSlope() { SlopeAdjust(m_hDIB); //在屏幕上显示位图 CDC* pDC=GetDC(); DisplayDIB(pDC,m_hDIB); }
/********************************************************* * 函数名称: * SlopeAdjust() * * 参数: * HDIB hDIB -原图像的句柄 * * 返回值: * 无 * * 功能: * 通过对图像左右半边平均高度的统计来进行倾斜的调整 * * 说明: * 只能对2值图像进行处理 * ****************************************************************/ void SlopeAdjust(HDIB hDIB) { // 指向DIB的指针 LPSTR lpDIB=(LPSTR) ::GlobalLock((HGLOBAL)hDIB); // 指向DIB象素指针 LPSTR lpDIBBits; // 找到DIB图像象素起始位置 lpDIBBits = ::FindDIBBits(lpDIB); // 指向源图像的指针 unsigned char* lpSrc; // 循环变量 LONG i; LONG j; // 图像每行的字节数 LONG lLineBytes; //图像的长度 LONG lWidth; //图像的宽度 LONG lHeight; //获取图像的长度 lWidth=::DIBWidth ((char*)lpDIB); //获取图像的宽度 lHeight=::DIBHeight ((char*)lpDIB); // 计算图像每行的字节数 lLineBytes = WIDTHBYTES(lWidth * 8); //图像左半边的平均高度 double leftaver=0.0; //图像右半边的平均高度 double rightaver=0.0; //图像的倾斜度 double slope; //统计循环变量 LONG counts=0; //扫描左半边的图像,求黑色象素的平均高度 //行 for (i=0;i<lHeight;i++) { //列 for (j=0;j<lWidth/2;j++) { //指向第i行第j个象素的指针 lpSrc=(unsigned char*)lpDIBBits + lLineBytes * i + j; //如果为黑点 if (*lpSrc == 0) { //对其高度进行统计叠加 counts +=lWidth/2 -j; leftaver += i*(lWidth/2 -j); } } } //计算平均高度 leftaver /= counts; //将统计循环变量重新赋值 counts =0; //扫描右半边的图像,求黑色象素的平均高度 //行 for (i =0;i<lHeight;i++) { //列 for (j=lWidth/2;j<lWidth;j++) { //指向第i行第j个象素的指针 lpSrc=(unsigned char*)lpDIBBits + lLineBytes * i + j; //如果为黑点 if (*lpSrc == 0) { //进行统计叠加 counts +=lWidth -j; rightaver += i*(lWidth -j); } } } //计算右半边的平均高度 rightaver /= counts; //计算斜率 slope = (leftaver - rightaver) / (lWidth/2); //指向新的图像象素起始位置的指针 LPSTR lpNewDIBBits; //指向新图像的指针 LPSTR lpDst; //新图像的句柄 HLOCAL nNewDIBBits=LocalAlloc(LHND,lLineBytes*lHeight); //锁定内存 lpNewDIBBits=(char*)LocalLock(nNewDIBBits); //指向新图像象素的指针 lpDst=(char*)lpNewDIBBits; //为新图像赋初始值 memset(lpDst,(BYTE)255,lLineBytes*lHeight); //象素点的灰度值 int gray; //位置映射值 int i_src; //根据斜率,把当前新图像的点映射到源图像的点 //行 for (i=0;i<lHeight;i++) { //列 for (j=0;j<lWidth;j++) { //计算映射位置 i_src=int(i - (j-lWidth/2)*slope); //如果点在图像外,象素置白色 if (i_src <0 || i_src >=lHeight ) gray = 255; else { //否则到源图像中找点,取得象素值 //指向第i_src行第j个象素的指针 lpSrc=(unsigned char *)lpDIBBits + lLineBytes * i_src + j; gray = *lpSrc; } //把新图像的点用得到的象素值填充 //指向第i行第j个象素的指针 lpDst = (char *)lpNewDIBBits + lLineBytes * i + j; *lpDst=gray; } } // 将新的图像的内容拷贝到旧的图像中 memcpy(lpDIBBits,lpNewDIBBits,lLineBytes*lHeight); // 解除锁定 ::GlobalUnlock ((HGLOBAL)hDIB); }
运行效果:
调整前
调整后