美文网首页LinuxBB-black开发板[Linux arm-v8]OpenCv
arm-VS2017 opencv远程人脸识别--APPLE的学

arm-VS2017 opencv远程人脸识别--APPLE的学

作者: applecai | 来源:发表于2018-06-17 17:14 被阅读25次

    一,人脸识别问题记录:

    1. face_cascade.detectMultiScale报错empty。原来是忘记load xml对比数据集了。

    二,将来优化的空间

    arm开发板BB-Black的优化

    1. 视频采集延迟,不顺畅。
        需要修改方案。目前是采集yuyv后压缩成jpeg然后传给客户端。客户端decode解析后再识别人脸,然后显示到窗口。
    2. 开发板只能采集320*240的分辨率。
        需要修改驱动的buffer。
    3. 将来功能要做成能识别出摄像头中是否有人。有人则抓拍,当做白天的小偷监控。
        目前只是识别出人脸。而且侧面是识别不了的。只能正面识别。
    

    win+linxu PC将来优化空间

    1. client端640*480也还有buffer 65535限制的问题,需要优化。---这部分可以和linuxPC先优化。
    

    注:准备10月份之后再继续玩视频采集

    三,有图有真相

    人脸监控.png

    代码中imwrite的抓拍效果


    pic2.jpg

    运行中的BB-Black开发板


    BB-Black开发板连接摄像头.png

    四,arm server代码

    #include<unistd.h>
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<errno.h>
    #include<sys/types.h>
    #include<sys/socket.h>
    #include<netinet/in.h>
    #include <opencv2/core.hpp>
    #include <opencv2/videoio.hpp>
    #include <opencv2/highgui.hpp>
    #include <iostream>
    #include <vector>
    using namespace std; 
    
    #define MAXLINE 4096
    using namespace cv;
    
    string int2string(int value)
    {
        stringstream ss;
        ss<<value;
        return ss.str();
    }
    
    int main(int argc, char** argv)
    {
        int    listenfd, connfd;
        struct sockaddr_in     servaddr;
    
        if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 )
        {
            printf("create socket error: %s(errno: %d)\n",strerror(errno),errno);
            exit(0);
        }
    
        memset(&servaddr, 0, sizeof(servaddr));
        servaddr.sin_family = AF_INET;
        servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
        servaddr.sin_port = htons(8080);
    
        int opt = 1;
        if(setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,(const void *)&opt,sizeof(opt)))
        {
        perror("setsockopt");
        return -1;
        }
    
        if( bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1){
        printf("bind socket error: %s(errno: %d)\n",strerror(errno),errno);
        exit(0);
        }
    
        if( listen(listenfd, 10) == -1){
        printf("listen socket error: %s(errno: %d)\n",strerror(errno),errno);
        exit(0);
        }
            /* ---main task process--- */
        Mat frame;
        //--- INITIALIZE VIDEOCAPTURE
        VideoCapture cap;
        vector<unsigned char> inImage;  
        // open the default camera using default API
        cap.open(0);
        cap.set(CV_CAP_PROP_FRAME_HEIGHT,240);
        cap.set(CV_CAP_PROP_FRAME_WIDTH,320);   
        if (!cap.isOpened()) 
        {
            cerr << "ERROR! Unable to open camera\n";
            return -1;
        }
            printf("open camera success\n");
            cap.read(frame);
            printf("======waiting for client's apple request======\n");
        if( (connfd = accept(listenfd, (struct sockaddr*)NULL, NULL)) == -1){
                printf("accept socket error: %s(errno: %d)",strerror(errno),errno);
                exit(0);
        }
    
        
        
        char cok[1]={0x55};
        char cokstart[1]={0};
        int sizelen=0;
        int sizejpg=0;
        for (;;)
        {
            // wait for a new frame from camera and store it into 'frame'
            cap.read(frame);
            // check if we succeeded
            if (frame.empty()) {
                cerr << "ERROR! blank frame grabbed\n";
                break;
            }
    
            if (cok[0]==0x55){
                cok[0]=0;
                //printf("read one frame!\n");
                imencode(".jpg",frame,inImage);  
                int datalen=inImage.size();
    
                unsigned char *msgImage=new unsigned char[datalen]; 
    
                unsigned char msgLen[4];
                msgLen[0]=datalen >> 24;
                msgLen[1]=datalen >> 16;
                msgLen[2]=datalen >> 8;
                msgLen[3]=datalen;
                //printf("datalen=%x\n",datalen);
                sizelen=send(connfd,msgLen,4,0);
                    //printf("sizelen:%x",sizelen);
                for(int i=0;i<datalen;i++)  
                {  
                        msgImage[i]=inImage[i];  
                        //cout<<msgImage[i]<<endl;  
                } 
                recv(connfd,cokstart,1,0);
                if(cokstart[0] == 0x33)
                {
                    cokstart[0]=0x0;
                    //vector<char>vec;
                    //Mat img_decode;
                    //string filename="";
                    //cokstart[0]=0x0;
                    //for(int i=0;i<datalen;i++)
                    //{
                    //  vec.push_back(msgImage[i]);
                    //}
                    //img_decode =imdecode(vec,CV_LOAD_IMAGE_COLOR);
                    //j++;
                
                    //imshow("serpic",img_decode);
                    //usleep(1000);
                    //filename="sevpic"+int2string(j)+".jpg";
                    //imwrite(filename,img_decode);
    
                    sizejpg=send(connfd,msgImage,datalen,0);
                    //printf("sizejpg:%x",sizejpg);
                    usleep(10000);
    
    
                    recv(connfd,cok,1,0);
                }
            
            }
        }   
        
    
    
        close(listenfd);
        return 0;
    }
    

    五,VS2017 client代码

    // client.cpp: 定义控制台应用程序的入口点。
    //
    
    #include <stdio.h>
    #include <winsock2.h>
    #include <cv.h>
    #include <opencv2/core/core.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    #include <opencv2/objdetect.hpp>
    #include <WINSOCK2.H> 
    #include <Ws2tcpip.h>
    #pragma comment(lib,"ws2_32.lib")
    
    void detectAndDisplay(cv::Mat frame);
    
    cv::CascadeClassifier face_cascade;
    cv::CascadeClassifier eyes_cascade;
    
    /* tansfer int to string */
    std::string int2string(int value)
    {
        std::stringstream ss;
        ss << value;
        return ss.str();
    }
    
    int main(int argc, char** argv)
    {
        SOCKADDR_IN servaddr;
        WORD wVersionRequested;
        WSADATA wsaData;
        int err;
        /** Global variables */
        std::string face_cascade_name = "haarcascade_frontalface_alt2.xml";
        //导入级联分类器xml文件,并作文件是否存在的判断
        if (!face_cascade.load(face_cascade_name))
        {
            printf("--(!)Error loading face data\n");
            return -1;
        }
        /** Global variables */
        std::string eyes_cascade_name = "haarcascade_eye_tree_eyeglasses.xml";
        //导入级联分类器xml文件,并作文件是否存在的判断
        if (!eyes_cascade.load(eyes_cascade_name))
        {
            printf("--(!)Error loading eyes data\n");
            return -1;
        }   
        
        wVersionRequested = MAKEWORD(1, 1);
        err = WSAStartup(wVersionRequested, &wsaData);
        if (err != 0) {
            return 0;
        }
    
        if (LOBYTE(wsaData.wVersion) != 1 ||
            HIBYTE(wsaData.wVersion) != 1) {
            WSACleanup();
            return 0;
        }
    
        SOCKET sockfd = socket(AF_INET, SOCK_STREAM, 0);
    
        memset(&servaddr, 0, sizeof(servaddr));
        //servaddr.sin_addr.S_un.S_addr = inet_pton(AF_INET,"192.168.7.4",&servaddr.sin_addr);//服务器端的地址  
        //servaddr.sin_addr.S_un.S_addr = inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);//服务器端的地址 
        servaddr.sin_addr.S_un.S_addr = inet_addr("192.168.7.2");
        servaddr.sin_family = AF_INET;
        servaddr.sin_port = htons(8080);
        connect(sockfd, (SOCKADDR*)&servaddr, sizeof(SOCKADDR));
    
    
        #define BUF_SIZE 65535
        char buffer[BUF_SIZE];
        std::vector<char> vec;
        cv::Mat img_decode;
        //std::string filename = "";
        int size = 0;
        int mylen = 0;
        int j = 0;
        int getpic = 0;
        char cokstart[1] = { 0x33 };
        memset(buffer, 0, 4);
        while (1)
        {
            size = recv(sockfd, buffer, 4, 0);
    
            mylen = ((buffer[2] << 8)&(0xFF00)) | ((buffer[3])&(0xFF));
            if (mylen>1)
            {
                getpic = 1; //设置标志位,如第一次server没有连接上后续则不执行
            }
            if (mylen>0) {
                /*received length then send ack signal cokstart.*/
                send(sockfd, cokstart, 1, 0);
            }
            /* receive one frame of jpg data */
            while (mylen>0)
            {
                size = recv(sockfd, buffer, mylen, 0);
                printf("size is %d\n",size);
                //printf("mylen is %x\n",mylen);
                /* put char values to vector */
                for (int i = 0; i < mylen; i++)
                {
                    vec.push_back(buffer[i]);
                }
                if (mylen > size)
                {
                    mylen = mylen - size;
                }
                else
                {
                    mylen = 0;
                }
                
            }
            if (getpic==1)
            {
                /* decode jpg data */
                img_decode = cv::imdecode(vec, CV_LOAD_IMAGE_COLOR);
                /* release vector then ready to receive next frame */
                vec.clear();
                //cout << "vector capacity:"<<vec.capacity()<<endl;
                std::vector<char>(vec).swap(vec);
                //cout << "vector capacity afterswap:"<<vec.capacity()<<endl;
    
                //-- 3. Apply the classifier to the frame
                detectAndDisplay(img_decode);
                
                /* display the jpg in windows */
                //cv::namedWindow("detect_pic", cv::WINDOW_AUTOSIZE);
                //if (!img_decode.empty()) {
                //  imshow("detect_pic", img_decode);
                //}
    
                /* reflash display window in every 33ms */
                cvWaitKey(33);
    
                /* save to file -- this function is optional */
                //j++;
                //filename = "pic" + int2string(j) + ".jpg";
                //imwrite(filename, img_decode);
    
                /* send ack signal cok to tell that I'm ready to handler next frame */
                char cok[1] = { 0x55 };
                send(sockfd, cok, 1, 0);
            }
        }
    }
    
    void detectAndDisplay(cv::Mat frame)
    {
        std::vector<cv::Rect> faces;
        cv::Mat frame_gray;
        std::string filename = "";
        int k=0;
        cvtColor(frame, frame_gray, cv::COLOR_BGR2GRAY);
        equalizeHist(frame_gray, frame_gray);
    
        //-- Detect faces
        face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0 | cv::CASCADE_SCALE_IMAGE, cv::Size(20, 20));
        printf("the size of face %d",faces.size());
        for (size_t i = 0; i < faces.size(); i++)
        {
            cv::Point center(faces[i].x + faces[i].width / 2, faces[i].y + faces[i].height / 2);
            ellipse(frame, center, cv::Size(faces[i].width / 2, faces[i].height / 2), 0, 0, 360, cv::Scalar(255, 0, 255), 4, 8, 0);
    
            cv::Mat faceROI = frame_gray(faces[i]);
            std::vector<cv::Rect> eyes;
    
            //-- In each face, detect eyes
            eyes_cascade.detectMultiScale(faceROI, eyes, 1.1, 2, 0 | cv::CASCADE_SCALE_IMAGE, cv::Size(30, 30));
    
    
            for (size_t j = 0; j < eyes.size(); j++)
            {
                cv::Point eye_center(faces[i].x + eyes[j].x + eyes[j].width / 2, faces[i].y + eyes[j].y + eyes[j].height / 2);
                int radius = cvRound((eyes[j].width + eyes[j].height)*0.25);
                circle(frame, eye_center, radius, cv::Scalar(255, 0, 0), 4, 8, 0);
                k++;
                filename = "pic" + int2string(k) + ".jpg";
                cv::imwrite(filename, frame);
            }
        }
        /* save to file -- this function is optional */
    
        //-- Show what you got
        cv::namedWindow("detect_pic", cv::WINDOW_AUTOSIZE);
        if (!frame.empty()) {
            imshow("detect_pic", frame);
        }
    }
    

    相关文章

      网友评论

        本文标题:arm-VS2017 opencv远程人脸识别--APPLE的学

        本文链接:https://www.haomeiwen.com/subject/tjbweftx.html