FaceDetectDoc.cpp
上传用户:sdsuchuang
上传日期:2013-01-12
资源大小:2228k
文件大小:15k
- // FaceDetectDoc.cpp : implementation of the CFaceDetectDoc class
- //
- #include "stdafx.h"
- #include "FaceDetect.h"
- #include "DIB.h"
- #include "FaceDetectDoc.h"
- #include "FaceDetectView.h"
- #include "LikelyHood.h"
- #include "math.h"
- #define WIDTHBYTES(bits) ((bits+31)/32*4)
- //#include "ReplaceDoc.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- extern HANDLE hDIB;
- extern HANDLE hDIB1;
- extern HANDLE hDIBTemp;
- extern HANDLE hDIBTemp1;
- extern class DIB gDib;
- extern int gheight;
- extern int gwidth;
- extern WORD gwBytesPerLine;
- #define IDC_BMPSHOW 1000
- /////////////////////////////////////////////////////////////////////////////
- // CFaceDetectDoc
- IMPLEMENT_DYNCREATE(CFaceDetectDoc, CDocument)
- BEGIN_MESSAGE_MAP(CFaceDetectDoc, CDocument)
- //{{AFX_MSG_MAP(CFaceDetectDoc)
- ON_COMMAND(ID_READY_GetFaceOutLline, OnREADYGetFaceOutLline)
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CFaceDetectDoc construction/destruction
- CFaceDetectDoc::CFaceDetectDoc()
- {
- // TODO: add one-time construction code here
- m_bFaceOK = false;
-
- }
- CFaceDetectDoc::~CFaceDetectDoc()
- {
- }
- BOOL CFaceDetectDoc::OnNewDocument()
- {
- if (!CDocument::OnNewDocument())
- return FALSE;
- // TODO: add reinitialization code here
- // (SDI documents will reuse this document)
- return TRUE;
- }
- /////////////////////////////////////////////////////////////////////////////
- // CFaceDetectDoc serialization
- void CFaceDetectDoc::Serialize(CArchive& ar)
- {
- if (ar.IsStoring())
- {
- // TODO: add storing code here
- }
- else
- {
- // TODO: add loading code here
- }
- }
- /////////////////////////////////////////////////////////////////////////////
- // CFaceDetectDoc diagnostics
- #ifdef _DEBUG
- void CFaceDetectDoc::AssertValid() const
- {
- CDocument::AssertValid();
- }
- void CFaceDetectDoc::Dump(CDumpContext& dc) const
- {
- CDocument::Dump(dc);
- }
- #endif //_DEBUG
- /////////////////////////////////////////////////////////////////////////////
- // CFaceDetectDoc commands
- BOOL CFaceDetectDoc::OnOpenDocument(LPCTSTR lpszPathName)
- {
- if (!CDocument::OnOpenDocument(lpszPathName))
- return FALSE;
- if(hDIB)
- GlobalFree(hDIB);
- path=lpszPathName;
- hDIB = gDib.LoadDIB(lpszPathName);
- ASSERT(hDIB != NULL);
- hDIBTemp = gDib.CopyHandle(hDIB);
- LPBITMAPINFOHEADER lpbi;
- lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
- gheight = lpbi->biHeight;
- gwidth = lpbi->biWidth;
- m_nWndWidth = gwidth;
- m_nWndHeight=gheight ;
- gwBytesPerLine = gDib.BytePerLine(hDIB);
- GlobalUnlock(hDIB);
- return TRUE;
- }
- BOOL CFaceDetectDoc::OnOpenDocument1(LPCTSTR lpszPathName)
- {
- if (!CDocument::OnOpenDocument(lpszPathName))
- return FALSE;
- if(hDIB1)
- GlobalFree(hDIB1);
- path=lpszPathName;
- hDIB1 = gDib.LoadDIB(lpszPathName);
- ASSERT(hDIB1 != NULL);
- hDIBTemp1 = gDib.CopyHandle(hDIB1);
- LPBITMAPINFOHEADER lpbi;
- lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB1);
- gheight = lpbi->biHeight;
- gwidth = lpbi->biWidth;
- m_nWndWidth = gwidth;
- m_nWndHeight=gheight ;
- gwBytesPerLine = gDib.BytePerLine(hDIB1);
- GlobalUnlock(hDIB);
- return TRUE;
- }
- ///////////////////////获取图片数据//////////////////
- void CFaceDetectDoc::OnREADYGetFaceOutLline()
- {
- // BYTE *colorTable;
- if(!hDIB)
- {
- ::AfxMessageBox("请确认是否有图片?");return ;
- }
- READYGetFaceOutLline1() ;
- }
- void CFaceDetectDoc::READYGetFaceOutLline1()
- {
- DIB *m_pMainDib=new DIB();
- //BYTE *m_pDib=m_pMainDib->GetBits();
-
- // colorTable = (BYTE *)m_pDib;
- //////////////////////////////////////////////////////
- HDIB hNewDIB = NULL;
- LPBITMAPINFOHEADER lpSrc,lpDest;
- LPBYTE lpS,lpD;
- DWORD dwBytesPerLine;
- DWORD dwImgSize;
- // WORD wBytesPerLine;
- unsigned i ,j,height,width;
- if(!hDIB)
- return ;
-
- lpSrc = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
- dwBytesPerLine = WIDTHBYTES(24*(lpSrc->biWidth));
- dwImgSize = lpSrc->biHeight * dwBytesPerLine;
- //申请新的内存,大小等于原来图象的大小
- hNewDIB = GlobalAlloc(GHND,sizeof(BITMAPINFOHEADER)+dwImgSize);
- lpDest = (LPBITMAPINFOHEADER)GlobalLock(hNewDIB);
- //保存图片的长宽、颜色深度等信息
-
- memcpy((void*)lpDest,(void*)lpSrc,sizeof(BITMAPINFOHEADER));
-
- DWORD dwSBytesPerLine;
-
- dwSBytesPerLine = (24*(lpSrc->biWidth)+31)/32*4;
- height = lpDest->biHeight;
- width = lpDest->biWidth;
- lpS = (LPBYTE)lpSrc;
- // wBytesPerLine = this->BytePerLine(hDIB);//
- lpD = (LPBYTE)lpDest;
- lpS = lpS + sizeof(BITMAPINFOHEADER);
- lpD = lpD + sizeof(BITMAPINFOHEADER);
-
- ////////////////////////////////////////////////////
-
- int byteBitCount = m_pMainDib->GetBiBitCount()/8;
- m_tOriPixelArray = new RGBQUAD*[height];
- m_tResPixelArray = new RGBQUAD*[height];
- for(i=0; i<height; i++)
- {
- m_tOriPixelArray[i] = new RGBQUAD[width];
- m_tResPixelArray[i] = new RGBQUAD[width];
-
- }
- LPBYTE lpData;
- long lOffset;
- lpData = gDib.FindDIBBits(hDIB);
- WORD gwBytesPerLine = gDib.BytePerLine(hDIB);
- for(i=0; i<height; i++)
- {
- for(j=0; j<width; j++)
- {
- lOffset = gDib.PixelOffset(i, j, gwBytesPerLine);
- m_tOriPixelArray[i][j].rgbBlue =*(lpData + lOffset++);
- m_tOriPixelArray[i][j].rgbGreen=*(lpData + lOffset++);
- m_tOriPixelArray[i][j].rgbRed =*(lpData + lOffset++);
-
- m_tOriPixelArray[i][j].rgbReserved = 0;
- m_tResPixelArray[i][j]=m_tOriPixelArray[i][j];
-
-
- }
-
- }
- m_nWndWidth=width;
- m_nWndHeight=height;
- method1 =new CLikelyHood(m_tOriPixelArray,m_nWndWidth,m_nWndHeight);
-
- Likehood(m_nWndWidth,m_nWndHeight) ;
- OnBtnBinary();
-
- HistogramV();
- OnBtnHistogramH();
-
- OnBtnMarkFace();
- ///////////////////////////////////////////////
- /*
- for(int k1=top;k1<bottom; k1++)
- for(int k=left;k<right; k++)
- if(method1->m_pBinaryArray[k1][k]==1)
- {
- lOffset = gDib.PixelOffset(k1, k, gwBytesPerLine);
- *(lpData+lOffset)=255;
- *(lpData+lOffset+1)=255;
- *(lpData+lOffset+2)=255;
- }
- */
- ////////////////////////////////////////////////////
-
- }
- ////////////////////////////////////////////////////////////////////////////////
- // 计算相似度
- ////////////////////////////////////////////////////////////////////////////////
- void CFaceDetectDoc::Likehood(int m_WndWidth,int m_WndHeight)
- {
- int i,j;
- SetCursor(LoadCursor(NULL,IDC_WAIT));
-
- method1->CalLikeHood();
- for( i=0; i<m_WndHeight; i++)
- for( j=0; j<m_WndWidth; j++)
- {
- m_tResPixelArray[i][j].rgbBlue = m_tResPixelArray[i][j].rgbGreen =m_tResPixelArray[i][j].rgbRed=(int)(method1->m_pLikeliHoodArray[i][j]*255);
-
- }
- //MakeBitMap();
-
- SetCursor(LoadCursor(NULL,IDC_ARROW));
- }
- ////////////////////////////////////////////////////////////////////////////////
- // 二值化
- ////////////////////////////////////////////////////////////////////////////////
- void CFaceDetectDoc::OnBtnBinary()
- {
- SetCursor(LoadCursor(NULL,IDC_WAIT));
- int i,j;
- // long lOffset;
- LPBYTE lpData = gDib.FindDIBBits(hDIB);
- WORD gwBytesPerLine = gDib.BytePerLine(hDIB);
- if(!method1->CalBinary())
- {
- AfxMessageBox("请先计算相似度!");
- SetCursor(LoadCursor(NULL,IDC_ARROW));
- return;
- }
-
- for(i=0; i<m_nWndHeight; i++)
- for( j=0; j<m_nWndWidth; j++)
- {
- m_tResPixelArray[i][j].rgbBlue = m_tResPixelArray[i][j].rgbGreen =
- m_tResPixelArray[i][j].rgbRed = (int)(method1->m_pBinaryArray[i][j]*255);
-
- }
- // MakeBitMap();
-
- SetCursor(LoadCursor(NULL,IDC_ARROW));
- //MyDraw();
- }
- ////////////////////////////////////////////////////////////////////////////////
- // 画图
- ////////////////////////////////////////////////////////////////////////////////
- /*
- void CFaceDetectDoc::MyDraw()
- {
- CRect rc;
-
- m_pResMap=new CBitmap();
- pDCShow->GetWindow()->GetClientRect(&rc);
- pDCShow->Rectangle(&rc);
- CDC dc;
- CBitmap *pOldBitmap;
- dc.CreateCompatibleDC(pDCShow);
-
- pOldBitmap=dc.SelectObject(m_pResMap);
- pDCShow->StretchBlt(0,0,m_nWndWidth,m_nWndHeight,&dc,0,0,m_nWndWidth,m_nWndHeight,SRCCOPY);
- dc.SelectObject(pOldBitmap);
- dc.DeleteDC();
- }
- */
- ////////////////////////////////////////////////////////////////////////////////
- // 垂直方向的直方图
- ////////////////////////////////////////////////////////////////////////////////
- void CFaceDetectDoc::HistogramV()
- {
-
- SetCursor(LoadCursor(NULL,IDC_WAIT));
- for(int i=0; i<m_nWndHeight; i++)
- {
- int count = 0;
- for(int j=0; j<m_nWndWidth; j++)
- {
- if(method1->m_pBinaryArray[i][j] == 1) count++;
- m_tResPixelArray[i][j].rgbBlue = m_tResPixelArray[i][j].rgbGreen =
- m_tResPixelArray[i][j].rgbRed = 255;
- }
- for(j=0; j<count; j++)
- {
- m_tResPixelArray[i][j].rgbBlue = m_tResPixelArray[i][j].rgbGreen =
- m_tResPixelArray[i][j].rgbRed = 0;
- }
- }
-
- // MakeBitMap();
- SetCursor(LoadCursor(NULL,IDC_ARROW));
- }
- ////////////////////////////////////////////////////////////////////////////////
- // 水平方向直方图
- ////////////////////////////////////////////////////////////////////////////////
- void CFaceDetectDoc::OnBtnHistogramH()
- {
- SetCursor(LoadCursor(NULL,IDC_WAIT));
- for(int j=0; j<m_nWndWidth; j++)
- {
- int count = 0;
- for(int i=0; i<m_nWndHeight; i++)
- {
- if(method1->m_pBinaryArray[i][j] == 1) count++;
- m_tResPixelArray[i][j].rgbBlue = m_tResPixelArray[i][j].rgbGreen =
- m_tResPixelArray[i][j].rgbRed = 255;
- }
- for(i=m_nWndHeight-1; i>=m_nWndHeight-count;i--)
- {
- m_tResPixelArray[i][j].rgbBlue = m_tResPixelArray[i][j].rgbGreen =
- m_tResPixelArray[i][j].rgbRed = 0;
- }
- }
-
- // MakeBitMap();
- SetCursor(LoadCursor(NULL,IDC_ARROW));
- }
- ////////////////////////////////////////////////////////////////////////////////
- //标记脸部区域
- ////////////////////////////////////////////////////////////////////////////////
- void CFaceDetectDoc::OnBtnMarkFace()
- {
-
-
- SetCursor(LoadCursor(NULL,IDC_WAIT));
- int *temp = new int[m_nWndWidth];
- int max = 0;
- int pos = -1;
- for(int j=0; j<m_nWndWidth; j++)////////////////计算出每行占有的脸部像素点数
- {
- int count = 0;
- for(int i=0; i<m_nWndHeight; i++)
- {
- if(method1->m_pBinaryArray[i][j]== 1) count++;
- }
- temp[j] = count;
- if(count > max)////////////////////////获取哪一行具有的脸部像素点数最多,记下数目和第几行
- {
- max = count;
- pos = j;
- }
- }
-
- for(l=pos; l>=0; l--)////////////////////////向上获取具有的脸部像素点数最多的一半的行
- {
- if(temp[l]<max*0.2||l==0)
- {
- left = l;
- break;
- }
- }
- for(l=pos; l<m_nWndWidth; l++)////////////////////////向下获取具有的脸部像素点数最多的1/3的行
- {
- if(temp[l]<max*0.3||l==m_nWndWidth-1)
- {
- right = l;
- break;
- }
- }
-
- for(int i=0; i<m_nWndHeight; i++)
- {
- int count = 0;
- for(l = left;l<=right;l++)
- {
- if(method1->m_pBinaryArray[i][l] == 1) count++;
- }
- if(count>=(right-left)*0.5)
- {
- top = i;
- break;
- }
- }
- bottom = (int)(top+(right-left)*1.5)>=m_nWndHeight? m_nWndHeight-1:(int)(top+(right-left)*1.5);
- CopyBitMap(m_tResPixelArray,m_tOriPixelArray);
-
- for(i=top;i<=bottom;i++)
- {
- m_tResPixelArray[i][left].rgbBlue=255;
- m_tResPixelArray[i][left].rgbGreen = m_tResPixelArray[i][left].rgbRed = 0;
- m_tResPixelArray[i][right].rgbBlue=255;
- m_tResPixelArray[i][right].rgbGreen = m_tResPixelArray[i][right].rgbRed = 0;
- }
- for(j=left;j<=right;j++)
- {
- m_tResPixelArray[top][j].rgbBlue=255;
- m_tResPixelArray[top][j].rgbGreen = m_tResPixelArray[top][j].rgbRed = 0;
- m_tResPixelArray[bottom][j].rgbBlue=255;
- m_tResPixelArray[bottom][j].rgbGreen = m_tResPixelArray[bottom][j].rgbRed = 0;
- }
- // MakeBitMap();
-
- SetCursor(LoadCursor(NULL,IDC_ARROW));
- //////////////////////////////////////////////////////////////////////////////////////
-
- for(int h=bottom;h<m_nWndHeight;h++)
- { int count=0;
- for(int w=left;w<right;w++)
- {
- if(method1->m_pBinaryArray[h][w] == 1)
- count++;
- }
- if(count>=(right-left)*0.5)
- bottom++;
-
-
-
- }
-
- CFaceDetectView *Gd=new CFaceDetectView();
- Gd->DrawLine(left,top,bottom,right);
-
- //////////////////////////////////////////////////////////////////////////////////////
-
- if(m_bFaceOK)
- {
- //ReplaceDoc dlg;
- // if(dlg.DoModal()==IDOK)
- // {
- CopyBitMap(m_tResPixelArray,m_tOriPixelArray);
- CRect rect(left,top,right,bottom);
- m_rFaceRegion = rect;
- // MakeBitMap();
- //}
- }
- else
- {
- m_bFaceOK = true;
- CopyBitMap(m_tResPixelArray,m_tOriPixelArray);
- CRect rect(left,top,right,bottom);
- m_rFaceRegion = rect;
- // MakeBitMap();
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- // 拷贝位图
- // 参数: dest-目标位图指针
- // source-源位图指针
- ////////////////////////////////////////////////////////////////////////////////
- bool CFaceDetectDoc::CopyBitMap(RGBQUAD **dest, RGBQUAD **source)
- {
- if(source==NULL || dest==NULL)
- return false;
- for(int i=0; i<m_nWndHeight; i++)
- for(int j=0; j<m_nWndWidth; j++)
- dest[i][j]=source[i][j];
-
- return true;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // 生成新的位图
- ////////////////////////////////////////////////////////////////////////////////
- void CFaceDetectDoc::MakeBitMap()
- {
- CClientDC ClientDC(pDCShow->GetWindow());
- if(m_pResMap!=NULL) delete m_pResMap;
- m_pResMap=new CBitmap();
- m_pResMap->CreateCompatibleBitmap(&ClientDC,m_nWndWidth,m_nWndHeight);
- CDC dc;
- dc.CreateCompatibleDC(&ClientDC);
- dc.SelectObject(m_pResMap);
- for(int i=0; i<m_nWndHeight; i++)
- for(int j=0; j<m_nWndWidth; j++)
- dc.SetPixelV(j,i,RGB(m_tResPixelArray[i][j].rgbRed,m_tResPixelArray[i][j].rgbGreen,m_tResPixelArray[i][j].rgbBlue));
-
- if(m_bFaceOK )
- {
- CBrush Pen;
- Pen.CreateSolidBrush(RGB(255,0,0));
- dc.FrameRect(m_rFaceRegion,&Pen);
- Pen.DeleteObject();
- }
- if(m_bLeftEyeOK) DrawCross(&dc,m_LeftEye,RGB(255,0,0));
- if(m_bRightEyeOK) DrawCross(&dc,m_RightEye,RGB(255,0,0));
- if(m_bLeftEyeLeftCornerOK) DrawCross(&dc,m_LeftEyeLeftCorner,RGB(255,0,255));
- if(m_bLeftEyeRightCornerOK) DrawCross(&dc,m_LeftEyeRightCorner,RGB(255,255,0));
- if(m_bRightEyeLeftCornerOK) DrawCross(&dc,m_RightEyeLeftCorner,RGB(255,0,255));
- if(m_bRightEyeRightCornerOK) DrawCross(&dc,m_RightEyeRightCorner,RGB(255,255,0));
- if(m_bLeftNostrilOK) DrawCross(&dc,m_LeftNostril,RGB(0,255,0));
- if(m_bRightNostrilOK) DrawCross(&dc,m_RightNostril,RGB(0,255,0));
- if(m_bMidNoseOK) DrawCross(&dc,m_MidNose,RGB(0,255,0));
- if(m_bLeftMouthCornerOK) DrawCross(&dc,m_LeftMouthCorner,RGB(0,0,255));
- if(m_bRightMouthCornerOK) DrawCross(&dc,m_RightMouthCorner,RGB(0,0,255));
- if(m_bMidMouthOK) DrawCross(&dc,m_MidMouth,RGB(0,0,255));
- dc.DeleteDC();
- // MyDraw();
- }
- ////////////////////////////////////////////////////////////////////////////////
- // 画十字形标记
- // 参数: pDC-CDC指针
- // point-要画的点的坐标
- // crColor-标记得颜色
- ////////////////////////////////////////////////////////////////////////////////
- void CFaceDetectDoc::DrawCross(CDC *pDC, CPoint point, COLORREF crColor)
- {
- CPen pen,*oldPen;
- pen.CreatePen(PS_SOLID,1,crColor);
- oldPen = (CPen*)pDC->SelectObject(&pen);
- pDC->MoveTo(point.x-7,point.y);
- pDC->LineTo(point.x+7,point.y);
- pDC->MoveTo(point.x,point.y-7);
- pDC->LineTo(point.x,point.y+7);
- pDC->SelectObject(oldPen);
- pen.DeleteObject();
- }