官术网_书友最值得收藏!

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;
                }
            }
        }
主站蜘蛛池模板: 那坡县| 共和县| 安义县| 天水市| 共和县| 综艺| 桑日县| 莱州市| 林西县| 贺兰县| 宁化县| 屏东市| 渭南市| 梧州市| 连云港市| 衡阳县| 二连浩特市| 塘沽区| 通城县| 宁都县| 昌吉市| 武义县| 乡城县| 承德市| 团风县| 资中县| 富裕县| 旺苍县| 安康市| 吴桥县| 辽源市| 肥城市| 淄博市| 北海市| 东丽区| 高邑县| 望谟县| 隆回县| 孟州市| 佛冈县| 海南省|