<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          OpenCV實(shí)現(xiàn)人臉對(duì)齊

          共 2706字,需瀏覽 6分鐘

           ·

          2021-12-01 13:48

          點(diǎn)擊上方小白學(xué)視覺(jué)”,選擇加"星標(biāo)"或“置頂

          重磅干貨,第一時(shí)間送達(dá)

          一、人臉對(duì)齊介紹

          在人臉識(shí)別中有一個(gè)重要的預(yù)處理步驟-人臉對(duì)齊,該操作可以大幅度提高人臉識(shí)別的準(zhǔn)確率與穩(wěn)定性,但是早期的OpenCV版本不支持人臉Landmark檢測(cè),因此一般都是通過(guò)對(duì)人臉進(jìn)行分割,然后通過(guò)角點(diǎn)檢測(cè)來(lái)尋找眼睛兩個(gè)角點(diǎn),連線之后根據(jù)它們有水平線的角度,旋轉(zhuǎn)實(shí)現(xiàn)人臉對(duì)齊之后在提取人臉區(qū)域,OpenCV3.x版本開始支持獲取Landmark數(shù)據(jù),最常見的Landmark數(shù)據(jù)就是人臉的68個(gè)標(biāo)準(zhǔn)點(diǎn)位,圖示如下:

          實(shí)現(xiàn)對(duì)齊主要是基于眼睛的位置,對(duì)人臉傾斜進(jìn)行幾何變換,實(shí)現(xiàn)人臉對(duì)齊操作,人臉對(duì)齊對(duì)提高人臉識(shí)別率特別重要,常見的人臉識(shí)別系統(tǒng)都會(huì)包含人臉對(duì)齊操作,舉例如下:

          二、人臉對(duì)齊代碼實(shí)現(xiàn)

          基于OpenCV實(shí)現(xiàn)人臉對(duì)齊主要分為如下幾步

          1.人臉檢測(cè)器定義與Landmark檢測(cè)

          OpenCV中通過(guò)HAAR或者LBP特征實(shí)現(xiàn)了人臉檢測(cè),最新的OpenCV3.4基于殘差網(wǎng)絡(luò)也實(shí)現(xiàn)了人臉檢測(cè),相關(guān)的文章可以閱讀:?

          OpenCV基于殘差網(wǎng)絡(luò)實(shí)現(xiàn)人臉檢測(cè)

          詳解LBP特征與應(yīng)用(人臉識(shí)別)

          ?有了人臉之后,我們就可以通過(guò)加載預(yù)訓(xùn)練的Landmark檢測(cè)模型,實(shí)現(xiàn)Landmark檢測(cè),這里使用的模型是局部二值特征(LBF-Local Binary Feature)實(shí)現(xiàn)人臉68個(gè)點(diǎn)位的檢測(cè),這個(gè)也是2014年CVPR的一篇論文。最新的OpenCV3.4 Landmark檢測(cè)器支持自定義人臉檢測(cè)器設(shè)置,所以只要把我們上面的HAAR/LBP/殘差人臉檢測(cè)器設(shè)置過(guò)去就會(huì)自動(dòng)檢測(cè)人臉,然后發(fā)現(xiàn)Landmark數(shù)據(jù)。整個(gè)代碼實(shí)現(xiàn)如下:

          1. // 創(chuàng)建LBF landmark 檢測(cè)器

          2. Ptr<FacemarkLBF> facemark = FacemarkLBF::create(params);

          3. facemark->setFaceDetector((FN_FaceDetector)myDetector, &face_cascade);

          4. // 加載模型數(shù)據(jù)

          5. facemark->loadModel("D:/vcprojects/images/lbfmodel.yaml");

          6. cout << "Loaded model" << endl;

          7. // 開始檢測(cè)

          8. printf("start to detect landmarks...\n");

          9. vector<Rect> faces;

          10. facemark->getFaces(img, faces);

          11. vector< vector<Point2f> > shapes;

          12. if (facemark->fit(img, faces, shapes))

          13. {

          14. ? ?Point eye_left; // 36th

          15. ? ?Point eye_right; // 45th

          16. ? ?for (unsigned long i = 0; i

          17. ? ? ? ?eye_left = shapes[i][36];

          18. ? ? ? ?eye_right = shapes[i][45];

          19. ? ? ? ?line(img, eye_left, eye_right, Scalar(255, 0, 0), 2, 8, 0);

          20. ? ? ? ?face_alignment(img(faces[i]), eye_left, eye_right, faces[i]);

          21. ? ? ? ?// 繪制人臉矩形區(qū)域

          22. ? ? ? ?rectangle(img, faces[i], Scalar(255, 0, 0));

          23. ? ? ? ?// 繪制人臉68個(gè) landmark點(diǎn)位

          24. ? ? ? ?for (unsigned long k = 0; k

          25. ? ? ? ? ? ?cv::circle(img, shapes[i][k], 2, cv::Scalar(0, 0, 255), FILLED);

          26. ? ?}

          27. ? ?namedWindow("Detected_shape");

          28. ? ?imshow("Detected_shape", img);

          29. ? ?waitKey(0);

          30. }

          2.Landmark數(shù)據(jù)處理

          對(duì)Landmark數(shù)據(jù)提取獲得眼睛位置坐標(biāo),這里我們獲取的是36與45兩個(gè)點(diǎn)坐標(biāo)計(jì)算角度(參照第一張圖),然后通過(guò)幾何變換實(shí)現(xiàn)人臉對(duì)齊操作。代碼如下:

          1. int offsetx = roi.x;

          2. int offsety = roi.y;

          3. // 計(jì)算中心位置

          4. int cx = roi.width / 2;

          5. int cy = roi.height / 2;

          6. // 計(jì)算角度

          7. int dx = right.x - left.x;

          8. int dy = right.y - left.y;

          9. double degree = 180 * ((atan2(dy, dx)) / CV_PI);

          10. // 旋轉(zhuǎn)矩陣計(jì)算

          11. Mat M = getRotationMatrix2D(Point2f(cx, cy), degree, 1.0);

          12. Point2f center(cx, cy);

          13. Rect bbox = RotatedRect(center, face.size(), degree).boundingRect();

          14. M.at(0, 2) += (bbox.width / 2.0 - center.x);

          15. M.at(1, 2) += (bbox.height / 2.0 - center.y);

          16. // 對(duì)齊

          17. Mat result;

          18. warpAffine(face, result, M, bbox.size());

          19. imshow("face-alignment", result);

          3.運(yùn)行效果

          完整的程序代碼如下:

          1. #include

          2. #include

          3. #include

          4. #include

          5. using namespace cv;

          6. using namespace cv::face;

          7. using namespace std;

          8. const String ?lbpfilePath = "D:/opencv-3.4/opencv/build/etc/lbpcascades/lbpcascade_frontalface.xml";

          9. bool myDetector(InputArray image, OutputArray faces, CascadeClassifier *face_cascade);

          10. void face_alignment(Mat &face, Point left, Point right, Rect roi);

          11. int main(int argc, char** argv) {

          12. ? ?Mat img = imread("D:/vcprojects/images/gaoyy.png");

          13. ? ?namedWindow("input", CV_WINDOW_AUTOSIZE);

          14. ? ?imshow("input", img);

          15. ? ?CascadeClassifier face_cascade;

          16. ? ?face_cascade.load(lbpfilePath);

          17. ? ?FacemarkLBF::Params params;

          18. ? ?params.n_landmarks = 68; // 68個(gè)標(biāo)注點(diǎn)

          19. ? ?params.initShape_n = 10;

          20. ? ?params.stages_n = 5; // 算法的5個(gè)強(qiáng)化步驟

          21. ? ?params.tree_n = 6; // 模型中每個(gè)標(biāo)注點(diǎn)結(jié)構(gòu)樹 數(shù)目

          22. ? ?params.tree_depth = 5; // 決策樹深度

          23. ? ?// 創(chuàng)建LBF landmark 檢測(cè)器

          24. ? ?Ptr<FacemarkLBF> facemark = FacemarkLBF::create(params);

          25. ? ?facemark->setFaceDetector((FN_FaceDetector)myDetector, &face_cascade);

          26. ? ?// 加載模型數(shù)據(jù)

          27. ? ?facemark->loadModel("D:/vcprojects/images/lbfmodel.yaml");

          28. ? ?cout << "Loaded model" << endl;

          29. ? ?// 開始檢測(cè)

          30. ? ?printf("start to detect landmarks...\n");

          31. ? ?vector<Rect> faces;

          32. ? ?facemark->getFaces(img, faces);

          33. ? ?vector< vector<Point2f> > shapes;

          34. ? ?if (facemark->fit(img, faces, shapes))

          35. ? ?{

          36. ? ? ? ?Point eye_left; // 36th

          37. ? ? ? ?Point eye_right; // 45th

          38. ? ? ? ?for (unsigned long i = 0; i

          39. ? ? ? ? ? ?eye_left = shapes[i][36];

          40. ? ? ? ? ? ?eye_right = shapes[i][45];

          41. ? ? ? ? ? ?line(img, eye_left, eye_right, Scalar(255, 0, 0), 2, 8, 0);

          42. ? ? ? ? ? ?face_alignment(img(faces[i]), eye_left, eye_right, faces[i]);

          43. ? ? ? ? ? ?// 繪制人臉矩形區(qū)域

          44. ? ? ? ? ? ?rectangle(img, faces[i], Scalar(255, 0, 0));

          45. ? ? ? ? ? ?// 繪制人臉68個(gè) landmark點(diǎn)位

          46. ? ? ? ? ? ?for (unsigned long k = 0; k

          47. ? ? ? ? ? ? ? ?cv::circle(img, shapes[i][k], 2, cv::Scalar(0, 0, 255), FILLED);

          48. ? ? ? ?}

          49. ? ? ? ?namedWindow("Detected_shape");

          50. ? ? ? ?imshow("Detected_shape", img);

          51. ? ? ? ?waitKey(0);

          52. ? ?}

          53. ? ?return 0;

          54. }

          55. bool myDetector(InputArray image, OutputArray faces, CascadeClassifier *face_cascade)

          56. {

          57. ? ?Mat gray;

          58. ? ?if (image.channels() > 1)

          59. ? ? ? ?cvtColor(image, gray, COLOR_BGR2GRAY);

          60. ? ?else

          61. ? ? ? ?gray = image.getMat().clone();

          62. ? ?equalizeHist(gray, gray);

          63. ? ?std::vector<Rect> faces_;

          64. ? ?face_cascade->detectMultiScale(gray, faces_, 1.1, 1, CASCADE_SCALE_IMAGE, Size(50, 50));

          65. ? ?Mat(faces_).copyTo(faces);

          66. ? ?return true;

          67. }

          68. void face_alignment(Mat &face, Point left, Point right, Rect roi) {

          69. ? ?int offsetx = roi.x;

          70. ? ?int offsety = roi.y;

          71. ? ?// 計(jì)算中心位置

          72. ? ?int cx = roi.width / 2;

          73. ? ?int cy = roi.height / 2;

          74. ? ?// 計(jì)算角度

          75. ? ?int dx = right.x - left.x;

          76. ? ?int dy = right.y - left.y;

          77. ? ?double degree = 180 * ((atan2(dy, dx)) / CV_PI);

          78. ? ?// 旋轉(zhuǎn)矩陣計(jì)算

          79. ? ?Mat M = getRotationMatrix2D(Point2f(cx, cy), degree, 1.0);

          80. ? ?Point2f center(cx, cy);

          81. ? ?Rect bbox = RotatedRect(center, face.size(), degree).boundingRect();

          82. ? ?M.at(0, 2) += (bbox.width / 2.0 - center.x);

          83. ? ?M.at(1, 2) += (bbox.height / 2.0 - center.y);

          84. ? ?// 對(duì)齊

          85. ? ?Mat result;

          86. ? ?warpAffine(face, result, M, bbox.size());

          87. ? ?imshow("face-alignment", result);

          88. }



          下載1:OpenCV-Contrib擴(kuò)展模塊中文版教程
          在「小白學(xué)視覺(jué)」公眾號(hào)后臺(tái)回復(fù):擴(kuò)展模塊中文教程即可下載全網(wǎng)第一份OpenCV擴(kuò)展模塊教程中文版,涵蓋擴(kuò)展模塊安裝、SFM算法、立體視覺(jué)、目標(biāo)跟蹤、生物視覺(jué)、超分辨率處理等二十多章內(nèi)容。

          下載2:Python視覺(jué)實(shí)戰(zhàn)項(xiàng)目52講
          小白學(xué)視覺(jué)公眾號(hào)后臺(tái)回復(fù):Python視覺(jué)實(shí)戰(zhàn)項(xiàng)目即可下載包括圖像分割、口罩檢測(cè)、車道線檢測(cè)、車輛計(jì)數(shù)、添加眼線、車牌識(shí)別、字符識(shí)別、情緒檢測(cè)、文本內(nèi)容提取、面部識(shí)別等31個(gè)視覺(jué)實(shí)戰(zhàn)項(xiàng)目,助力快速學(xué)校計(jì)算機(jī)視覺(jué)。

          下載3:OpenCV實(shí)戰(zhàn)項(xiàng)目20講
          小白學(xué)視覺(jué)公眾號(hào)后臺(tái)回復(fù):OpenCV實(shí)戰(zhàn)項(xiàng)目20講即可下載含有20個(gè)基于OpenCV實(shí)現(xiàn)20個(gè)實(shí)戰(zhàn)項(xiàng)目,實(shí)現(xiàn)OpenCV學(xué)習(xí)進(jìn)階。

          交流群


          歡迎加入公眾號(hào)讀者群一起和同行交流,目前有SLAM、三維視覺(jué)、傳感器自動(dòng)駕駛、計(jì)算攝影、檢測(cè)、分割、識(shí)別、醫(yī)學(xué)影像、GAN算法競(jìng)賽等微信群(以后會(huì)逐漸細(xì)分),請(qǐng)掃描下面微信號(hào)加群,備注:”昵稱+學(xué)校/公司+研究方向“,例如:”張三?+?上海交大?+?視覺(jué)SLAM“。請(qǐng)按照格式備注,否則不予通過(guò)。添加成功后會(huì)根據(jù)研究方向邀請(qǐng)進(jìn)入相關(guān)微信群。請(qǐng)勿在群內(nèi)發(fā)送廣告,否則會(huì)請(qǐng)出群,謝謝理解~


          瀏覽 65
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲男人天堂2025 | 操逼内射导航 | 无一区二区三区 | 色五月欧美 | 91爱搞搞 |