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

人脸识别已经遇到好几年了(2013),在opencv中,今天终于抄过来了,发现不完美,但以后可以慢慢改进,家里先用上再说,干什么?开关灯呗,在工作上,程序驱动开关,已经不算什么,但对于家用,可以激活父母孩子的好奇心,时代嘛,应该是老百姓的嘛!电脑有了,摄像头有了,不可能再花个电脑的价钱买个开关吧(机器视觉的开关好贵啊!)?某宝淘到一个usb继电器开关(不到十五元),有硬件,有源代码,可以二次开发,可以尝试一把,走起!多好的一个时代啊!

         电脑摄像头的代码有了!

        opencv的人脸识别代码有了!

        usb继电器开关代码也有了!

把他装起来,硬件和软件,diy(do it yourself!),看到这些字,一些青春年华做过的事,又从眼前飘过,多么熟悉啊!沉淀的岁月,就剩下这几个字,这种影响,成为习惯,深入骨髓,那么,借此,就继续发扬和传承下去!

这一次使用visual c++,关于c#,就剩opencv的人脸识别代码翻译工作了,等待完成,还是那句话,c++可以搞定的,c#不在话下!是不是有点那个?二!

vs2010用c++写程序都快吐了,函数一点提示都没有,还好完成了,vs2013使用c++好多了,就像又回到vs2005下的c++时代,我们废话少说,先上摄像头代码:

1,在stdafx.h中:

#include "cv.h"
#include"highgui.h"//以上使用opencv1.0人脸识别需要使用的
#include
#pragma comment(lib,"vfw32")

#include
using namespace Gdiplus;
#pragma comment(lib,"gdiplus")//以上是摄像头需要使用的库和头文件

#include "usb_relay_device.h"
#pragma comment(lib, "usb_relay_device.lib")//以上是usb继电器开关需要使用的库和头文件//

需要说明的是,你需要安装opencv1.0(网上下载一个,十几mbytes,很小),usb继电器开关的库和头文件,购买时会提供你下载地址(看似很多的代码,吓人一大跳!一只纸老虎,关键代码就几句,想起了那个opt的串口光源控制器,价格不菲啊!关键要学会读懂人家说明书!)。

2,摄像头取像:因为人脸识别时,会显示图像,所以设置图像显示为disabled,另外你传递给人脸识别的图像buffer,也有显示,为了验证这个图像buffer是否ok,他已经变换为灰度图: 

BOOL CdetectFaceDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

.............省略了mfc自己生成的代码

   CWnd *pCarryWnd=this->GetDlgItem(IDC_STATIC_ADD);//IDD_DETECTFACE_DIALOG
    CRect rect;
    pCarryWnd->GetClientRect(&rect);
   
    this->m_hCamWnd=capCreateCaptureWindow("MY CAM",WS_CHILD|WS_DISABLED,0,0,rect.Width(),rect.Width(),pCarryWnd->GetSafeHwnd(),0);
    if(!capDriverConnect(m_hCamWnd,0))//win7和win8.1下:  while (capDriverConnect(m_hCamWnd,0)!=true)                     
       {return true;}/////////////////////////////////////////  win7和win8.1下: {  continue;}
             
    CAPDRIVERCAPS cpas;
    capDriverGetCaps(m_hCamWnd,sizeof(cpas),&cpas);
    if(cpas.fCaptureInitialized)
    {        
        capPreviewRate(m_hCamWnd,25);
        capPreview(m_hCamWnd,true);
       SetTimer(1,100,0);     ////计时器
    }
    return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

3,在计时器中void CdetectFaceDlg::OnTimer(UINT_PTR nIDEvent),把图像buffer(byte*)取出来给人脸识别用(这里边使用了剪贴板技术,虽然笨,但通关了)(虽然现在进步了,曾经不敢忘):  

 if(1==nIDEvent)
    if(capCaptureSingleFrameOpen(m_hCamWnd))
    {
        //成功则捕捉
        if(capCaptureSingleFrame(m_hCamWnd))                        
        {
            //捕捉成功则关闭
            if(capCaptureSingleFrameClose(m_hCamWnd))
            {

if(capGrabFrameNoStop(m_hCamWnd))//////////////////////
        {            
                capEditCopy(m_hCamWnd);

                EmptyClipboard();
                CloseClipboard();
                if(IsClipboardFormatAvailable(CF_DIB))//vfw只能提供640*480的图像
                {
                    if(OpenClipboard())
                    {
                       GLOBALHANDLE hGMem;
                       LPBITMAPINFO lpbi;
                       byte * pdibBits;
                       hGMem=GetClipboardData(CF_DIB);
                       lpbi=(LPBITMAPINFO)GlobalLock(hGMem);
                       pdibBits=(byte*)(lpbi+1);
                       for(int i=479;i>=0;i--)
                       {
                           for(int j=0;j<640;j++)
                           {
                               m_buffer[i*640*4+j*4]=*pdibBits;
                               pdibBits++;
                               m_buffer[i*640*4+j*4+1]=*pdibBits;
                               pdibBits++;
                               m_buffer[i*640*4+j*4+2]=*pdibBits;
                               pdibBits++;
                               m_buffer[i*640*4+j*4+3]=128;
                           }
                       }
                       for(int j=0;j<480;j++)//我电脑的摄像头是颠倒的图像,下面代码针对它,进行了翻转
            for(int i=0;i<640;i++)
            {
                int n=j*640+i;
                int m=(480-j-1)*640+i;
                byte tempbt=(byte)(m_buffer[4*m]*0.3+m_buffer[4*m+1]*0.59+m_buffer[4*m+2]*0.11);
                m_buffer8org[n]=tempbt;
                /*m_buffer8org[j*640+i]=pm->m_buffer[4*m];*/

//当初只取了蓝色通道,翻转了180度,图像出来了,8位图像在c++下很搞怪,想起曾经这样过。201911101838
                m_buffer8dst[3*n]=tempbt;
                m_buffer8dst[3*n+1]=tempbt;
                m_buffer8dst[3*n+2]=tempbt;
            }//正确的方法是,显示要大于24位,即使8位图像
                      this->m_bcopyed=true;
                      this->m_Pic.Invalidate();
                       GlobalUnlock(hGMem);
                       CloseClipboard();                       
                    }
                }
            
        }
            }
        }
    }

摄像头技术讲完了,对比c#,真是繁琐复杂,困难重重。下一节我们使用人脸识别

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

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

 

你可能感兴趣的:(人脸识别驱动usb继电器开关灯,人脸识别驱动usb继电器开关灯)