笑脸识别从零开始研究:优美的程序(2)

作者: 球长爱折腾 | 来源:发表于2018-06-18 16:44 被阅读31次

    近几个月的笑脸识别研究过程中踩了很多坑,担心记录在本地容易不小心给删了,记录一份放在网上

    回顾学习之路,程序上从C++开始,到执着于Python,从实现简单的图像剪切到自己构建卷积神经网络,筚路蓝缕,我心依旧。

    以下为关于笑脸识别的个人自学记录,不具备科学的严谨性,仅作参考。


    【程序:批量尺寸修改】

    #用于修改尺寸
    from skimage import data_dir,io,transform,color
    import numpy as np
    
    def convert_gray(f,**args):
     rgb=io.imread(f)    #依次读取rgb图片
     dst=transform.resize(rgb,(256,256))  #将图片大小转换为256*256
     return dst
    
    ImagePath='/users/liuzuoli/facedata/asix/spider2/sp'
    # 保存路径
    str='/users/liuzuoli/facedata/asix/spider2/*.jpg'
    coll = io.ImageCollection(str,load_func=convert_gray)
    for i in range(len(coll)):
        io.imsave(ImagePath+'/'+np.str(i)+'.jpg',coll[i])  #循环保存图片
    

    【程序:截取人脸的函数】

    https://blog.csdn.net/u012162613/article/details/43523507

    **def** saveFaces(image_name):
     faces = detectFaces(image_name)
      **if** faces:
     #将人脸保存在save_dir目录下。
     #Image模块:Image.open获取图像句柄,crop剪切图像(剪切的区域就是detectFaces返回的坐标),save保存。
     save_dir = image_name.split('.')[0]+"_faces"
     os.mkdir(save_dir)
     count = 0
     **for** (x1,y1,x2,y2) **in** faces:
     file_name = os.path.join(save_dir,str(count)+".jpg")
     Image.open(image_name).crop((x1,y1,x2,y2)).save(file_name)
     count+=1
    

    【程序-人脸画出68个点】

    import dlib                     #人脸识别的库dlib
    import numpy as np              #数据处理的库numpy
    import cv2                      #图像处理的库OpenCv
    
    # dlib预测器
    detector = dlib.get_frontal_face_detector()
    #PREDICTOR_PATH =             "/Users/liuzuoli/PycharmProjects/68dlib/shape_predictor_68_face_landmarks.dat"
      predictor =dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')
    #这里出现了一个报错
    path="/users/liuzuoli/test/"
    
    # cv2读取图像
    img=cv2.imread(path+"pic3.JPG")
    
    # 取灰度
    img_gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
    
    # 人脸数rects
    rects = detector(img_gray, 0)
    
    for i in range(len(rects)):
        landmarks = np.matrix([[p.x, p.y] for p in predictor(img, rects[i]).parts()])
    
    for idx, point in enumerate(landmarks):
        # 68点的坐标
        pos = (point[0, 0], point[0, 1])
    
        # 利用cv2.circle给每个特征点画一个圈,共68个
        cv2.circle(img, pos, 6, color=(0, 255, 0))
    
        # 利用cv2.putText输出1-68,font后面的参数可以调整
        font = cv2.FONT_HERSHEY_SIMPLEX
        cv2.putText(img, str(idx+1), pos, font, 0.6, (0, 0, 255), 1, cv2.LINE_AA)
    
    cv2.namedWindow("img", 2)
    cv2.imshow("img", img)
    cv2.waitKey(0)
    

    【人脸检测-未完全实现2】

     #include <opencv/cv.hpp>
    #include <stdio.h>  
    #include <stdlib.h>
     #include <string.h>
     #include <assert.h>
     #include <math.h>
     #include <float.h>
     #include <limits.h>
     #include <time.h>
     #include <ctype.h>
    
     static CvMemStorage* storage = 0;   //创建一个内存存储器,来统一管理各种动态对象的内存
     static CvHaarClassifierCascade* cascade = 0;    //分类器
    
    void detect_and_draw( IplImage* image );    //检测人脸并标记
    
    const char* cascade_name =
     "/usr/local/Cellar/opencv/3.4.1_2/share/OpenCV/haarcascades/haarcascade_frontalface_alt_tree.xml";      //分类器名称
    
      int main( int argc, char** argv )
      {
    CvCapture* capture = 0;     //视频的结构体
    IplImage *frame, *frame_copy = 0;   //读取每一帧的结构体
    cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );    //载入分类器   
    if( !cascade )
    {
        fprintf( stderr, "ERROR: Could not load classifier cascade\n" );
        fprintf( stderr,
                "Usage: facedetect --cascade=\"<cascade_path>\" 
       [filename|camera_index]\n" );
        return -1;
    }
    storage = cvCreateMemStorage(0);
    cvNamedWindow( "result", 1 );   //1表示autosize
      
    //检测视频
    capture = cvCaptureFromCAM(-1); //调用摄像头
    
    if( capture )
    {
        for(;;)
        {
            if( !cvGrabFrame( capture ))    //从摄像头或者视频文件中抓取帧
                break;
            frame = cvRetrieveFrame( capture );     //取回由函数cvGrabFrame抓取的图像
            if( !frame )
                break;
            if( !frame_copy )   //复制图像
                frame_copy = cvCreateImage( cvSize(frame->width,frame->height),
                                           IPL_DEPTH_8U, frame->nChannels );
            
            if( frame->origin == IPL_ORIGIN_TL )    //图像顶点是否在顶-左
                cvCopy( frame, frame_copy, 0 );
            else
                cvFlip( frame, frame_copy, 0 );     //翻转
            
            IplImage *equ = cvCreateImage(cvGetSize(frame_copy),8, 1);
            IplImage *gray = cvCreateImage(cvGetSize(frame_copy), 8, 1);
            cvCvtColor(frame_copy, gray, CV_BGR2GRAY);      //转灰度图
            cvEqualizeHist(gray, equ);      //直方图均衡化
            
            //cvNamedWindow("yuantu");
            //cvNamedWindow("equ");
            //cvShowImage("yuantu",gray);
            //cvShowImage("equ",equ);
            
            detect_and_draw( frame_copy );      //人脸检测并标记
            
            if( cvWaitKey(1) >= 0 )
                break;
            //cvReleaseImage(&gray);
            //cvReleaseImage(&equ);
        }
        
        
        
        cvReleaseImage( &frame_copy );
        cvReleaseCapture( &capture );
    }
    
    cvWaitKey(-1); //检测图片的时候,等待显示
    cvDestroyWindow("result");
    
    return 0;
    }
    
    void detect_and_draw( IplImage* img )
    {
    static CvScalar colors[] =      //用8种颜色标记人脸
    {
        {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.2;     //缩放因子
    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 );       //转灰度图
    cvResize( gray, small_img, CV_INTER_LINEAR );   //调整大小
    cvEqualizeHist( small_img, small_img );     //使灰度图象直方图均衡化
    cvClearMemStorage( storage );       //重置
    
    if( cascade )
    {
        double t = (double)cvGetTickCount();    //返回从操作系统启动所经过的毫秒数
        CvSeq* faces = cvHaarDetectObjects( small_img, cascade, storage,
                                           1.1, 2, 0/*CV_HAAR_DO_CANNY_PRUNING*/,
                                           cvSize(30, 30) );
        
        printf("face's total is %d\n",faces->total);
        
        t = (double)cvGetTickCount() - t;
        printf( "detection time = %gms\n", t/((double)cvGetTickFrequency()*1000.) );    //cvGetTickFrequency()返回每秒的计时周期数
        for( i = 0; i < (faces ? faces->total : 0); i++ )
        {
            CvRect* r = (CvRect*)cvGetSeqElem( faces, i );
            CvRect tr(r->x,r->y,r->width,r->height);
            //用矩形框框出
            cvRectangle(img, cvPoint(r->x * scale, r->y * scale), cvPoint( (r->x + r->width) * scale, (r->y + r->height)  * scale), colors[i%8], 3, 8, 0);
            
            //用原型框出
            CvPoint center;
            int radius;
            center.x = cvRound((r->x + r->width*0.5)*scale);
            center.y = cvRound((r->y + r->height*0.5)*scale);
            radius = cvRound((r->width + r->height)*0.25*scale);
            cvCircle( img, center, radius, colors[i%8], 3, 8, 0 );
            
            //用ROI截取人脸区域
            cvSetImageROI(small_img, tr);   //用缩放后的图,设置源图像ROI
            CvSize size1 = cvSize(r->width, r->height);
            IplImage* roi_img = cvCreateImage(size1,small_img->depth,small_img->nChannels);
            cvCopy(small_img,roi_img);      //复制图像
            cvResetImageROI(small_img);     //源图像用完后,清空ROI
            cvNamedWindow("picture", CV_WINDOW_AUTOSIZE);
            cvShowImage("picture", roi_img);
            //cvReleaseImage( &roi_img );
            //cvDestroyWindow("picture");
        }
    }
    
    cvShowImage( "result", img );
    cvReleaseImage( &gray );
    cvReleaseImage( &small_img );
    }

    相关文章

      网友评论

        本文标题:笑脸识别从零开始研究:优美的程序(2)

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