opencv-人臉識別-2增加人臉資料集
阿新 • • 發佈:2019-02-02
人臉識別-增加自己的臉或者別人臉的資料
這裡要增加的一定是臉部的資料,而不是全身的,所以要把臉部的影象從原圖中拿出來就可以了,這就是傳說中的人臉檢測。
程式碼
static Mat detectAndDraw(Mat& img, CascadeClassifier& cascade,
double scale, bool tryflip)
{
double t = 0;
vector<Rect> faces, faces2;
const static Scalar colors[] =
{
Scalar(255 ,0,0),
Scalar(255,128,0),
Scalar(255,255,0),
Scalar(0,255,0),
Scalar(0,128,255),
Scalar(0,255,255),
Scalar(0,0,255),
Scalar(255,0,255)
};
Mat imgcopy = img.clone();
Mat gray, smallImg;
cvtColor(img, gray, COLOR_BGR2GRAY);
double fx = 1 / scale;
resize(gray, smallImg, Size(), fx, fx, INTER_LINEAR_EXACT);
equalizeHist(smallImg, smallImg);
t = (double)getTickCount();
cascade.detectMultiScale(smallImg, faces, 1.1, 3, CV_HAAR_DO_ROUGH_SEARCH, Size(70, 70), Size(100, 100));
if (tryflip)
{
flip(smallImg, smallImg, 1 );
cascade.detectMultiScale(smallImg, faces2,
1.1, 2, 0
//|CASCADE_FIND_BIGGEST_OBJECT
//|CASCADE_DO_ROUGH_SEARCH
| CASCADE_SCALE_IMAGE,
Size(30, 30));
for (vector<Rect>::const_iterator r = faces2.begin(); r != faces2.end(); ++r)
{
faces.push_back(Rect(smallImg.cols - r->x - r->width, r->y, r->width, r->height));
}
}
t = (double)getTickCount() - t;
printf("detection time = %g ms\n", t * 1000 / getTickFrequency());
Mat faceROI;
for (size_t i = 0; i < faces.size(); i++)
{
Rect r = faces[i];
Mat smallImgROI;
// vector<Rect> nestedObjects;
Point center;
Scalar color = colors[i % 8];
double aspect_ratio = (double)r.width / r.height;
// if (0.75 < aspect_ratio && aspect_ratio < 1.3)
{
// center.x = cvRound((r.x + r.width*0.5)*scale);
// center.y = cvRound((r.y + r.height*0.5)*scale);
// radius = cvRound((r.width + r.height)*0.25*scale);
// circle(img, center, radius, color, 3, 8, 0);
}
// else
rectangle(img, cvPoint(cvRound(r.x*scale), cvRound(r.y*scale)),
cvPoint(cvRound((r.x + r.width - 1)*scale), cvRound((r.y + r.height - 1)*scale)),
color, 3, 8, 0);
smallImgROI = smallImg(r);
faceROI = imgcopy(Rect(cvPoint(cvRound(r.x*scale), cvRound(r.y*scale)),
cvPoint(cvRound((r.x + r.width - 1)*scale), cvRound((r.y + r.height - 1)*scale))));
}
cv::imshow("result", img);
if (!faceROI.empty())
{
namedWindow("faceROI", WINDOW_NORMAL);
imshow("faceROI", faceROI);
return faceROI;
}
}
/*有兩種輸入方式,可以選擇資料夾,也可以選擇相機*/
//= "faces\\s41";
//= ".jpg";
int detect_save_face(string Normalizat_Dir,int camera_id , string FilePath, string FileType)
{
bool tryflip = 1;
CascadeClassifier cascade;
double scale = 1.3;
string cascadeName = "haarcascade_frontalface_alt.xml";
if (scale < 1)
scale = 1;
if (!cascade.load(cascadeName))
{
cerr << "ERROR: Could not load classifier cascade" << endl;
help();
system("pause");
return -1;
}
/*如果沒有輸入,就啟動相機*/
if (FilePath.empty()||FileType.empty())
{
VideoCapture capture;
Mat frame, image;
//如果相機打不開
if (!capture.open(camera_id))
{
cout << "Capture from camera #" << camera_id << " didn't work" << endl;
system("pause");
return -1;
}
if (capture.isOpened())
{
char *name = new char[Normalizat_Dir.size() + 1];
strcpy(name, Normalizat_Dir.data());
cout << "Video capturing has been started ..." << endl;
for (;;)
{
static int k = 0;
capture >> frame;
if (frame.empty())
break;
Mat frame1 = frame.clone();
Mat faceROI = detectAndDraw(frame1, cascade, scale, tryflip);
// waitKey(200);
char filename[100];
char c = (char)waitKey(10);
if (c == 27 || c == 'q' || c == 'Q')
break;
if (c == 32)
{
if (!faceROI.empty())
{
sprintf(filename, "%s/%d.jpg", name, k++);
resize(faceROI, faceROI, Size(92, 112));
imwrite(filename, faceROI);
imshow("faceROI", faceROI);
}
}
}
delete name;
}
}
/*有輸入的話,則讀取資料夾中的圖片,並儲存頭像圖片*/
else
{
vector<string> FilesName;
/*存放符合格式的影象的名字*/
string buffer = FilePath + "/*" + FileType;
_finddata_t c_file; // 存放檔名的結構體
intptr_t hFile;
hFile = _findfirst(buffer.c_str(), &c_file); //找第一個檔案命
if (hFile == -1L) // 檢查資料夾目錄下存在需要查詢的檔案
cout << "No" << FileType << " files in current directory!!!" << endl;
else
{
int i = 0;
string fullFilePath;
do
{
/*清除上一次快取的名稱*/
fullFilePath.clear();
/*取出檔案照片名*/
fullFilePath = FilePath + "/" + c_file.name;
/*儲存當前檔案的路徑和名稱*/
FilesName.push_back(fullFilePath);
} while (_findnext(hFile, &c_file) == 0);
_findclose(hFile);
}
char *name = new char[Normalizat_Dir.size() + 1];
strcpy(name, Normalizat_Dir.data());
for (int i = 0; i < FilesName.size(); i++)
{
Mat image = imread(FilesName[i], 1);
if (!image.empty())
{
static int k = 0;
Mat faceROI = detectAndDraw(image, cascade, scale, tryflip);
waitKey(200);
char filename[100];
if (!faceROI.empty())
{
sprintf(filename, "%s/%d.jpg", name, k++);
resize(faceROI, faceROI, Size(92, 112));
imwrite(filename, faceROI);
imshow("faceROI", faceROI);
}
}
}
delete name;
}
destroyAllWindows();
return 0;
}