xjy427() ( ) 信誉:100    Blog   加为好友  2007-5-6 16:55:56  得分: 0  
 
 
   
原来这里没有人脸识别的高手啊  都时菜鸟啊 呵呵  
 
Top  
 xjy427() ( ) 信誉:100    Blog   加为好友  2007-5-6 16:56:37  得分: 0  
 
 
   
可能我的问题太难了 没有人能回答我吧 呵呵 谁叫咱时高手呢  世界级的难题  
 
Top  ==============================================
就你这种素质,以后别来CSDN了吧

解决方案 »

  1.   

    #include "stdafx.h"
    #include "FaceDetect.h"
    #include "FaceDetectDlg.h"
    #include "ReplaceDlg.h"#ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif#include "AddSampleDlg.h"/////////////////////////////////////////////////////////////////////////////
    // CAboutDlg dialog used for App Aboutclass CAboutDlg : public CDialog
    {
    public:
    CAboutDlg();// Dialog Data
    //{{AFX_DATA(CAboutDlg)
    enum { IDD = IDD_ABOUTBOX };
    //}}AFX_DATA // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CAboutDlg)
    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
    //}}AFX_VIRTUAL// Implementation
    protected:
    //{{AFX_MSG(CAboutDlg)
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
    };CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
    {
    //{{AFX_DATA_INIT(CAboutDlg)
    //}}AFX_DATA_INIT
    }void CAboutDlg::DoDataExchange(CDataExchange* pDX)
    {
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CAboutDlg)
    //}}AFX_DATA_MAP
    }BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
    //{{AFX_MSG_MAP(CAboutDlg)
    // No message handlers
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
    // CFaceDetectDlg dialogCFaceDetectDlg::CFaceDetectDlg(CWnd* pParent /*=NULL*/)
    : CDialog(CFaceDetectDlg::IDD, pParent)
    {
    //{{AFX_DATA_INIT(CFaceDetectDlg)
    // NOTE: the ClassWizard will add member initialization here
    //}}AFX_DATA_INIT
    // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    }void CFaceDetectDlg::DoDataExchange(CDataExchange* pDX)
    {
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CFaceDetectDlg)
    // NOTE: the ClassWizard will add DDX and DDV calls here
    //}}AFX_DATA_MAP
    }BEGIN_MESSAGE_MAP(CFaceDetectDlg, CDialog)
    //{{AFX_MSG_MAP(CFaceDetectDlg)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_BN_CLICKED(IDC_BTN_BINARY, OnBtnBinary)
    ON_BN_CLICKED(IDC_BTN_EDGE, OnBtnEdge)
    ON_BN_CLICKED(IDC_BTN_FACEHAIR, OnBtnFacehair)
    ON_BN_CLICKED(IDC_BTN_HISTOGRAM_FACE, OnBtnHistogramFace)
    ON_BN_CLICKED(IDC_BTN_HISTOGRAM_H, OnBtnHistogramH)
    ON_BN_CLICKED(IDC_BTN_HISTOGRAM_HAIR, OnBtnHistogramHair)
    ON_BN_CLICKED(IDC_BTN_HISTOGRAM_V, OnBtnHistogramV)
    ON_BN_CLICKED(IDC_BTN_LIKEHOOD, OnBtnLikehood)
    ON_BN_CLICKED(IDC_BTN_MARK_EYE, OnBtnMarkEye)
    ON_BN_CLICKED(IDC_BTN_MARK_FACE_1, OnBtnMarkFace1)
    ON_BN_CLICKED(IDC_BTN_MARK_FACE_2, OnBtnMarkFace2)
    ON_BN_CLICKED(IDC_BTN_MARK_MOUSE, OnBtnMarkMouse)
    ON_BN_CLICKED(IDC_BTN_MARK_NOSE, OnBtnMarkNose)
    ON_BN_CLICKED(IDC_BTN_OPENFILE, OnBtnOpenfile)
    ON_BN_CLICKED(IDC_BMPSHOW, OnBmpshow)
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
    // CFaceDetectDlg message handlersBOOL CFaceDetectDlg::OnInitDialog()
    {
    CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range.
    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE);
    if (pSysMenu != NULL)
    {
    CString strAboutMenu;
    strAboutMenu.LoadString(IDS_ABOUTBOX);
    if (!strAboutMenu.IsEmpty())
    {
    pSysMenu->AppendMenu(MF_SEPARATOR);
    pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
    }
    } // Set the icon for this dialog.  The framework does this automatically
    //  when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE); // Set big icon
    SetIcon(m_hIcon, FALSE); // Set small icon

    // TODO: Add extra initialization here
    CWnd *pWnd0= GetDlgItem(IDC_BMPSHOW);
    pDCShow = pWnd0->GetDC(); m_pMainDib = new CDib(); m_tOriPixelArray = NULL;
    m_tResPixelArray = NULL; m_pResMap = NULL; m_nWndWidth = 0;
    m_nWndHeight= 0;
    m_sFileName = ""; m_bSelectByMan = false;
    m_bLBottonDown = false; m_ManLeft = -1;
    m_ManRight = -1;
    m_ManTop = -1;
    m_ManBottom = -1; m_bFaceOK = false;
    m_bShowFace = false;
    m_rFaceRegion.left = m_rFaceRegion.right = m_rFaceRegion.top = m_rFaceRegion.bottom = 0; m_bManualMarkFacial = false;
    m_bLeftEyeOK = m_bRightEyeOK = m_bLeftNostrilOK = m_bRightNostrilOK =
    m_bLeftEyeLeftCornerOK = m_bLeftEyeRightCornerOK = m_bRightEyeLeftCornerOK = 
    m_bRightEyeRightCornerOK = m_bLeftMouthCornerOK = m_bRightMouthCornerOK = false; m_bMidMouthOK = m_bMidNoseOK = false; m_LeftEye = m_RightEye = m_LeftEyeLeftCorner = m_LeftEyeRightCorner = 
    m_LeftNostril = m_RightNostril = m_RightEyeLeftCorner = m_RightEyeRightCorner =
    m_LeftMouthCorner = m_RightMouthCorner = m_MidMouth = m_MidNose = CPoint(-1,-1);

    return TRUE;  // return TRUE  unless you set the focus to a control
    }
      

  2.   

    void CFaceDetectDlg::OnSysCommand(UINT nID, LPARAM lParam)
    {
    if ((nID & 0xFFF0) == IDM_ABOUTBOX)
    {
    CAboutDlg dlgAbout;
    dlgAbout.DoModal();
    }
    else
    {
    CDialog::OnSysCommand(nID, lParam);
    }
    }// If you add a minimize button to your dialog, you will need the code below
    //  to draw the icon.  For MFC applications using the document/view model,
    //  this is automatically done for you by the framework.void CFaceDetectDlg::OnPaint() 
    {
    if (IsIconic())
    {
    CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle
    int cxIcon = GetSystemMetrics(SM_CXICON);
    int cyIcon = GetSystemMetrics(SM_CYICON);
    CRect rect;
    GetClientRect(&rect);
    int x = (rect.Width() - cxIcon + 1) / 2;
    int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon
    dc.DrawIcon(x, y, m_hIcon); if(m_tResPixelArray==NULL) return;
    }
    else
    {
    CDialog::OnPaint();
    }
    }// The system calls this to obtain the cursor to display while the user drags
    //  the minimized window.
    HCURSOR CFaceDetectDlg::OnQueryDragIcon()
    {
    return (HCURSOR) m_hIcon;
    }////////////////////////////////////////////////////////////////////////////////
    // 画十字形标记
    // 参数:  pDC-CDC指针
    //         point-要画的点的坐标
    //         crColor-标记得颜色
    ////////////////////////////////////////////////////////////////////////////////
    void CFaceDetectDlg::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();
    }////////////////////////////////////////////////////////////////////////////////
    // 拷贝位图
    // 参数:  dest-目标位图指针
    //         source-源位图指针
    ////////////////////////////////////////////////////////////////////////////////
    bool CFaceDetectDlg::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 CFaceDetectDlg::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 && m_bShowFace)
    {
    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();
    }
      

  3.   

    ///////////////////////////////////////////////////////////////////////////////////
    //读原图的数据
    ////////////////////////////////////////////////////////////////////////////////////
    void CFaceDetectDlg::LoadOriPixel(CDib *pDib)
    {
    BYTE *colorTable;
    colorTable = (BYTE *)pDib->m_pDibBits;
    int byteBitCount  = pDib->GetBiBitCount()/8; m_tOriPixelArray  = new RGBQUAD*[m_nWndHeight];
    m_tResPixelArray  = new RGBQUAD*[m_nWndHeight];
    for(int l=0 ; l<m_nWndHeight; l++)
    {
    m_tOriPixelArray[l] = new RGBQUAD[m_nWndWidth];
    m_tResPixelArray[l] = new RGBQUAD[m_nWndWidth];
    } int count = 0;
    for(int i=m_nWndHeight-1; i>=0; i--)
    {
    for(int j=0; j<m_nWndWidth; j++)
    {
    m_tOriPixelArray[i][j].rgbBlue =colorTable[count++];
    m_tOriPixelArray[i][j].rgbGreen=colorTable[count++];
    m_tOriPixelArray[i][j].rgbRed  =colorTable[count++];
    m_tOriPixelArray[i][j].rgbReserved = 0;
    m_tResPixelArray[i][j]=m_tOriPixelArray[i][j];
    count += byteBitCount-3;
    }
    count += (4-(m_nWndWidth*byteBitCount)%4)%4;
    } method1 = new CLikelyHood(m_tOriPixelArray,m_nWndWidth,m_nWndHeight);
    method2 = new CHairFace(m_tOriPixelArray,m_nWndWidth,m_nWndHeight);
    }////////////////////////////////////////////////////////////////////////////////
    // 给位图赋值
    // 参数:  target-目标位图指针
    //         Val-要赋予的值
    ////////////////////////////////////////////////////////////////////////////////
    void CFaceDetectDlg::SetPixelArray(RGBQUAD **target, int Val)
    {
    for(int i=0; i<m_nWndHeight; i++)
    for(int j=0; j<m_nWndWidth; j++)
    {
    target[i][j].rgbRed =  target[i][j].rgbBlue = target[i][j].rgbGreen = Val;
    }
    }////////////////////////////////////////////////////////////////////////////////
    // 边界检测
    ////////////////////////////////////////////////////////////////////////////////
    void CFaceDetectDlg::DoLOG(int left, int right, int top, int bottom, RGBQUAD **source, RGBQUAD **target)
    {
    int i,j; double **result;  
    result = new double*[m_nWndHeight];
    for(int l=0 ; l<m_nWndHeight; l++)
    {
    result[l] = new double[m_nWndWidth];
    for(j=0; j<m_nWndWidth; j++)
    result[l][j] = source[l][j].rgbRed;
    }

    for(i=0; i<m_nWndHeight; i++)
    for(j=0; j<m_nWndWidth; j++)
    {
    double r,g,temp;
    temp = source[i][j].rgbGreen+source[i][j].rgbRed+source[i][j].rgbBlue;
    r = (double)source[i][j].rgbRed/temp;
    g = (double)source[i][j].rgbGreen/temp;
    if(g<0.398 && g > 0.246 && r<0.664 && r>0.233 && r>g && g>=0.5*(1-r))
    {
    target[i][j].rgbRed = 255;  //face
    }
    else target[i][j].rgbRed = 0;
    }

    for(i=top+2; i<bottom-2; i++)
    for(j=left+2; j<right-2; j++)
    {
    result[i][j] =  
         (0-2.0/24.0)*((unsigned char)target[i-2][j-2].rgbRed) + 
                     (0-4.0/24.0)*((unsigned char)target[i-2][j-1].rgbRed) + 
         (0-4.0/24.0)*((unsigned char)target[i-2][j].rgbRed)   +
         (0-4.0/24.0)*((unsigned char)target[i-2][j+1].rgbRed) +
         (0-2.0/24.0)*((unsigned char)target[i-2][j+2].rgbRed) +
     (0-4.0/24.0)*((unsigned char)target[i-1][j-2].rgbRed) + 
     (8.0/24.0)  *((unsigned char)target[i-1][j].rgbRed)   +
     (0-4.0/24.0)*((unsigned char)target[i-1][j+2].rgbRed) +
     (0-4.0/24.0)*((unsigned char)target[i][j-2].rgbRed)   + 
     (8.0/24.0)  *((unsigned char)target[i][j-1].rgbRed)   + 
     (1.0)       *((unsigned char)target[i][j].rgbRed)     +
     (8.0/24.0)  *((unsigned char)target[i][j+1].rgbRed)   +
     (0-4.0/24.0)*((unsigned char)target[i][j+2].rgbRed)   +
     (0-4.0/24.0)*((unsigned char)target[i+1][j-2].rgbRed) + 
     (8.0/24.0)  *((unsigned char)target[i+1][j].rgbRed)   +
     (0-4.0/24.0)*((unsigned char)target[i+1][j+2].rgbRed) +
     (0-2.0/24.0)*((unsigned char)target[i+2][j-2].rgbRed) + 
     (0-4.0/24.0)*((unsigned char)target[i+2][j-1].rgbRed) + 
     (0-4.0/24.0)*((unsigned char)target[i+2][j].rgbRed)   +
     (0-4.0/24.0)*((unsigned char)target[i+2][j+1].rgbRed) +
     (0-2.0/24.0)*((unsigned char)target[i+2][j+2].rgbRed);
    } SetPixelArray(target,255); for(i=top+1; i<bottom-1; i++)
    for(j=left+1; j<right-1; j++)
    {
    int positive = 0;   
    int negtive  = 0;
    for(int m=-1;m<=1;m++)
    for(int n=-1;n<=1;n++)
    if(m!=0 || n!=0)
    {
    if(result[i+m][j+n]<-5)negtive++;
    if(result[i+m][j+n]>=5)positive++;
    }
    if(positive>2 && negtive>2) 
    {
    target[i][j].rgbBlue = target[i][j].rgbGreen = target[i][j].rgbRed = 0;
    } } if(result!=NULL)
    {
    for (int i=0 ;i<m_nWndHeight;i++)
    if(result[i]!=NULL) delete result[i];
    delete result;
    }
    }////////////////////////////////////////////////////////////////////////////////
    // 二值化
    ////////////////////////////////////////////////////////////////////////////////
    void CFaceDetectDlg::OnBtnBinary() 
    {
    SetCursor(LoadCursor(NULL,IDC_WAIT));

    if(!method1->CalBinary())
    {
    AfxMessageBox("请先计算相似度!");
    SetCursor(LoadCursor(NULL,IDC_ARROW));
    return;
    }

    m_bShowFace = false;
    for(int i=0; i<m_nWndHeight; i++)
    for(int 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 CFaceDetectDlg::OnBtnEdge() 
    {
    if(!m_bFaceOK)
    {
    AfxMessageBox("请先确定脸部区域");
    return;
    }
    //左右眼的水平区域
    int nLeft,nRight,nTop,nBottom; nLeft = m_rFaceRegion.left-5  > 0 ? m_rFaceRegion.left-5:0;
    nRight = m_rFaceRegion.right+5 < m_nWndWidth? m_rFaceRegion.right+5:m_nWndWidth-1;
    nTop = m_rFaceRegion.top-5   > 0 ? m_rFaceRegion.top-5:0;
    nBottom = m_rFaceRegion.bottom+5< m_nWndHeight?m_rFaceRegion.bottom+5:m_nWndHeight-1;
    //边缘检查
    DoLOG(nLeft,nRight,nTop,nBottom,m_tOriPixelArray,m_tResPixelArray);
    MakeBitMap();
    }////////////////////////////////////////////////////////////////////////////////
    // 求取头发和脸部区域
    ////////////////////////////////////////////////////////////////////////////////
    void CFaceDetectDlg::OnBtnFacehair() 
    {
    m_bShowFace = false;
    SetCursor(LoadCursor(NULL,IDC_WAIT));
    method2->MarkHairFace();
    for(int i=0; i<m_nWndHeight; i++)
    for(int j=0; j<m_nWndWidth;  j++)
    {
    switch(method2->m_pBinaryArray[i][j])
    {
    case 0:
    m_tResPixelArray[i][j].rgbBlue = m_tResPixelArray[i][j].rgbGreen = 0;
    m_tResPixelArray[i][j].rgbRed  = 255;
    break;
    case 1:
    m_tResPixelArray[i][j].rgbBlue = 255;
    m_tResPixelArray[i][j].rgbGreen=m_tResPixelArray[i][j].rgbRed=0;
    break;
    case 2:
    m_tResPixelArray[i][j].rgbBlue = m_tResPixelArray[i][j].rgbGreen =
    m_tResPixelArray[i][j].rgbRed  = 0;
    break;
    }
    }
    MakeBitMap();
    SetCursor(LoadCursor(NULL,IDC_ARROW));
    }////////////////////////////////////////////////////////////////////////////////
    // 脸部区域直方图
    ////////////////////////////////////////////////////////////////////////////////
    void CFaceDetectDlg::OnBtnHistogramFace() 
    {
    if(!method2->m_bBinaryOK)
    {
    AfxMessageBox("请先计算二值化图!");
    return;
    } m_bShowFace = false;
    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(method2->m_pBinaryArray[i][j] == 0) 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));
    }