1. 程式人生 > >OpenCV實踐之路——人臉檢測(C++/Python)

OpenCV實踐之路——人臉檢測(C++/Python)

本文由@星沉閣冰不語出品,轉載請註明作者和出處。

之前一直覺得人臉檢測是非常麻煩的,即使是用opencv,麻煩到我都不敢去碰。這兩天仔細看了下,如果只是呼叫opencv自帶的分類器和函式的話,簡直是簡單。這不,正好最近也在學習Python,索性就用C++和Python兩種語言都實現一下。當然,我現在這個是最簡單的版本。

步驟:

呼叫opencv訓練好的分類器和自帶的檢測函式檢測人臉人眼等的步驟簡單直接:

1.載入分類器,當然分類器事先要放在工程目錄中去。分類器本來的位置是在*\opencv\sources\data\haarcascades(harr分類器,也有其他的可以用,也可以自己訓練)

2.呼叫detectMultiScale()函式檢測,調整函式的引數可以使檢測結果更加精確。

3.把檢測到的人臉等用矩形(或者圓形等其他圖形)畫出來。

主要函式:

這裡面最主要的一個函式就是detectMultiScale()。文件中的解釋如下:




1.image表示的是要檢測的輸入影象

2.objects表示檢測到的人臉目標序列

3.scaleFactor表示每次影象尺寸減小的比例

4. minNeighbors表示每一個目標至少要被檢測到3次才算是真的目標(因為周圍的畫素和不同的視窗大小都可以檢測到人臉),

5.minSize為目標的最小尺寸

6.minSize為目標的最大尺寸

適當調整4,5,6兩個引數可以用來排除檢測結果中的干擾項。

程式:

C++程式如下:

#include<opencv2\opencv.hpp>
#include <iostream>
#include <stdio.h>

using namespace std;
using namespace cv;

/** Function Headers */
void detectAndDisplay(Mat frame);

/** Global variables */
String face_cascade_name = "haarcascade_frontalface_default.xml";
String eyes_cascade_name = "haarcascade_eye_tree_eyeglasses.xml";
CascadeClassifier face_cascade;   //定義人臉分類器
CascadeClassifier eyes_cascade;   //定義人眼分類器
String window_name = "Capture - Face detection";

/** @function main */
int main(void)
{
	Mat frame = imread("2.jpg");

	//VideoCapture capture;
	//Mat frame;

	//-- 1. Load the cascades
	if (!face_cascade.load(face_cascade_name)){ printf("--(!)Error loading face cascade\n"); return -1; };
	if (!eyes_cascade.load(eyes_cascade_name)){ printf("--(!)Error loading eyes cascade\n"); return -1; };

	//-- 2. Read the video stream
	//capture.open(0);
	//if (!capture.isOpened()) { printf("--(!)Error opening video capture\n"); return -1; }

	//while (capture.read(frame))
	//{
	//	if (frame.empty())
	//	{
	//		printf(" --(!) No captured frame -- Break!");
	//		break;
	//	}

		//-- 3. Apply the classifier to the frame
		detectAndDisplay(frame);

		int c = waitKey(0);
		if ((char)c == 27) { return 0; } // escape
	//}
	return 0;
}

/** @function detectAndDisplay */
void detectAndDisplay(Mat frame)
{
	std::vector<Rect> faces;
	Mat frame_gray;

	cvtColor(frame, frame_gray, COLOR_BGR2GRAY);
	equalizeHist(frame_gray, frame_gray);

	//-- Detect faces
	face_cascade.detectMultiScale(frame_gray, faces, 1.1, 3, CV_HAAR_DO_ROUGH_SEARCH, Size(70, 70),Size(100,100));

	for (size_t i = 0; i < faces.size(); i++)
	{
		//Point center(faces[i].x + faces[i].width / 2, faces[i].y + faces[i].height / 2);
		//ellipse(frame, center, Size(faces[i].width / 2, faces[i].height / 2), 0, 0, 360, Scalar(255, 0, 255), 4, 8, 0);
		rectangle(frame, faces[i],Scalar(255,0,0),2,8,0);
		
		Mat faceROI = frame_gray(faces[i]);
		std::vector<Rect> eyes;

		//-- In each face, detect eyes
		eyes_cascade.detectMultiScale(faceROI, eyes, 1.1, 1, CV_HAAR_DO_ROUGH_SEARCH, Size(3, 3));

		for (size_t j = 0; j < eyes.size(); j++)
		{
			Rect rect(faces[i].x + eyes[j].x, faces[i].y + eyes[j].y, eyes[j].width, eyes[j].height);
			
			//Point eye_center(faces[i].x + eyes[j].x + eyes[j].width / 2, faces[i].y + eyes[j].y + eyes[j].height / 2);
			//int radius = cvRound((eyes[j].width + eyes[j].height)*0.25);
			//circle(frame, eye_center, radius, Scalar(255, 0, 0), 4, 8, 0);
			rectangle(frame, rect, Scalar(0, 255, 0), 2, 8, 0);
		}
	}
	//-- Show what you got
	namedWindow(window_name, 2);
	imshow(window_name, frame);
}
Python程式如下:
import numpy as np
import cv2


face_cascade = cv2.CascadeClassifier("/haarcascade_frontalface_default.xml")
eye_cascade = cv2.CascadeClassifier("/haarcascade_eye_tree_eyeglasses.xml")

img = cv2.imread("/2.jpg")
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
                    
faces = face_cascade.detectMultiScale(gray,1.1,5,cv2.CASCADE_SCALE_IMAGE,(50,50),(100,100))

if len(faces)>0:
    for faceRect in faces:
        x,y,w,h = faceRect
        cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2,8,0)

        roi_gray = gray[y:y+h,x:x+w]
        roi_color = img[y:y+h,x:x+w]

        eyes = eye_cascade.detectMultiScale(roi_gray,1.1,1,cv2.CASCADE_SCALE_IMAGE,(2,2))
        for (ex,ey,ew,eh) in eyes:
            cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
            
cv2.imshow("img",img)
cv2.waitKey(0)

效果:

最終結果如下圖所示:


知識星球

除了平時發文章之外,也會發一些平時學習過程中其他的參考資料和程式碼,歡迎加入。



相關推薦

OpenCV實踐——人臉檢測C++/Python)

本文由@星沉閣冰不語出品,轉載請註明作者和出處。之前一直覺得人臉檢測是非常麻煩的,即使是用opencv,麻煩到我都不敢去碰。這兩天仔細看了下,如果只是呼叫opencv自帶的分類器和函式的話,簡直是簡單。這不,正好最近也在學習Python,索性就用C++和Python兩種語言都

OpenCV實踐——人臉識別二模型訓練

本文由@星沉閣冰不語出品,轉載請註明作者和出處。在之前的部落格人臉識別之一資料收集和預處理之中,已經下載了ORL人臉資料庫,並且為了識別自己的人臉寫了一個拍照程式自拍。之後對拍的照片進行人臉識別和提取,最後我們得到了一個包含自己的人臉照片的資料夾s41。在部落格的最後我們提到

利用opencv實現人臉檢測C++版)

小編所有的帖子都是基於unbuntu系統的,當然稍作修改同樣試用於windows的,經過小編的絞盡腦汁,把剛剛發的那篇python 實現人臉和眼睛的檢測的程式用C++ 實現了,當然,也參考了不少大神的部落格,下面我們就一起來看看: Linux系統下安裝open

vuex實踐——筆記本應用一)

time 中大 -- this 隔離 思想 一個表 環境搭建 一定的 首先使用vue-cli把環境搭建好。 介紹一下應用的界面。 App.vue根組件,就是整個應用的最外層 Toolbar.vue:最左邊紅色的區域,包括三個按鈕,添加、收藏、刪除。 NoteList.vu

vuex實踐——筆記本應用三)

lang 們的 res tool method note 做到 筆記 not Actions Action 類似於 mutation,不同在於: Action 提交的是 mutation,而不是直接變更狀態。 Action 可以包含任意異步操作。 讓我們來註冊一個簡單的

OpenCV實踐——Python的安裝和使用

imread ipp 多少 變量 target 好的 文件 記錄 span 本文由@星沈閣冰不語出品,轉載請註明作者和出處。 文章鏈接:http://blog.csdn.net/xingchenbingbuyu/article/details/

OpenCV實踐——使用imread()函式讀取圖片的六種正確姿勢

經常看到有人在網上詢問關於imread()函式讀取圖片失敗的問題。今天心血來潮,經過實驗,總結出imread()呼叫的四種正確姿勢。通常我要獲取一張圖片的絕對路徑是這樣做的:在圖片上右鍵——屬性——安全——物件名稱。然後複製物件名稱就得到了圖片的絕對路徑。如圖:然而這樣得到的

OpenCV實踐——圓形切割和矩形切割

本文由@星沉閣冰不語出品,轉載請註明作者和出處。 之前對於Opencv的學習,一直是一種查詢資料然後執行別人的程式碼的狀態。自己最多修改個變數什麼的。直到上學期期末的時候才開始有意識地給自己讓自己解決一些自己提出的問題。也許在大神們看來這些問題太多簡單甚至幼稚,

OpenCV實踐——opencv玩數獨之一九宮格輪廓提取與透視變換

本文由@星沉閣冰不語出品,轉載請註明作者和出處。本文部分參考自如下連結:Sudoku-recognizer。前幾天發現了這個網頁,覺得挺好玩的,就想自己實現一下。本以為只是把程式碼從Python轉換到C++是一件很簡單的事情,經過這幾天的努力發現是自己想的太簡單了。到現在也沒

OpenCV實踐——opencv玩數獨二九宮格小方格的提取和數字的提取

本文由@星沉閣冰不語出品,轉載請註明作者和出處。在之前的博文OpenCV實踐之路——opencv玩數獨之一九宮格輪廓提取與透視變換中,已經實現了九宮格最外圍矩形輪廓的提取,並利用透視變換把矩形擺正。今天接著上一篇的內容,在擺正後的矩形中檢測並提取出九九八十一個小方格,並提取出

Python學習——第二彈認識python

內容 代碼結構 計算 戰術 個人 方法 十分 現在 目的   第一彈中我是說明了學習python的目的,主要為了自我提升的考慮,那麽為什麽我對python感興趣,python有什麽用了?本章就簡單說明下。   python的用途很廣,而且代碼十分簡潔,不像java、c等其他

OpenCV探索十五):角點檢測

回調函數 閾值 source and 類型 幾何 擁有 .com named 角點檢測是計算機視覺系統中用來獲取圖像特征的一種方法。我們都常說,這幅圖像很有特點,但是一問他到底有哪些特點,或者這幅圖有哪些特征可以讓你一下子就識別出該物體,你可能就說不出來了。其實說圖像的特征

OpenCV探索六):邊緣檢測canny、sobel、laplacian)

邊緣檢測的一般步驟: 濾波——消除噪聲 增強——使邊界輪廓更加明顯 檢測——選出邊緣點 Canny演算法 Canny邊緣檢測演算法被很多人推崇為當今最優秀的邊緣檢測演算法,所以我們第一個就介紹他。 opencv中提供了Canny函式。 #include<

OpenCV探索十三):詳解掩膜mask

ret 如果 拷貝 ace 設置 之路 動作 與運算 區域 在OpenCV中我們經常會遇到一個名字:Mask(掩膜)。很多函數都使用到它,那麽這個Mask到底什麽呢? 一開始我接觸到Mask這個東西時,我還真是一頭霧水啊,也對無法理解Mask到底有什麽用。經過查閱大量資料後

OpenCV探索十六):圖像矯正技術深入探討

double gb2 教科書 長方形 strong fine open lines 導致 剛進入實驗室導師就交給我一個任務,就是讓我設計算法給圖像進行矯正。哎呀,我不太會圖像這塊啊,不過還是接下來了,硬著頭皮開幹吧! 那什麽是圖像的矯正呢?舉個例子就好明白了。 我的好朋友小

轉)微服務框架落地實踐

整合 改善 系統調用 系列 開源 服務 .com 跨語言 拆分 http://www.primeton.com/read.php?id=2276&his=1 一、微服務架構產生的背景 近十年中,互聯網給我們生活帶來了翻天覆地的變化,消費者的生活方式日益數字

OpenCV探索二十六):如何去除票據上的印章

com 票據 uid amp 去除 album 探索 ace 十六 http://pic.cnhubei.com/space.php?uid=1774&do=album&id=1338281http://pic.cnhubei.com/space.php?u

使用級聯分類器實現人臉檢測OpenCV自帶的數據)

== output include print code ould har his ... 1 #include <opencv2/opencv.hpp> 2 #include <iostream> 3 4 using namespace

Android MVP 實踐理解篇)

一.簡單介紹下MVP 1.什麼是mvp? 簡稱:MVP 全稱:Model-View-Presenter ;MVP 是從經典的模式MVC演變而來,它們的基本思想有相通的地方:Controller/Presenter負責邏輯的處理,Model提供資料,View負責顯示。 2.mv

Opencv 學習一)

前面很長一段時間一直在用opencv庫但是一直沒有去系統的學習,都是遇到問題直接百度,連庫內大多數函式都不認識。最近閒下來了打算系統將opencv學習下 1、開啟圖片 2、讀取視訊 3、開啟攝像頭拍照 4、對攝像頭捕獲的畫面進行處理 開啟圖片 #includ