//圖像預處理第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); }
運行效果:函數
調整前spa
調整後指針