近几个月的笑脸识别研究过程中踩了很多坑,担心记录在本地容易不小心给删了,记录一份放在网上
回顾学习之路,程序上从C++开始,到执着于Python,从实现简单的图像剪切到自己构建卷积神经网络,筚路蓝缕,我心依旧。
以下为关于笑脸识别的个人自学记录,不具备科学的严谨性,仅作参考。
【程序:批量尺寸修改】
#用于修改尺寸from skimage import data_dir,io,transform,colorimport numpy as npdef 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 #人脸识别的库dlibimport numpy as np #数据处理的库numpyimport 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)# 人脸数rectsrects = 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 ); }
作者:刘必王A6
链接:https://www.jianshu.com/p/9430dcaa592b