人脸识别驱动usb继电器开关灯(二)(vc++)

接着上一节,显示我们得到的灰度图像buffer(byte*),并且传递给人脸识别代码

一,显示灰度图像buffer(byte*)

1,要显示,就要用gdi,头文件和库已经加载了,下面是在detectFace.h下声明:

public:
    GdiplusStartupInput gdiplusInput;
    ULONG_PTR           gdiplusToken;

2,在detectFace.cpp的BOOL CdetectFaceApp::InitInstance()函数中启动gdi:

/////////////////////////
    ::GdiplusStartup(&gdiplusToken,&gdiplusInput,NULL);

3,在detectFace.cpp的int CdetectFaceApp::ExitInstance()函数中关闭gdi://程序退出时

/////////////////
      GdiplusShutdown(gdiplusToken);

4,在IDC_STATIC_PIC控件中显示灰度图像buffer(byte*)

a,使用这样一个类class CPicZoom : public CWnd{......省略了mfc自己生成的代码}

b,新添加一个IDC_STATIC_PIC控件()变量(默认),如此替换他://vs2010 vc++

    public:   CPicZoom m_Pic;// public:  CStatic m_Pic;

void CdetectFaceDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_STATIC_PIC, m_Pic);

}

5,在m_pic的onpaint函数中显示图像:

void CPicZoom::OnPaint()
{
    CPaintDC dc(this); // device context for painting
    // TODO: 在此处添加消息处理程序代码
    // 不为绘图消息调用 CWnd::OnPaint()
    CdetectFaceDlg  *pm=(CdetectFaceDlg  *)::AfxGetMainWnd ();
    if(pm->m_bcopyed)
    {
        Graphics graph(dc.m_hDC);                
            Bitmap bitmap(640,
            480,
            640*3 ,
            PixelFormat24bppRGB, 
            pm->m_buffer8dst);      
        graph.DrawImage(&bitmap,0, 0);           
    }
}

二,传递给人脸识别代码

1,人脸识别的头文件和库要拷贝到项目目录下,stdafx.h已经正确加载。

2,人脸识别需要加载的.xml文件,opencv有提供,拷贝过来放在目录下,声明为全局变量。

const char* cascade_name = "haarcascade_frontalface_alt.xml";
const char* nested_cascade_name =
    "C:\\Program Files\\OpenCV\\data\\haarcascades\\haarcascade_eye_tree_eyeglasses.xml";

3,人脸识别代码:

使用timer定时器调用它:void CdetectFaceDlg::OnTimer(UINT_PTR nIDEvent)
{

    if(2==nIDEvent)//程序初始化时,启动timer2.
    {
        OnBnClickedBtFacedetect2();
        if(b_isface){
         //这里可以打开继电器了201911102109
       // usb_relay_init();//放到程序初始化中去
         //   struct usb_relay_device_info *device_info = usb_relay_device_enumerate();//放到程序初始化中去
            m_hCurDevice=    usb_relay_device_open(device_info); //打开继电器
          usb_relay_device_open_one_relay_channel(m_hCurDevice, 1); //打开继电1
    b_isface=false;   
        }
    }

}

////////////////////////////////////

void CdetectFaceDlg::OnBnClickedBtFacedetect2()
{
    // TODO: 在此添加控件通知处理程序代码
    nestedCascade = (CvHaarClassifierCascade*)cvLoad( nested_cascade_name, 0, 0, 0 );
    Cascade=(CvHaarClassifierCascade*)  cvLoad( cascade_name, 0,0,0);
    ////////////        
        pTest24byte=cvCreateImage(cvSize(640,480),8,3);//使用了24位灰度图像

        cvSetData(pTest24byte,m_buffer8dst,640*3);//测试成功ok201911101905
    //////////////////pTestgrey
          pTestgrey = cvCreateImage( cvSize(pTest24byte->width,pTest24byte->height),
                                            IPL_DEPTH_8U, pTest24byte->nChannels );
            
                cvCopy( pTest24byte, pTestgrey, 0 );
    if(Cascade)
    {
        //CvMemStorage* 
        storage=cvCreateMemStorage(0);
        cvNamedWindow("人脸检测",1);
        if(pTestgrey)
        {        
            detect_and_drawSE(pTestgrey);//最后一句opencv异常,使用24位图像后正常            
           
        }
        cvReleaseImage(&pTestgrey);
        cvReleaseMemStorage(&storage);
    }
    cvReleaseHaarClassifierCascade(&Cascade);    
}

/////////////////////////////////

void CdetectFaceDlg::detect_and_drawSE(IplImage *img)
{
    static CvScalar colors[]=
    {
        {{0,0,255}},
        {{0,128,255}},
        {{0,255,255}},
        {{0,255,0}},
        {{255,128,0}},
        {{255,255,0}},
        {{255,0,0}},
        {{255,0,255}}
    };
double scale=1.3;
IplImage* gray=cvCreateImage(cvSize(img->width,img->height),8,1);
IplImage* small_img=cvCreateImage(cvSize(cvRound(img->width/scale),cvRound(img->height/scale)),8,1);
int i;

cvCvtColor(img,gray,CV_BGR2GRAY);//变为opencv自己想要的灰度图像

cvResize(gray,small_img,CV_INTER_LINEAR);
cvEqualizeHist(small_img,small_img);//直方图均衡化
 cvClearMemStorage(storage);
if(Cascade)
{
    //CvSeq* faces=cvHaarDetectObjects(small_img,Cascade,storage,1.1,2,0,cvSize(640,480));
     CvSeq* faces = cvHaarDetectObjects( small_img, Cascade, storage,//人脸识别
                                            1.1, 2, 0
                                            //|CV_HAAR_FIND_BIGGEST_OBJECT
                                           // |CV_HAAR_DO_ROUGH_SEARCH
                                            |CV_HAAR_DO_CANNY_PRUNING//可以坎尼(canny)
                                           // |CV_HAAR_SCALE_IMAGE
                                            ,
                                            cvSize(30, 30) );
     if(faces->total>=1){b_isface=true;}//找到人脸
    for(i=0;i<(faces?faces->total:0);i++)//脸上画圆
    {
        CvRect* r=(CvRect*)cvGetSeqElem(faces,i);
        CvPoint centre;
        int radius;
        centre.x=cvRound((r->x+r->width*0.5)*scale);
        centre.y=cvRound((r->y+r->height*0.5)*scale);
        radius=cvRound((r->width+r->height)*0.25*scale);
        cvCircle(img,centre,radius,colors[i%8],3,8,0);
    }
    cvShowImage("人脸检测",img);
    cvReleaseImage(&gray);
    cvReleaseImage(&small_img);
}
}

三,usb免驱继电器开关不再列篇介绍了,这里顺便说明一下:

1,拷贝usb_relay_device.lib和usb_relay_device.dll及usb_relay_device.h三个文件到项目目录下。

2,stdafx.h已经加载,你也看到,在前一篇。

3,然后在oninitdialog()中初始化继电器:

    usb_relay_init();//放到程序初始化中去
    struct usb_relay_device_info *device_info = usb_relay_device_enumerate();//放到程序初始化中去

4,有人脸时,bool值为true,打开继电器。代码上面有,已经写入。

5,程序退出或者没有人脸时bool值为false,关闭继电器。

usb_relay_device_close_one_relay_channel(m_hCurDevice, 1);//关闭继电器1
 usb_relay_device_close(m_hCurDevice);

6,m_hCurDevice是int类型的。

加油,c#代码也快了,期待中..........

待续(慢慢来!...........)每天一点小改变☺

我的邮箱[email protected];[email protected]

发布了66 篇原创文章 · 获赞 12 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/ganggangwawa/article/details/103107955
今日推荐