Opencv_臉譜分類器_研究_part1(臉部到眼睛_CascadeClassifier類介紹_參數)
畫出來的人臉好像不太像人臉 畫工有待加強 QQ
// 階梯式類器別宣告
CascadeClassifier face_cascade; // 人臉分類器
CascadeClassifier eyes_cascade; //眼睛分類器
CascadeClassifier mouth_cascade; //嘴巴分類器
指定 分類器xml檔路徑
下方是主要函式的演算定義
/* 函式 detectAndDisplay 的定義函式 */
void detectAndDisplay(Mat frame)
{
std::vector<Rect> faces; // 首先 vector<Rect> faces; 一個存放臉的陣列(矩陣)
Mat frame_gray;
// 在影像處理領域中很常先轉灰階再直方均勻化來做處理
//主要目的是為了,去除任何彩色資訊,我們只計算ROI的灰階值(亮度值)
// 將攝像轉成灰階
cvtColor(frame, frame_gray, COLOR_BGR2GRAY);
// 灰階圖作直條式的評等化
equalizeHist(frame_gray, frame_gray);
//-- 偵測臉
face_cascade.detectMultiScale(frame_gray,faces, 1.1, 2, 0
| CASCADE_SCALE_IMAGE, Size(30, 30));
//在取得人臉臉譜的矩陣資訊(都正的;非負的)之後,我們利用loop來遍歷
for (size_t i = 0; i < faces.size(); i++) //無符號的,0-MAXINT的範圍 人臉臉譜loop
{
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);
//printf("繪臉, 臉的大小 %d..............\n", faces.size());
Mat faceROI = frame_gray(faces[i]);//
std::vector<Rect> eyes;
//-- 在臉內偵測眼睛
eyes_cascade.detectMultiScale(faceROI, eyes,
1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30));
for (size_t j = 0; j < eyes.size(); j++)
{
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);
//printf("繪眼, 眼睛數量 %d\n\n\n", eyes.size());
}
std::vector<Rect> mouth;
//-- 在臉內偵測嘴巴
mouth_cascade.detectMultiScale(faceROI, mouth,
1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30));
for (size_t j = 0; j < mouth.size(); j++)
{
Point mouth_center(faces[i].x + mouth[j].x + mouth[j].width / 2,
faces[i].y + mouth[j].y + mouth[j].height / 2);
int radius = cvRound((mouth[j].width + mouth[j].height)*0.25);
circle(frame, mouth_center, radius, Scalar(0, 255, 0), 4, 8, 0);
}
}
//-- 顯示結果
imshow(window_name, frame);
}
針對 人臉區塊的詳說
這裡改個顏色
===================================================================
Point這個函式怎麼運作的呢???
Point 這個資料結構 能 存取及表示 二維座標的點(x,y)
上方提供兩種方式來做指派座標印出座標
1.多行打法
2.一行指定
===================================================================
ellipse 這個函式怎麼運作的呢???
在使用ellipse之前我們知道它是用來畫橢圓用的
在畫圖前應該要先準備好畫布
因此我先試著產生一個畫布
測試代碼
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <opencv2/opencv.hpp> | |
#include<opencv2\highgui\highgui.hpp> | |
#include<opencv2\imgproc\imgproc.hpp> | |
#include<opencv2\core\core.hpp> | |
#include<opencv2\video\background_segm.hpp> | |
#include<stdlib.h> | |
using namespace cv; | |
using namespace std; | |
int main(void) | |
{ | |
// 創建一個黑色畫布 | |
// CV_8UC3----->8位元的unsigned char型態三通道 | |
// CV_[位元數][有無帶符號]C[通道數目] | |
Mat image1 = Mat::zeros(400, 400, CV_8UC3); | |
//宣告所有值都是0的矩陣 , 矩陣大小為 600(直行)*400(橫列) , | |
//Mat::zeros(int rows, int cols, int type) | |
//rows -> 行數 | |
//cols -> 列數 | |
ellipse(image1, Point(200, 200), Size(100.0, 160.0), 0, 0, 360, Scalar(255, 0, 0), 1, 8); | |
imshow("Image1_0度", image1); | |
Mat image2 = Mat::zeros(400, 400, CV_8UC3); | |
ellipse(image2, Point(200, 200), Size(100.0, 160.0), 45, 0, 360, Scalar(255, 0, 0), 1, 8); | |
imshow("Image2_45度", image2); | |
Mat image3 = Mat::zeros(400, 400, CV_8UC3); | |
ellipse(image3, Point(200, 200), Size(100.0, 160.0), 90, 0, 360, Scalar(255, 0, 0), 1, 8); | |
imshow("Image3_90度", image3); | |
Mat image4 = Mat::zeros(400, 400, CV_8UC3); | |
ellipse(image4, Point(200, 200), Size(100.0, 160.0), 135, 0, 360, Scalar(255, 0, 0), 1, 8); | |
imshow("Image4_135度", image4); | |
Mat image5 = Mat::zeros(400, 400, CV_8UC3); | |
ellipse(image5, Point(200, 200), Size(100.0, 160.0), 180, 0, 360, Scalar(255, 0, 0), 1, 8); | |
imshow("Image5_180度", image5); | |
waitKey(0); | |
return 0; | |
} |
眼睛部分
再來眼睛和嘴巴其實可以和再一起看
眼睛和鼻子都只長在臉部區域
所以臉部為我們的ROI
再偵測眼睛和嘴巴的時候應該要先
設置搜尋的感興趣區域
接著我把註解掉的 眼睛偵測打開了
偵測人臉+眼睛 測試結果
眼睛數量明確被診斷出來了
接著我好奇問了自己如果 (1)不轉灰階也不直方平等化 (2)只轉灰階不直方平等化
這兩個可能會造就捨麼結果呢????
(1)不轉灰階也不直方平等化 ----------------> 捨麼事情也沒發生
(2)只轉灰階不直方平等化----------------> 出現偵測區了
所以接下來我們要來研究一下這行的語法到底在幹嘛
face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30));
注意: face_cascade.detectMultiScale 是內建自己出現的!!!!
捨麼意思就是你不用打全部自動跑出後面語法
當你打完face_cascade. 之後你會發現後面自動語法提示功能
CascadeClassifier類 (級聯分類器類)
haar支持的目標有臉部、眼睛、嘴巴、鼻子、身體。
--------------------------------------------------------------------------------------------------------
CascadeClassifier::detectMultiScale
--------------------------------------------------------------------------------------------------------
我們來看一下函式參數
C++:
void CascadeClassifier:: detectMultiScale ( const Mat& image ,
vector<Rect>& objects ,
double scaleFactor =1.1,
int minNeighbors =3,
int flags =0,
Size minSize =Size(),
Size maxSize =Size() )
參數
================================================
- image –需要檢測的CV_8U輸入矩陣。(單通道)
- objects –輸出vector載體容器用於保存被識別的物體矩陣。
- scaleFactor –指定每張圖片的縮小比例的參數。
- minNeighbors –指定每個候選矩陣至少包含的鄰近元素個數。
- flags – 與舊版級聯分類器模型函數cvHaarDetectObjects的flags相同.此參數不被用於新版模型。(可省略)
- minSize – 最小可能的對象的大小,小於的對象將被忽略。
- maxSize – 最大可能的對象的大小,大於的對象將被忽略。
==================================================
face_cascade.detectMultiScale(frame_gray,
faces,
1.1,
2,
0 | CASCADE_SCALE_IMAGE,
Size(30, 30));
參考資料&文獻&部落格、博客網站連結:
OpenCV 2.4+ C++ 人臉識別
http://www.cnblogs.com/justany/archive/2012/11/22/2781552.htmlOpenCV學習筆記(二十七)——基於級聯分類器的目標檢測objdect
http://blog.csdn.net/yang_xian521/article/details/6973667
留言
張貼留言