1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        OpenCV實現(xiàn)人臉對齊

        共 2706字,需瀏覽 6分鐘

         ·

        2021-12-01 13:48

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

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

        一、人臉對齊介紹

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

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

        二、人臉對齊代碼實現(xiàn)

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

        1.人臉檢測器定義與Landmark檢測

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

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

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

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

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

        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. // 開始檢測

        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個 landmark點位

        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ù)處理

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

        1. int offsetx = roi.x;

        2. int offsety = roi.y;

        3. // 計算中心位置

        4. int cx = roi.width / 2;

        5. int cy = roi.height / 2;

        6. // 計算角度

        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)矩陣計算

        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. // 對齊

        17. Mat result;

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

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

        3.運行效果

        完整的程序代碼如下:

        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個標(biāo)注點

        19. ? ?params.initShape_n = 10;

        20. ? ?params.stages_n = 5; // 算法的5個強化步驟

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

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

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

        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. ? ?// 開始檢測

        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個 landmark點位

        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. ? ?// 計算中心位置

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

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

        74. ? ?// 計算角度

        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)矩陣計算

        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. ? ?// 對齊

        85. ? ?Mat result;

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

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

        88. }



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

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

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

        交流群


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


        瀏覽 65
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            粗长灌满h双龙h双性男男动漫 | 久久久精品影视 | 亚洲中文在线视频 | 日韩精品一区二区三区妇产科痴汉 | 日本高潮视频 | 翔田千里电影一二三区 | 污污网站观看 | 干人人| 自拍偷拍1| 日韩一级影片 |