linux系统下打开usb摄像头:
“虚拟机–可移动设备–camera – 连接”
通过opencv中自带的opencv_createsamples(用于准备训练数据的正样本和测试样本)和opencv_traincascade进行训练生成分类器。
首先准备好要参与训练的正样本和负样本
接下来创建一个名为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’ ,将这一行删除,最终为下图所示
对于负样本也同样在car_neg文件夹里新建neg.txt文件,然后在cmd里cd到car_neg文件夹下,执行
dir /b > neg.txt
在neg.txt文件里搜索 ‘neg.txt’ ,将这一行删除,最终为下图所示
接下来在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
报这个错是因为负样本的路径问题。或者文件内有空格
改成以下即可
再次运行,开始漫长的训练过程
至此训练结束,在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进行车辆识别的功能。