You don't have javascript enabled. Good luck! :(

This is a test

You’ll find this post in your _posts directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different ways, but the most common way is to run jekyll serve, which launches a web server and auto-regenerates your site when a file is updated.

To add new posts, simply add a file in the _posts directory that follows the convention YYYY-MM-DD-name-of-post.ext and includes the necessary front matter. Take a look at the source for this post to get an idea about how it works.

Jekyll also offers powerful support for code snippets:

def print_hi(name)
  puts "Hi, #{name}"
end
print_hi('Tom')
#=> prints 'Hi, Tom' to STDOUT.

Check out the Jekyll docs for more info on how to get the most out of Jekyll. File all bugs/feature requests at Jekyll’s GitHub repo. If you have questions, you can ask them on Jekyll Talk.

  Nov 20, 2017     WenYuan     OpenCV  UPDATE:

[OpenCV] 臉部偵測 (FaceDetection)

我的實作環境

  • 作業系統: Lubuntu 16.04
  • OpenCV 函式庫版本: Version 3.3
  • 程式語言: C++

在作業系統方面不用擔心, 因為 OpenCV 是一個跨平台的函數庫


先建立檔案

先依序建立以下幾個檔案:

mkdir FaceDetection
cd FaceDetection
mkdir Source
touch FaceDetection.cpp


下載人臉及人眼分類器

先進到 Source 目錄中

cd Source

下載人臉及人眼分類器

# 取得人眼分類器

wget https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_eye_tree_eyeglasses.xml

# 取得人臉分類器

wget https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_default.xml

XML 是可以自行定義各標籤名稱的標記式語言, 透過標記式語言, 電腦之間便可以傳輸各種資訊 所以當我們 Load 上面兩個 XML 進程式之後, 就可以使用他們的演算法來找出人臉及眼睛


開始撰寫臉部偵測

/** FaceDetection.cpp **/
#include <opencv2/opencv.hpp>
#include <iostream>
#include <stdio.h>

using namespace std;
using namespace cv;

/** Print error message **/
void PANIC(char *msg);
#define PANIC(msg){perror(msg); exit(-1);}

/** Function for face detection **/
void DetectAndDraw(Mat frame);

/** Global variables **/
String face_cascade_name = "Source/haarcascade_frontalface_default.xml";
String eyes_cascade_name = "Source/haarcascade_eye_tree_eyeglasses.xml";
CascadeClassifier face_cascade; // Declare the face classifier
CascadeClassifier eyes_cascade; // Declare the eyes classifier
String window_name = "Face detection";

int main(int argc, char *argv[]){
	/* Open the web camera */
	VideoCapture capture = VideoCapture(0);
	Mat frame, image;
	
	/** Load cascade classifiers **/
	if(!face_cascade.load(face_cascade_name))
		PANIC("Error loading face cascade");
	if(!eyes_cascade.load(eyes_cascade_name))
		PANIC("Error loading eyes cascade");
	
	/** After the camera is opened **/
	if(capture.isOpened()){
		cout<<"Face Detection Started..."<<endl;

		for(;;){
			/* Get image from camera */
			capture>>frame; 			
			if(frame.empty())
				PANIC("Error capture frame");
			
			/* Start the face detection function */
			DetectAndDraw(frame);
			
			/** If you press ESC, q, or Q , the process will end **/
			char ch = (char)waitKey(10);
			if(ch==27 || ch=='q' || ch=='Q')
				break;
		}
	}
	else
		PANIC("Error open camera");
	
	return 0;
}

void DetectAndDraw(Mat frame){
    /* Declare vector for faces and eyes */
    std::vector<Rect> faces, eyes;
    Mat frame_gray, frame_resize;
    int radius;
	
    /* Convert to gray scale */
    cvtColor(frame, frame_gray, COLOR_BGR2GRAY);
    //imshow("grayscale", frame_gray);
	
    /* Resize the grayscale Image */
    //resize(frame_gray, frame_resize, Size(), 1, 1, INTER_LINEAR);
    //imshow("resize", frame_resize);
	
    /* Histogram equalization */
    equalizeHist(frame_gray, frame_gray);
    //imshow("equalize", frame_gray);
	
    /* Detect faces of different sizes using cascade classifier */
    face_cascade.detectMultiScale(frame_gray, faces, 1.1, 5, CV_HAAR_SCALE_IMAGE, Size(30, 30));
	
    /** Draw circles around the faces **/
    for (size_t i = 0; i < faces.size(); i++)
    {
        Point center;
 
        /* Draw rectangular on face */
        rectangle(frame, faces[i], Scalar(255, 0, 0), 3, 8, 0);

        Mat faceROI = frame_gray(faces[i]);

        /* Detection of eyes int the input image */
        eyes_cascade.detectMultiScale(faceROI, eyes, 1.1, 1, CV_HAAR_SCALE_IMAGE, Size(3, 3)); 
         
        /** Draw circles around eyes **/
        for (size_t j = 0; j < eyes.size(); j++) 
        {
            center.x = cvRound((faces[i].x + eyes[j].x + eyes[j].width*0.5));
            center.y = cvRound((faces[i].y + eyes[j].y + eyes[j].height*0.5));
            radius = cvRound((eyes[j].width + eyes[j].height)*0.25);
            circle(frame, center, radius, Scalar(0, 255, 0), 3, 8, 0);
        }
    }
 
    // Show Processed Image with detected faces
    imshow( "Face Detection", frame);
}


編譯與執行

## 編譯

g++ FaceDetection.cpp -o output `pkg-config --cflags --libs opencv`

# 執行

./output

執行後將你的臉對準攝相頭, 應該會看到你的臉及眼睛被框出來

如果你還沒安裝 OpenCV 可以參考我的文章來安裝


解釋程式

其實過程很簡單, 大致分為以下幾個步驟:

  • 將人臉和人眼分類器 Load 進來
  • 使用 cvtColor() 將影像轉換成灰階
  • 使用 resize() 更改影像大小比率, 視情況而定, 我們在這裡先不用
  • 使用 equalizeHist() 將影像做直方圖等化, 以增強對比度
  • 運用 XML 內的分類器演算法來偵測人臉和人眼
  • 分別框出臉和眼睛
  • 完成臉部偵測