代码来源于<Mastering OpenCV with Practical Computer Vision Projects >

她的另外几篇文章,也翻译的很好

http://blog.csdn.net/raby_gyl/article/details/12611861

http://blog.csdn.net/raby_gyl/article/details/12623539

http://blog.csdn.net/raby_gyl/article/details/12338371

我感觉下面的程序——对人眼定位,人脸矫正,人脸尺寸化,对于初学人脸识别,做人脸的预处理非常有帮助~

程序的思路是:首先通过人脸检测级联器检测到人脸区域,对于人脸区域我们采用经验理论(即不同的人眼检测器在不同的人脸搜索区域具有最优性),也即人眼在人脸区域中的位置,得到人眼的大体位置,采用opencv的人眼级联检测器检测人眼,获取每一个人眼的中心位置,两个人眼的连线与水平位置的夹角来确定人脸旋转、矫正的角度。同时通过我们想要得到的目标图像来计算得到仿射矩阵的scale尺度因子,即图像缩放的比例,以及通过平移来计算得到的距离,进而实现定位人眼在目的图像的位置。

代码如下:

[cpp] view plain copy
  1. #include "stdafx.h"
  2. #include "opencv2/imgproc/imgproc.hpp"
  3. #include "opencv2/highgui/highgui.hpp"
  4. #include "opencv2/opencv.hpp"
  5. #include<iostream>
  6. #include<vector>
  7. using namespace std;
  8. using namespace cv;
  9. const double DESIRED_LEFT_EYE_X = 0.16;     // 控制处理后人脸的多少部分是可见的
  10. const double DESIRED_LEFT_EYE_Y = 0.14;
  11. const double FACE_ELLIPSE_CY = 0.40;
  12. const double FACE_ELLIPSE_W = 0.50;         // 应当至少为0.5
  13. const double FACE_ELLIPSE_H = 0.80;         //控制人脸掩码的高度
  14. /*--------------------------------------目标检测-------------------------------------*/
  15. void detectObjectsCustom(const Mat &img, CascadeClassifier &cascade, vector<Rect> &objects, int scaledWidth, int flags, Size minFeatureSize, float searchScaleFactor, int minNeighbors);
  16. void detectLargestObject(const Mat &img, CascadeClassifier &cascade, Rect &largestObject, int scaledWidth);
  17. void detectManyObjects(const Mat &img, CascadeClassifier &cascade, vector<Rect> &objects, int scaledWidth);
  18. /*------------------------------------- end------------------------------------------*/
  19. void detectBothEyes(const Mat &face, CascadeClassifier &eyeCascade1, CascadeClassifier &eyeCascade2, Point &leftEye, Point &rightEye, Rect *searchedLeftEye, Rect *searchedRightEye);
  20. Mat getPreprocessedFace(Mat &srcImg, int desiredFaceWidth, CascadeClassifier &faceCascade, CascadeClassifier &eyeCascade1, CascadeClassifier &eyeCascade2, bool doLeftAndRightSeparately, Rect *storeFaceRect, Point *storeLeftEye, Point *storeRightEye, Rect *searchedLeftEye, Rect *searchedRightEye);
  21. int main(int argc,char **argv)
  22. {
  23. CascadeClassifier faceDetector;
  24. CascadeClassifier  eyeDetector1;
  25. CascadeClassifier  eyeDetector2;//未初始化不用
  26. try{
  27. //faceDetector.load("E:\\OpenCV-2.3.0\\data\\haarcascades\\haarcascade_frontalface_alt.xml");
  28. faceDetector.load("E:\\OpenCV-2.3.0\\data\\lbpcascades\\lbpcascade_frontalface.xml");
  29. eyeDetector1.load("E:\\OpenCV-2.3.0\\data\\haarcascades\\haarcascade_eye.xml");
  30. eyeDetector2.load("E:\\OpenCV-2.3.0\\data\\haarcascades\\haarcascade_eye_tree_eyeglasses.xml");
  31. }catch (cv::Exception e){}
  32. if(faceDetector.empty())
  33. {
  34. cerr<<"error:couldn't load face detector (";
  35. cerr<<"lbpcascade_frontalface.xml)!"<<endl;
  36. exit(1);
  37. }
  38. Mat img=imread(argv[1],1);
  39. Rect largestObject;
  40. const int scaledWidth=320;
  41. detectLargestObject(img,faceDetector,largestObject,scaledWidth);
  42. Mat img_rect(img,largestObject);
  43. Point leftEye,rightEye;
  44. Rect searchedLeftEye,searchedRightEye;
  45. detectBothEyes(img_rect,eyeDetector1,eyeDetector2,leftEye,rightEye,&searchedLeftEye,&searchedRightEye);
  46. //仿射变换
  47. Point2f eyesCenter;
  48. eyesCenter.x=(leftEye.x+rightEye.x)*0.5f;
  49. eyesCenter.y=(leftEye.y+rightEye.y)*0.5f;
  50. cout<<"左眼中心坐标 "<<leftEye.x<<" and "<<leftEye.y<<endl;
  51. cout<<"右眼中心坐标 "<<rightEye.x<<" and "<<rightEye.y<<endl;
  52. //获取两个人眼的角度
  53. double dy=(rightEye.y-leftEye.y);
  54. double dx=(rightEye.x-leftEye.x);
  55. double len=sqrt(dx*dx+dy*dy);
  56. cout<<"dx is "<<dx<<endl;
  57. cout<<"dy is "<<dy<<endl;
  58. cout<<"len is "<<len<<endl;
  59. double angle=atan2(dy,dx)*180.0/CV_PI;
  60. const double DESIRED_RIGHT_EYE_X=1.0f-0.16;
  61. //得到我们想要的尺度化大小
  62. const int DESIRED_FACE_WIDTH=70;
  63. const int DESIRED_FACE_HEIGHT=70;
  64. double desiredLen=(DESIRED_RIGHT_EYE_X-0.16);
  65. cout<<"desiredlen is "<<desiredLen<<endl;
  66. double scale=desiredLen*DESIRED_FACE_WIDTH/len;
  67. cout<<"the scale is "<<scale<<endl;
  68. Mat rot_mat = getRotationMatrix2D(eyesCenter, angle, scale);
  69. double ex=DESIRED_FACE_WIDTH * 0.5f - eyesCenter.x;
  70. double ey = DESIRED_FACE_HEIGHT * DESIRED_LEFT_EYE_Y-eyesCenter.y;
  71. rot_mat.at<double>(0, 2) += ex;
  72. rot_mat.at<double>(1, 2) += ey;
  73. Mat warped = Mat(DESIRED_FACE_HEIGHT, DESIRED_FACE_WIDTH,CV_8U, Scalar(128));
  74. warpAffine(img_rect, warped, rot_mat, warped.size());
  75. imshow("warped",warped);
  76. rectangle(img,Point(largestObject.x,largestObject.y),Point(largestObject.x+largestObject.width,largestObject.y+largestObject.height),Scalar(0,0,255),2,8);
  77. rectangle(img_rect,Point(searchedLeftEye.x,searchedLeftEye.y),Point(searchedLeftEye.x+searchedLeftEye.width,searchedLeftEye.y+searchedLeftEye.height),Scalar(0,255,0),2,8);
  78. rectangle(img_rect,Point(searchedRightEye.x,searchedRightEye.y),Point(searchedRightEye.x+searchedRightEye.width,searchedRightEye.y+searchedRightEye.height),Scalar(0,255,0),2,8);
  79. //getPreprocessedFace
  80. imshow("img_rect",img_rect);
  81. imwrite("img_rect.jpg",img_rect);
  82. imshow("img",img);
  83. waitKey();
  84. }
  85. /*
  86. 1、采用给出的参数在图像中寻找目标,例如人脸
  87. 2、可以使用Haar级联器或者LBP级联器做人脸检测,或者甚至眼睛,鼻子,汽车检测
  88. 3、为了使检测更快,输入图像暂时被缩小到'scaledWidth',因为寻找人脸200的尺度已经足够了。
  89. */
  90. void detectObjectsCustom(const Mat &img, CascadeClassifier &cascade, vector<Rect> &objects, int scaledWidth, int flags, Size minFeatureSize, float searchScaleFactor, int minNeighbors)
  91. {
  92. //如果输入的图像不是灰度图像,那么将BRG或者BGRA彩色图像转换为灰度图像
  93. Mat gray;
  94. if (img.channels() == 3) {
  95. cvtColor(img, gray, CV_BGR2GRAY);
  96. }
  97. else if (img.channels() == 4) {
  98. cvtColor(img, gray, CV_BGRA2GRAY);
  99. }
  100. else {
  101. // 直接使用输入图像,既然它已经是灰度图像
  102. gray = img;
  103. }
  104. // 可能的缩小图像,是检索更快
  105. Mat inputImg;
  106. float scale = img.cols / (float)scaledWidth;
  107. if (img.cols > scaledWidth) {
  108. // 缩小图像并保持同样的宽高比
  109. int scaledHeight = cvRound(img.rows / scale);
  110. resize(gray, inputImg, Size(scaledWidth, scaledHeight));
  111. }
  112. else {
  113. // 直接使用输入图像,既然它已经小了
  114. inputImg = gray;
  115. }
  116. //标准化亮度和对比度来改善暗的图像
  117. Mat equalizedImg;
  118. equalizeHist(inputImg, equalizedImg);
  119. // 在小的灰色图像中检索目标
  120. cascade.detectMultiScale(equalizedImg, objects, searchScaleFactor, minNeighbors, flags, minFeatureSize);
  121. // 如果图像在检测之前暂时的被缩小了,则放大结果图像
  122. if (img.cols > scaledWidth) {
  123. for (int i = 0; i < (int)objects.size(); i++ ) {
  124. objects[i].x = cvRound(objects[i].x * scale);
  125. objects[i].y = cvRound(objects[i].y * scale);
  126. objects[i].width = cvRound(objects[i].width * scale);
  127. objects[i].height = cvRound(objects[i].height * scale);
  128. }
  129. }
  130. //确保目标全部在图像内部,以防它在边界上
  131. for (int i = 0; i < (int)objects.size(); i++ ) {
  132. if (objects[i].x < 0)
  133. objects[i].x = 0;
  134. if (objects[i].y < 0)
  135. objects[i].y = 0;
  136. if (objects[i].x + objects[i].width > img.cols)
  137. objects[i].x = img.cols - objects[i].width;
  138. if (objects[i].y + objects[i].height > img.rows)
  139. objects[i].y = img.rows - objects[i].height;
  140. }
  141. // 返回检测到的人脸矩形,存储在objects中
  142. }
  143. /*
  144. 1、仅寻找图像中的单个目标,例如最大的人脸,存储结果到largestObject
  145. 2、可以使用Haar级联器或者LBP级联器做人脸检测,或者甚至眼睛,鼻子,汽车检测
  146. 3、为了使检测更快,输入图像暂时被缩小到'scaledWidth',因为寻找人脸200的尺度已经足够了。
  147. 4、注释:detectLargestObject()要比 detectManyObjects()快。
  148. */
  149. void detectLargestObject(const Mat &img, CascadeClassifier &cascade, Rect &largestObject, int scaledWidth)
  150. {
  151. //仅寻找一个目标 (图像中最大的).
  152. int flags = CV_HAAR_FIND_BIGGEST_OBJECT;// | CASCADE_DO_ROUGH_SEARCH;
  153. // 最小的目标大小.
  154. Size minFeatureSize = Size(20, 20);
  155. // 寻找细节,尺度因子,必须比1大
  156. float searchScaleFactor = 1.1f;
  157. // 多少检测结果应当被滤掉,这依赖于你的检测系统是多坏,如果minNeighbors=2 ,大量的good or bad 被检测到。如果
  158. // minNeighbors=6,意味着只good检测结果,但是一些将漏掉。即可靠性 VS  检测人脸数量
  159. int minNeighbors = 4;
  160. // 执行目标或者人脸检测,仅寻找一个目标(图像中最大的)
  161. vector<Rect> objects;
  162. detectObjectsCustom(img, cascade, objects, scaledWidth, flags, minFeatureSize, searchScaleFactor, minNeighbors);
  163. if (objects.size() > 0) {
  164. // 返回仅检测到的目标
  165. largestObject = (Rect)objects.at(0);
  166. }
  167. else {
  168. // 返回一个无效的矩阵
  169. largestObject = Rect(-1,-1,-1,-1);
  170. }
  171. }
  172. void detectManyObjects(const Mat &img, CascadeClassifier &cascade, vector<Rect> &objects, int scaledWidth)
  173. {
  174. // 寻找图像中的许多目标
  175. int flags = CV_HAAR_SCALE_IMAGE;
  176. // 最小的目标大小.
  177. Size minFeatureSize = Size(20, 20);
  178. //  寻找细节,尺度因子,必须比1大
  179. float searchScaleFactor = 1.1f;
  180. // 多少检测结果应当被滤掉,这依赖于你的检测系统是多坏,如果minNeighbors=2 ,大量的good or bad 被检测到。如果
  181. // minNeighbors=6,意味着只good检测结果,但是一些将漏掉。即可靠性 VS  检测人脸数量
  182. int minNeighbors = 4;
  183. // 执行目标或者人脸检测,寻找图像中的许多目标
  184. detectObjectsCustom(img, cascade, objects, scaledWidth, flags, minFeatureSize, searchScaleFactor, minNeighbors);
  185. }
  186. /*
  187. 1、在给出的人脸图像中寻找双眼,返回左眼和右眼的中心,如果当找不到人眼时,或者设置为Point(-1,-1)
  188. 2、注意如果你想用两个不同的级联器寻找人眼,你可以传递第二个人眼检测器,例如如果你使用的一个常规人眼检测器和带眼镜的人眼检测器一样好,或者左眼检测器和右眼检测器一样好,
  189. 或者如果你不想第二个检测器,仅传一个未初始化级联检测器。
  190. 3、如果需要的话,也可以存储检测到的左眼和右眼的区域
  191. */
  192. void detectBothEyes(const Mat &face, CascadeClassifier &eyeCascade1, CascadeClassifier &eyeCascade2, Point &leftEye, Point &rightEye, Rect *searchedLeftEye, Rect *searchedRightEye)
  193. {
  194. //跳过人脸边界,因为它们经常是头发和耳朵,这不是我们关心的
  195. /*
  196. // For "2splits.xml": Finds both eyes in roughly 60% of detected faces, also detects closed eyes.
  197. const float EYE_SX = 0.12f;
  198. const float EYE_SY = 0.17f;
  199. const float EYE_SW = 0.37f;
  200. const float EYE_SH = 0.36f;
  201. */
  202. /*
  203. // For mcs.xml: Finds both eyes in roughly 80% of detected faces, also detects closed eyes.
  204. const float EYE_SX = 0.10f;
  205. const float EYE_SY = 0.19f;
  206. const float EYE_SW = 0.40f;
  207. const float EYE_SH = 0.36f;
  208. */
  209. // For default eye.xml or eyeglasses.xml: Finds both eyes in roughly 40% of detected faces, but does not detect closed eyes.
  210. //haarcascade_eye.xml检测器在由下面确定的人脸区域内搜索最优。
  211. const float EYE_SX = 0.16f;//x
  212. const float EYE_SY = 0.26f;//y
  213. const float EYE_SW = 0.30f;//width
  214. const float EYE_SH = 0.28f;//height
  215. int leftX = cvRound(face.cols * EYE_SX);
  216. int topY = cvRound(face.rows * EYE_SY);
  217. int widthX = cvRound(face.cols * EYE_SW);
  218. int heightY = cvRound(face.rows * EYE_SH);
  219. int rightX = cvRound(face.cols * (1.0-EYE_SX-EYE_SW) );  // 右眼的开始区域
  220. Mat topLeftOfFace = face(Rect(leftX, topY, widthX, heightY));
  221. Mat topRightOfFace = face(Rect(rightX, topY, widthX, heightY));
  222. Rect leftEyeRect, rightEyeRect;
  223. // 如果需要的话,然后搜索到的窗口给调用者
  224. if (searchedLeftEye)
  225. *searchedLeftEye = Rect(leftX, topY, widthX, heightY);
  226. if (searchedRightEye)
  227. *searchedRightEye = Rect(rightX, topY, widthX, heightY);
  228. // 寻找左区域,然后右区域使用第一个人眼检测器
  229. detectLargestObject(topLeftOfFace, eyeCascade1, leftEyeRect, topLeftOfFace.cols);
  230. detectLargestObject(topRightOfFace, eyeCascade1, rightEyeRect, topRightOfFace.cols);
  231. // 如果人眼没有检测到,尝试另外一个不同的级联检测器
  232. if (leftEyeRect.width <= 0 && !eyeCascade2.empty()) {
  233. detectLargestObject(topLeftOfFace, eyeCascade2, leftEyeRect, topLeftOfFace.cols);
  234. //if (leftEyeRect.width > 0)
  235. //    cout << "2nd eye detector LEFT SUCCESS" << endl;
  236. //else
  237. //    cout << "2nd eye detector LEFT failed" << endl;
  238. }
  239. //else
  240. //    cout << "1st eye detector LEFT SUCCESS" << endl;
  241. // 如果人眼没有检测到,尝试另外一个不同的级联检测器
  242. if (rightEyeRect.width <= 0 && !eyeCascade2.empty()) {
  243. detectLargestObject(topRightOfFace, eyeCascade2, rightEyeRect, topRightOfFace.cols);
  244. //if (rightEyeRect.width > 0)
  245. //    cout << "2nd eye detector RIGHT SUCCESS" << endl;
  246. //else
  247. //    cout << "2nd eye detector RIGHT failed" << endl;
  248. }
  249. //else
  250. //    cout << "1st eye detector RIGHT SUCCESS" << endl;
  251. if (leftEyeRect.width > 0) {   // 检查眼是否被检测到
  252. leftEyeRect.x += leftX;    //矫正左眼矩形,因为人脸边界被去除掉了
  253. leftEyeRect.y += topY;
  254. leftEye = Point(leftEyeRect.x + leftEyeRect.width/2, leftEyeRect.y + leftEyeRect.height/2);
  255. }
  256. else {
  257. leftEye = Point(-1, -1);    // 返回一个无效的点
  258. }
  259. if (rightEyeRect.width > 0) { //检查眼是否被检测到
  260. rightEyeRect.x += rightX; // 矫正左眼矩形,因为它从图像的右边界开始
  261. rightEyeRect.y += topY;  // 矫正右眼矩形,因为人脸边界被去除掉了
  262. rightEye = Point(rightEyeRect.x + rightEyeRect.width/2, rightEyeRect.y + rightEyeRect.height/2);
  263. }
  264. else {
  265. rightEye = Point(-1, -1);    // 返回一个无效的点
  266. }
  267. }

运行效果图:

1、

2、检测到的人脸矩形区域:

3、人脸矫正和尺寸归一化到70*70后的结果图:

我要说的:

1、代码是截取的原文中的一小部分,搭配好环境可以直接运行,人家的程序可能适用于网络摄像头拍的正对着人脸的,一个人脸图像。而不是针对一般的有一群人,人脸小一些的,或者人脸不是正面的图像,你可以那lena图像试一下,它只能检测到一只左眼(真实的右眼),而另外一只检测不到,那么就会返回一个无效的点Point(-1,-1)作为眼睛的中心,那么更别提后面的旋转了,即后面的旋转肯定也是不对的。在你用本程序测试的时候,一定要选择一个合理的图像。

2、我讲一下关于旋转平移的代码的理解:

首先我们看下图:

这是我们的目的图像,满足的要求为:

(1)大小为70*70;

(2)两个眼睛直接的距离为(1-0.16)*70;(图中的(0.16,0.14)是左眼中心在图像中比例位置,由于人眼时对称的,则右眼所在比例位置为(0.68,0.14),要想获得真实的位置乘以70即可,对于本例是这样的)

(3)两个人眼连线的中心位置;

有了上述三个条件,我们就可以固定一双人眼在一个大小(这里是70*70)固定的图像中的具体位置。下面的代码就是要实现这个功能:

[cpp] view plain copy
  1. Point2f eyesCenter;//原图像两个眼睛连续的中心点(参考下图参)
  2. eyesCenter.x=(leftEye.x+rightEye.x)*0.5f;
  3. eyesCenter.y=(leftEye.y+rightEye.y)*0.5f;
  4. double dy=(rightEye.y-leftEye.y);
  5. double dx=(rightEye.x-leftEye.x);
  6. double len=sqrt(dx*dx+dy*dy);//原图像两个眼睛之间的距离
  7. double angle=atan2(dy,dx)*180.0/CV_PI;//计算出来的旋转角度
[cpp] view plain copy
  1. //目标图像的位置
  2. const double DESIRED_RIGHT_EYE_X=1.0f-0.16;
  3. const int DESIRED_FACE_WIDTH=70;
  4. const int DESIRED_FACE_HEIGHT=70;
  5. double desiredLen=(DESIRED_RIGHT_EYE_X-0.16);//目标图像两个眼睛直接的比例距离,乘以WIDTH=70即得到距离
  6. double scale=desiredLen*DESIRED_FACE_WIDTH/len;//通过目的图像两个眼睛距离除以原图像两个眼睛的距离,得到旋转矩阵的尺度因子.
[cpp] view plain copy
  1. Mat rot_mat = getRotationMatrix2D(eyesCenter, angle, scale);//绕原图像两眼连线中心点旋转,旋转角度为angle,缩放尺度为scale
[cpp] view plain copy
  1. //难点部分理解,实现中心点的平移,来控制两个眼睛在图像中的位置:
  2. double ex=DESIRED_FACE_WIDTH * 0.5f - eyesCenter.x;//获取x方向的平移因子,即目标两眼连线中心点的x坐标—原图像两眼连线中心点x坐标
  3. double ey = DESIRED_FACE_HEIGHT * DESIRED_LEFT_EYE_Y-eyesCenter.y;//获取x方向的平移因子,即目标两眼连线中心点的x坐标—原图像两眼连线中心点x坐标
  4. rot_mat.at<double>(0, 2) += ex;//将上述结果加到旋转矩阵中控制x平移的位置
  5. rot_mat.at<double>(1, 2) += ey;//将上述结果加到旋转矩阵中控制y平移的位置
  6. Mat warped = Mat(DESIRED_FACE_HEIGHT, DESIRED_FACE_WIDTH,CV_8U, Scalar(128));
  7. warpAffine(img_rect, warped, rot_mat, warped.size());

我们可以假想一下,上边的代码如果没有最后一个中心点的平移,之前的旋转矩阵只能控制图像的缩放和两个眼睛直接的相对位置,但是控制不了两个眼睛在图像中的位置,即固定两个眼在图像中的位置。

补充知识(仿射变换):

上图中a0,b0为控制平移的因子,如果我们领a2=1,a1=0,b2=0,b1=1,即变为u=x+a0,v=y+b0;
参考图:

人脸识别之人眼定位、人脸矫正、人脸尺寸标准化---Mastering OpenCV with Practical Computer Vision Projects相关推荐

  1. 整理《Mastering OpenCV with Practical Computer Vision Projects》中第8章用Eigenfaces或Fisherfaces进行人脸识别操作流程

    These generally involve four main steps:(1).Face detection:(2).Face preprocessing:(3).Collect and le ...

  2. 人脸识别系统包括图像摄取、人脸定位、图像预处理、以及人脸识别

    https://www.toutiao.com/a6651763844760732164/ 2019-01-29 12:00:57 识别算法 一般来说,人脸识别系统包括图像摄取.人脸定位.图像预处理. ...

  3. 人脸识别资源推荐:20款人脸检测/识别的API、库和软件

    人脸识别资源推荐:20款人脸检测/识别的API.库和软件 码上一课导读 人脸识别技术是一种依据人的面部特征,自动进行身份鉴别的一种技术,它综合运用了数字图像.视频处理.模式识别等多种技术.通过人脸特征 ...

  4. 防沉迷人脸识别可以扫照片吗_人脸识别的智能门锁到底安不安全?用照片可以打开是真的吗?...

    随着人脸识别技术不断成熟发展,市场需求加速释放,应用场景不断被挖掘,多方的推动使得人脸识别锁备受青睐.人脸识别精度的提高,使得人脸识别智能锁具有高便捷性,强实用性等特点.因此,近年来这种门锁成为了越来 ...

  5. 人脸识别有趣应用3——抠出人脸并给人脸涂上戏剧脸谱

    目录 前言 原理 Python源代码 前言 人脸最基础的操作之一,是要将人脸识别出来后,把真个人脸给抠出来,这样就可以对人脸进行各种操作,比如:美白.去痘等等,本篇是基于人脸识别库,结合阈值分割图片的 ...

  6. AI人工智能相面项目总结二,AI人脸识别接口的选择和根据人脸数据的测算

    做AI相面,自然AI人脸识别是基础.目前AI人脸识别已经很成熟,相应提供接口的公司也很多,我们主要看了三家的接口,腾讯.百度和face++. 腾讯人脸识别接口 申请地址:https://cloud.t ...

  7. 人脸识别门禁_门禁人脸识别系统铜陵县门禁人脸识别系统哪家好

    门禁人脸识别系统铜陵县门禁人脸识别系统哪家好 工地 1.建筑工地使用人脸识别门禁考勤机解决问题:工人刷脸出入,刷脸考勤,杜绝虚假考勤,提高考勤效率,工人工种分组,实名制管理. 2.人脸识别测温一体机用 ...

  8. 树莓派人脸识别门禁opencv4.2_树莓派人脸识别实际应用:人脸识别门禁

    2020-3-16 之前舵机开门关门逻辑有点混乱,不太合乎常理,现对树莓派人脸识别代码进行修改,以及对Arduino控制代码有所调整: 在上一篇文章中 小雨:树莓派调用百度人脸识别API实现人脸识别​ ...

  9. python人脸识别从入门到工程pdf_Python人脸识别:从入门到工程实践

    前言 第1章 人脸识别入门1 1.1 人脸识别概况1 1.1.1 何为人脸识别1 1.1.2 人脸识别的应用2 1.1.3 人脸识别的目标4 1.1.4 人脸识别的一般方法5 1.2 人脸识别发展状况 ...

最新文章

  1. HA-heartbeat高可用双击热备安装配置详解
  2. BOM事件对象even
  3. PHP之星际设计模式下(转自lightsaber)
  4. MyBatis总结七:动态sql和sql片段
  5. 26-[Boostrap]-全局css样式,组件,控件
  6. 统计年鉴29份3种格式混合
  7. android3.0新功能,PCWorld:Android 3.0最受期待的五大新功能
  8. 自然语言在公路交通各建设阶段运用
  9. 百度推广怎么做排名靠前网站链接
  10. (附源码)springboot社区疫情防控管理系统 毕业设计 164621
  11. 如何创建一个javaWeb项目
  12. mysql直方图_MySQL · 特性分析 · 直方图的实现与分析
  13. 小程序登录 之 支付宝授权
  14. Android各国语言Values文件夹命名规则
  15. JESD204B IP核的配置与使用
  16. 【Android】触发按钮的三种方式
  17. 计算机设置用户权限的风险,电脑的用户权限设置在哪里
  18. 上千个常用软件,你对国产操作系统UOS有何期望?
  19. Lenovo 万全T260 重装windows server 2003
  20. TIM_OutputState,TIM_OutputNState的意思

热门文章

  1. ACM数论专题3——素数(质数)
  2. 小米4C刷openwrt
  3. 学习笔记-----Material design
  4. Linux基于bash命令实验报告,Linux操作系统实验报告1
  5. [brew|Mac]如何将软件发布到Homebrew
  6. 微信人工客服转服务电话号码呢?
  7. 知道创宇前端一面面经
  8. 这事妥了,百度云三步走战略全面支持IPv6
  9. java角谷_JAVA 角谷定理 递归
  10. qt样式表设置边框_QT样式表