- Visual C++數字圖像模式識別典型案例詳解
- 馮偉興 梁洪 王臣業編著
- 812字
- 2018-12-31 19:39:09
5.4.2 人臉識別與分割
編程實現
[1] 在視圖類里添加消息映射函數Onboundary()以實現輪廓提取。Onboundary()函數代碼如代碼5-5所示。
代碼5-5 Onboundary()函數
void CDemoView::Onboundary() { CDemoDoc *pDoc=GetDocument(); ImageDib *pDib=pDoc->GetPDib(); int i,j,thd; CSize size=pDib->GetDimensions(); int lineByte=(size.cx+3)/4*4; long pixel_scales=0; for(i=0;i<size.cx;i++){ for(j=0;j<size.cy;j++){ pixel_scales+=*(pDib->m_pImgData+j*lineByte+i); } } thd=pixel_scales/(size.cx*size.cy); GrayTrans graytrans(size,pDib->m_nBitCount, pDib->m_lpColorTable, pDib-> m_pImgData); graytrans.Binary(thd); //調用Binary()對圖像進行二值化 //建立一個新視圖,顯示分割結果 CMainFrame* pFrame = (CMainFrame *)(AfxGetApp()->m_pMainWnd); pFrame->SendMessage(WM_COMMAND, ID_FILE_NEW); CDemoView* pView=(CDemoView*)pFrame->MDIGetActive()->GetActiveView(); CDemoDoc* pDocNew=pView->GetDocument(); ImageDib *dibNew=pDocNew->GetPDib(); dibNew->ReplaceDib(graytrans.GetDimensions(),graytrans.m_nBitCountOut, graytrans.m_lpColorTableOut, graytrans.m_pImgDataOut); pView->OnInitialUpdate(); pDocNew->SetModifiedFlag(TRUE); pDocNew->UpdateAllViews(pView); } void CDemo1View::Onboundary() { CDemo1Doc *pDoc=GetDocument(); ImageDib *pDib=pDoc->GetPDib(); //只處理灰度圖像 if(pDib->m_nBitCount!=8){ ::MessageBox(0, "只處理灰度圖像", MB_OK,0); return ; } int i,j,thd; CSize size=pDib->GetDimensions(); int lineByte=(size.cx+3)/4*4; long pixel_scales=0; for(i=0;i<size.cx;i++){ for(j=0;j<size.cy;j++){ pixel_scales+=*(pDib->m_pImgData+j*lineByte+i); } } thd=pixel_scales/(size.cx*size.cy); GrayTrans graytrans(size,pDib->m_nBitCount, pDib->m_lpColorTable, pDib-> m_pImgData); //調用Binary()對圖像進行二值化 graytrans.BinaryImage(thd); //建立一個新視圖,顯示分割結果 CMainFrame* pFrame = (CMainFrame *)(AfxGetApp()->m_pMainWnd); pFrame->SendMessage(WM_COMMAND, ID_FILE_NEW); CDemo1View* pView=(CDemo1View*)pFrame->MDIGetActive()->GetActiveView(); CDemo1Doc* pDocNew=pView->GetDocument(); ImageDib *dibNew=pDocNew->GetPDib(); dibNew->ReplaceDib(graytrans.GetDimensions(),graytrans.m_nBitCountOut,gray trans.m_lpColorTableOut, graytrans.m_pImgDataOut); pView->OnInitialUpdate(); pDocNew->SetModifiedFlag(TRUE); pDocNew->UpdateAllViews(pView); }
[2] 上述代碼中調用了GrayTrans類中的BinaryImage ()函數,已進行圖像的二值化處理,其具體代碼如代碼5-6所示。
代碼5-6 BinaryImage()函數
void GrayTrans::BinaryImage(int threshold) { //對于灰度圖像 if(m_nBitCount==8){ //釋放舊的輸出圖像數據及顏色表緩沖區 if(m_pImgDataOut!=NULL){ delete []m_pImgDataOut; m_pImgDataOut=NULL; } if(m_lpColorTableOut!=NULL){ delete []m_lpColorTableOut; m_lpColorTableOut=NULL; } //輸出圖像的每像素位數、顏色表長度 m_nBitCountOut=m_nBitCount; m_nColorTableLengthOut=ComputeColorTabalLength(m_nBitCountOut); //申請輸出圖像顏色表緩沖區,并將輸入圖像顏色表復制至輸出圖像顏色表中 m_lpColorTableOut=new RGBQUAD[m_nColorTableLengthOut]; memcpy(m_lpColorTableOut,m_lpColorTable,sizeof(RGBQUAD)*m_ nColorTableLengthOut); //輸出圖像的寬高,與輸入圖像相等 m_imgWidthOut=m_imgWidth; m_imgHeightOut=m_imgHeight; //圖像每行像素所占字節數,輸入圖像與輸出圖像每行像素所占字節數相等 int lineByte=(m_imgWidth*m_nBitCount/8+3)/4*4; //申請輸出圖像位圖數據緩沖區 m_pImgDataOut=new unsigned char[lineByte*m_imgHeight]; //循環變量,圖像的坐標 int i,j; //二值化 for(i=0;i<m_imgHeight;i++){ for(j=0;j<m_imgWidth;j++){ if(*(m_pImgData+i*lineByte+j)<threshold) *(m_pImgDataOut+i*lineByte+j)=0; else *(m_pImgDataOut+i*lineByte+j)=255; } } } else { if(m_pImgDataOut!=NULL){ delete []m_pImgDataOut; m_pImgDataOut=NULL; } if(m_lpColorTableOut!=NULL){ delete []m_lpColorTableOut; m_lpColorTableOut=NULL; } //灰值化后,每像素位數為8比特 m_nBitCountOut=8; //顏色表長度 m_nColorTableLengthOut=ComputeColorTabalLength(m_nBitCountOut); //申請顏色表緩沖區,生成灰度圖像的顏色表 if(m_nColorTableLengthOut!=0){ m_lpColorTableOut=new RGBQUAD[m_nColorTableLengthOut]; for(int i=0; i<m_nColorTableLengthOut;i++){ m_lpColorTableOut[i].rgbBlue=i; m_lpColorTableOut[i].rgbGreen=i; m_lpColorTableOut[i].rgbRed=i; m_lpColorTableOut[i].rgbReserved=0; } } //輸入圖像每像素字節數,彩色圖像為3字節/像素 int pixelByteIn=3; //輸入圖像每行像素所占字節數,必須是4的倍數 int lineByteIn=(m_imgWidth*pixelByteIn+3)/4*4; //輸出圖像的寬高,與輸入圖像相等 m_imgWidthOut=m_imgWidth; m_imgHeightOut=m_imgHeight; //輸出圖像每行像素所占字節數,必須是4的倍數 int lineByteOut=(m_imgWidth*m_nBitCountOut/8+3)/4*4; //申請輸出圖像位圖數據緩沖區 m_pImgDataOut=new unsigned char[lineByteOut*m_imgHeight]; //循環變量,圖像的坐標 int m,n; //根據灰值化公式為輸出圖像賦值 for(m=0;m<m_imgHeight;m++){ for(n=0;n<m_imgWidth;n++) *(m_pImgDataOut+m*lineByteOut+n)=0.11**(m_pImgData+m* lineByteIn+n*pixelByteIn+0) +0.59**(m_pImgData+m*lineByteIn+n*pixelByteIn+1) +0.30**(m_pImgData+m*lineByteIn+n*pixelByteIn+2)+0.5; } //輸出圖像每行像素所占字節數,輸入圖像與輸出圖像每行像素所占字節數不等 int i,j; //二值化 for(i=0;i<m_imgHeight;i++){ for(j=0;j<m_imgWidth;j++) if(*(m_pImgDataOut+i*lineByteOut+j)<threshold) *(m_pImgDataOut+i*lineByteOut+j)=0; else *(m_pImgDataOut+i*lineByteOut+j)=255; } } }