linux系统下打开usb摄像头:

“虚拟机–可移动设备–camera – 连接”

通过opencv中自带的opencv_createsamples(用于准备训练数据的正样本和测试样本)和opencv_traincascade进行训练生成分类器。

首先准备好要参与训练的正样本和负样本

opencv识别视频中的车辆_搜索


opencv识别视频中的车辆_txt文件_02


接下来创建一个名为train的新文件夹,在新建的文件夹train里面再新建两个文件夹,car_pos文件夹放正样本,car_neg文件夹放负样本。将opencv自带的两个分类器复制过来train里面(这里博主使用的是opencv4.5,没有自带的分类器,opencv3.4.1有两个可执行文件opencv_createsamples.exe和opencv_traincascade.exe。将这两个文件拷贝到训练文件夹下。这里提供一个可在windows下使用的分类器opencv3.4.1分类器)。

为正样本创建描述文件格式文件pos.txt,即在car_pos文件夹里新建pos.txt文件,然后在cmd里cd到car_pos文件夹下,执行

dir /b > pos.txt

然后在pos.txt文件里搜索 ‘pos.txt’ ,将这一行删除,最终为下图所示

opencv识别视频中的车辆_xml_03


对于负样本也同样在car_neg文件夹里新建neg.txt文件,然后在cmd里cd到car_neg文件夹下,执行

dir /b > neg.txt

在neg.txt文件里搜索 ‘neg.txt’ ,将这一行删除,最终为下图所示

opencv识别视频中的车辆_搜索_04


接下来在train文件中创建一个data文件,data文件是用来装训练之后输出的xml文本的。

在train文件中打开终端,输入以下命令

opencv_createsamples.exe info pos.txt -vec pos_samples.vec -num 840 -w 32 -h 24

其中,-info字段填写正样本描述文件;-vec用于保存制作的正样本;-num制定正样本的数目;-w和-h分别指定正样本的宽和高。

输出文件是以.vec为后缀的包含图像信息的二进制数据类型。
继续输入以下命令即将开始训练。

opencv_traincascade.exe -data data -vec pos_samples.vec -bg neg.txt -numPos 610 -numNeg 1500 -numStages 15 -featureType HAAR -w 32 -h 24

opencv识别视频中的车辆_opencv识别视频中的车辆_05


报这个错是因为负样本的路径问题。或者文件内有空格

改成以下即可

opencv识别视频中的车辆_opencv识别视频中的车辆_06


再次运行,开始漫长的训练过程

opencv识别视频中的车辆_搜索_07


opencv识别视频中的车辆_txt文件_08


至此训练结束,在data文件夹中生成了很多xml文件,有用的只有cascade.xml

在vscode中新建main.cpp,配置opencv库(参考前几篇博客),之后输入以下代码。

#include <opencv2/opencv.hpp>
#include <iostream>
 
using namespace cv;
using namespace std;
 
String cascade_name = "/home/llw/桌面/tt/data/cascade.xml";
String window_name = "Capture - car detection";
CascadeClassifier customFaceDetector;
 
Mat image;
Mat gray_src;
 
int main() {
    //cout << "Built with OpenCV " << CV_VERSION << endl;
    VideoCapture capture; //VideoCapture(0) 打开摄像头
    capture.open(0);
    if(capture.isOpened()){
        cout << "Capture is opened" << endl;

        for(;;) //死循环
        {
            vector<Rect> faces;
            capture >> image;
             
            if (!customFaceDetector.load(cascade_name))
            {
                cout<<"could not load face data...\n"<<endl;
                return 0;
            }

            if(image.empty())
                break;

            //namedWindow("IMAGE",WINDOW_AUTOSIZE);
            //imshow("image", image);

            cvtColor(image, gray_src, COLOR_BGR2GRAY); //gray灰色
            equalizeHist(gray_src, gray_src); //均衡化
    
            customFaceDetector.detectMultiScale(gray_src, faces, 1.1, 2, 0, Size(50, 50));
    
            for (size_t t = 0; t < faces.size(); t++){
                rectangle(image, faces[t], Scalar(0, 0, 255), 3); 
            }
    
            //namedWindow(window_name, CV_WINDOW_AUTOSIZE);
            imshow(window_name, image);
    
            /*char c=waitKey(1);
            if(c==3){
                break;
            }*/

            if(waitKey(3) >= 0) 
                break;
        }
    }

    else
    {
        cout << "No capture" << endl;
        image = Mat::zeros(480, 640, CV_8UC1);
        //drawText(image);
        imshow("Test", image);
        waitKey(0);
    }

    return 0;
}

运行效果如下。

opencv识别视频中的车辆_搜索_09


至此完成了使用opencv进行车辆识别的功能。