如何在opencv中训练模块进行图像识别 [英] How train module for image recognition in opencv

查看:115
本文介绍了如何在opencv中训练模块进行图像识别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用c ++和opencv来识别面部。在文档示例中,我无法理解这些行。他们是什么以及如何在文件夹上制作参考图像以及什么是cvs文件。请帮我。开始进行图像处理。



  int  main( int  argc, const   char  * argv []) {
//
cout<< 用法:<< argv [ 0 ]<< < / path / to / haar_cascade>< /path/to/csv.Check查看有效的命令行参数,打印用法
//如果没有给出参数。
if(argc!= 4){ext>< / path / to / device id>
<< ENDL;
cout<< \t< / path / to / haar_cascade> - 用于面部检测的Haar Cascade路径。<< ENDL;
cout<< \t< /path/to/csv.ext> - 使用面部数据库的CSV文件的路径。<< ENDL;
cout<< \t< device id> - 从中​​抓取帧的网络摄像头设备ID。< ;< ENDL;
退出( 1 );
}





我的尝试:



  #include      opencv2 / core / core.hpp 
#include opencv2 / contrib / contrib.hpp
#include opencv2 / highgui / highgui.hpp
#include opencv2 / imgproc / imgproc.hpp
#include opencv2 /objdetect/objdetect.hpp

#include < iostream >
#include < fstream >
#include < sstream >

使用 命名空间 cv;
使用 命名空间标准;

static void read_csv( const string& filename,vector< mat>& images,vector< int>& labels, char separator = ' ;'){
std :: ifstream file(filename.c_str(),ifstream :: );
if (!file){
string error_message = 没有给出有效的输入文件,请检查给定的文件名。;
CV_Error(CV_StsBadArg,error_message);
}
string line,path,classlabel;
while (getline(file,line)){
stringstream liness(line);
getline(liness,path,separator);
getline(liness,classlabel);
if (!path.empty()&&!classlabel.empty()){
images.push_back(imread(path, 0 ));
labels.push_back(atoi(classlabel.c_str()));
}
}
}

int main( int argc, const char * argv []){
// 检查有效的命令行参数,打印用量
// 如果没有给出参数。
if (argc!= < span class =code-digit> 4
){
cout<< 用法:<< argv [ 0 ]<< < / path / to / haar_cascade>< /path/to/csv.ext>< / path / to / device id><< ENDL;
cout<< \t< / path / to / haar_cascade> - 用于面部检测的Haar Cascade路径。<< ENDL;
cout<< \t< /path/to/csv.ext> - 使用面部数据库的CSV文件的路径。<< ENDL;
cout<< \t< device id> - 从中​​抓取帧的网络摄像头设备ID。< ;< ENDL;
退出( 1 );
}
// 获取CSV的路径:
string fn_haar = string(argv [ 1 ]);
string fn_csv = string(argv [ 2 ]);
int deviceId = atoi(argv [ 3 ]);
// 这些向量包含图像和相应的标签:
vector< mat> ;图片;
vector< int>标签;
// 读入数据(如果没有给出有效的输入文件名,则会失败,但你会得到一个错误消息):
尝试 {
read_csv(fn_csv,images,labels);
} catch (cv :: Exception& e){
cerr<< 打开文件时出错\<<< fn_csv<< \。原因:<< e.msg<< ENDL;
// 我们无能为力
exit( 1 );
}
// 从第一张图片中获取高度。我们稍后需要这个
// 在代码中将图像重新整形为原始
// 尺寸我们需要将传入的面重塑为此尺寸:
int im_width = images [ 0 ]。cols;
int im_height = images [ 0 ]。rows;
// 创建FaceRecognizer并在给定图像上训练它:
Ptr< ; facerecognizer> model = createFisherFaceRecognizer();
model-> train(图片,标签);
// 这是学习人脸识别模型的原因。您现在
// 需要为人脸检测任务创建分类器。
// 我们将使用您在 $中指定的haar级联b $ b // 命令行参数:
//
CascadeClassifier haar_cascade;
haar_cascade.load(fn_haar);
// 获取视频设备的句柄:
VideoCapture cap(deviceId );
// 检查我们是否可以使用此设备:
if (!cap.isOpened()){
cerr<< 捕获设备ID<< deviceId<< 无法打开。<< ENDL;
返回 - 1 ;
}
// 保留视频设备中的当前帧:
Mat框架;
(;;){
cap>>帧;
// 克隆当前帧:
Mat original = frame.clone( );
// 将当前帧转换为灰度:
Mat grey;
cvtColor(original,grey,CV_BGR2GRAY);
// 查找框架中的面孔:
vector< Rect_< INT> >面对;
haar_cascade.detectMultiScale(灰色,面孔);
// 此时你的面部位置在
< span class =code-comment> //
faces。现在我们将获得面孔,进行预测并
// 在视频。酷或什么?
for int i = 0 ; i< faces.size(); i ++){
// 面对面处理:
Rect face_i = faces [i];
// 从图像中裁剪面部。使用OpenCV C ++如此简单:
Mat face = gray(face_i);
// Eigenfaces和Fisherfaces需要调整面的大小。您可以通过阅读OpenCV附带的人脸识别教程轻松
// 验证这一点。
// 调整局部二进制模式不需要调整直方图,所以准备
// 输入数据实际上取决于所使用的算法。
< span class =code-comment> //
// < span class =code-comment>我强烈建议您使用算法。在您的方案中查看哪个最佳工作
// ,LBPH应始终是强大的竞争者面部识别。
//
// 由于我在这里展示了Fisherfaces算法,我还展示了如何调整
// 您刚刚找到的面孔:
Mat face_resized;
cv :: resize(face,face_resized,Size(im_width,im_height), 1 0 1 0 ,INTER_CUBIC);
// 现在执行预测,看看它有多简单:
< span class =code-keyword> int prediction = model-> predict(face_resized);
// 最后写下我们发现的所有原始图像!
// 首先在检测到的面部周围绘制一个绿色矩形:
rectangle( original,face_i,CV_RGB( 0 255 0 ), 1 );
// 创建我们将在框中注释的文本:
string box_text = format( Prediction =%d,预测);
// 计算带注释文本的位置(确保我们不
// 将非法值放入其中):
int pos_x = std :: max(face_i.tl()。x - 10 0 < /跨度>);
int pos_y = std :: max(face_i.tl()。y - 10 0 );
// 现在把它放到图片中:
putText(原文, box_text,Point(pos_x,pos_y),FONT_HERSHEY_PLAIN, 1 0 ,CV_RGB( 0 255 0 ), 2 0 );
}
// 显示结果:
imshow(< span class =code-string>
face_recognizer,original);
// 并显示它:
char key =( char )waitKey( 20 );
// 在转义时退出此循环:
if (key == 27
break ;
}
return 0 ;
}

解决方案

您似乎正在使用 OpenCV视频中的人脸识别 - OpenCV 3.0.0-dev文档 [ ^ ]。



引用:

它们是什么以及如何在文件夹上制作参考图像以及什么是cvs文件

只需阅读链接中的文字:

引用:

在演示中,我决定阅读一个非常简单的CSV文件

这意味着您必须创建一个文本文件,其中包含参考图像和相应标签的图案。 CSV文件是包含表格数据的文本文件,其中行由特定字符分隔(CSV =逗号/字符分隔值,另请参阅以逗号分隔的值 - 维基百科 [ ^ ])。该示例使用';'字符并有两行:文件路径和标签。



作者甚至提供了Python脚本来创建所有的CSV文件特定目录中的图像文件(创建CSV文件)和对齐图像。



您只需要存储在一个目录中的一组面部图像。然后使用脚本对齐图像并创建CSV文件。


i want to identify face using c++ and opencv. on documentation example, i cant understand these line. what are they and how make ref images on the folder and what is the cvs file. please help me. um very beginning to image processing.

int main(int argc, const char *argv[]) {
    // 
        cout << "usage: " << argv[0] << " </path/to/haar_cascade> </path/to/csv.Check for valid command line arguments, print usage
    // if no arguments were given.
    if (argc != 4) {ext> </path/to/device id>" << endl;
        cout << "\t </path/to/haar_cascade> -- Path to the Haar Cascade for face detection." << endl;
        cout << "\t </path/to/csv.ext> -- Path to the CSV file with the face database." << endl;
        cout << "\t <device id> -- The webcam device id to grab frames from." << endl;
        exit(1);
    }



What I have tried:

#include "opencv2/core/core.hpp"
#include "opencv2/contrib/contrib.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/objdetect/objdetect.hpp"

#include <iostream>
#include <fstream>
#include <sstream>

using namespace cv;
using namespace std;

static void read_csv(const string& filename, vector<mat>& images, vector<int>& labels, char separator = ';') {
    std::ifstream file(filename.c_str(), ifstream::in);
    if (!file) {
        string error_message = "No valid input file was given, please check the given filename.";
        CV_Error(CV_StsBadArg, error_message);
    }
    string line, path, classlabel;
    while (getline(file, line)) {
        stringstream liness(line);
        getline(liness, path, separator);
        getline(liness, classlabel);
        if(!path.empty() && !classlabel.empty()) {
            images.push_back(imread(path, 0));
            labels.push_back(atoi(classlabel.c_str()));
        }
    }
}

int main(int argc, const char *argv[]) {
    // Check for valid command line arguments, print usage
    // if no arguments were given.
    if (argc != 4) {
        cout << "usage: " << argv[0] << " </path/to/haar_cascade> </path/to/csv.ext> </path/to/device id>" << endl;
        cout << "\t </path/to/haar_cascade> -- Path to the Haar Cascade for face detection." << endl;
        cout << "\t </path/to/csv.ext> -- Path to the CSV file with the face database." << endl;
        cout << "\t <device id> -- The webcam device id to grab frames from." << endl;
        exit(1);
    }
    // Get the path to your CSV:
    string fn_haar = string(argv[1]);
    string fn_csv = string(argv[2]);
    int deviceId = atoi(argv[3]);
    // These vectors hold the images and corresponding labels:
    vector<mat> images;
    vector<int> labels;
    // Read in the data (fails if no valid input filename is given, but you'll get an error message):
    try {
        read_csv(fn_csv, images, labels);
    } catch (cv::Exception& e) {
        cerr << "Error opening file \"" << fn_csv << "\". Reason: " << e.msg << endl;
        // nothing more we can do
        exit(1);
    }
    // Get the height from the first image. We'll need this
    // later in code to reshape the images to their original
    // size AND we need to reshape incoming faces to this size:
    int im_width = images[0].cols;
    int im_height = images[0].rows;
    // Create a FaceRecognizer and train it on the given images:
    Ptr<facerecognizer> model = createFisherFaceRecognizer();
    model->train(images, labels);
    // That's it for learning the Face Recognition model. You now
    // need to create the classifier for the task of Face Detection.
    // We are going to use the haar cascade you have specified in the
    // command line arguments:
    //
    CascadeClassifier haar_cascade;
    haar_cascade.load(fn_haar);
    // Get a handle to the Video device:
    VideoCapture cap(deviceId);
    // Check if we can use this device at all:
    if(!cap.isOpened()) {
        cerr << "Capture Device ID " << deviceId << "cannot be opened." << endl;
        return -1;
    }
    // Holds the current frame from the Video device:
    Mat frame;
    for(;;) {
        cap >> frame;
        // Clone the current frame:
        Mat original = frame.clone();
        // Convert the current frame to grayscale:
        Mat gray;
        cvtColor(original, gray, CV_BGR2GRAY);
        // Find the faces in the frame:
        vector< Rect_<int> > faces;
        haar_cascade.detectMultiScale(gray, faces);
        // At this point you have the position of the faces in
        // faces. Now we'll get the faces, make a prediction and
        // annotate it in the video. Cool or what?
        for(int i = 0; i < faces.size(); i++) {
            // Process face by face:
            Rect face_i = faces[i];
            // Crop the face from the image. So simple with OpenCV C++:
            Mat face = gray(face_i);
            // Resizing the face is necessary for Eigenfaces and Fisherfaces. You can easily
            // verify this, by reading through the face recognition tutorial coming with OpenCV.
            // Resizing IS NOT NEEDED for Local Binary Patterns Histograms, so preparing the
            // input data really depends on the algorithm used.
            //
            // I strongly encourage you to play around with the algorithms. See which work best
            // in your scenario, LBPH should always be a contender for robust face recognition.
            //
            // Since I am showing the Fisherfaces algorithm here, I also show how to resize the
            // face you have just found:
            Mat face_resized;
            cv::resize(face, face_resized, Size(im_width, im_height), 1.0, 1.0, INTER_CUBIC);
            // Now perform the prediction, see how easy that is:
            int prediction = model->predict(face_resized);
            // And finally write all we've found out to the original image!
            // First of all draw a green rectangle around the detected face:
            rectangle(original, face_i, CV_RGB(0, 255,0), 1);
            // Create the text we will annotate the box with:
            string box_text = format("Prediction = %d", prediction);
            // Calculate the position for annotated text (make sure we don't
            // put illegal values in there):
            int pos_x = std::max(face_i.tl().x - 10, 0);
            int pos_y = std::max(face_i.tl().y - 10, 0);
            // And now put it into the image:
            putText(original, box_text, Point(pos_x, pos_y), FONT_HERSHEY_PLAIN, 1.0, CV_RGB(0,255,0), 2.0);
        }
        // Show the result:
        imshow("face_recognizer", original);
        // And display it:
        char key = (char) waitKey(20);
        // Exit this loop on escape:
        if(key == 27)
            break;
    }
    return 0;
}

解决方案

It seems you are using the code from Face Recognition in Videos with OpenCV — OpenCV 3.0.0-dev documentation[^].

Quote:

what are they and how make ref images on the folder and what is the cvs file

Just read the text from your link:

Quote:

In the demo I have decided to read the images from a very simple CSV file

That means that you have to create a text file containing the pathes to the reference images and the corresponding labels. A CSV file is a text file containing tabular data where rows are separated by a specific character (CSV = Comma/Character Separated Values, see also Comma-separated values - Wikipedia[^] ). The example uses the ';' character and has two rows: The file path and the label.

The author has even provided Python scripts to create the CSV file from all image files in a specific directory (Creating the CSV file) and aligning images.

All you need is a set of face images stored within one directory. Then use the scripts to align the images and create the CSV file.


这篇关于如何在opencv中训练模块进行图像识别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆