windows 下OpenCV的安装部署详细教程
一、下载OpenCV
到OpenCV官网下载你需要的版本。
点击RELEASES(发布)

由于OpenCV支持好多平台,比如Windows, Android, Maemo, FreeBSD, OpenBSD, iOS, Linux和Mac OS,一般初学者都是用windows,所以在这里下载Win pack

点击Win pack 后跳出下面界面,等待5s自动下载。

下载后是这样的

然后双击他,解压,就是大佬们说的安装,实质就是解压一下,解压完出来一个文件夹,其他什么也没发生。你把这个文件夹放在哪都行,不过你要记住他在哪。

正在解压

解压完打开文件夹是这样的

其中build是OpenCV使用时要用到的一些库文件,而sources中则是OpenCV官方为我们提供的一些demo示例源码
二、配置环境变量
把OpenCV文件夹放好地方后,依次选择计算机—>属性—>高级系统设置—>环境变量,找到Path变量,选中并点击编辑,然后新建把你的OpenCV执行文件的路径填进去,然后一路点确定,这样环境变量就配置完了。

OpenCV执行文件的路径这样找:
找到你解压好的OpenCV文件夹,依次选择build—>x64—>vc15—>bin,
然后是这样的

这个路径就是我的OpenCV执行文件的路径,你的应该和我的差不多吧。
这里注意,如果你下载的是OpenCV2.x版本,选择build后,还需要选择x86或x64,然后是vc12(为什么不是vc10或vc11,一般都是选最新的),其他步骤大同小异。
三、部署OpenCV
前面说了,OpenCV是一个SDK,得使用工具开发它,比如Visual Studio(当然有些大佬只用记事本或神一样的Vim),接下来就是在Visual Studio中部署OpenCV了。
-
安装Visual Studio
因为主题是OpenCV,这个这里不讲了,请自行Google。 -
打开Visual Studio,新建工程
初学者最好是建一个控制台工程,没有其他问题的干扰。 -
添加包含目录
依次选择项目—>属性—>VC++目录—>包含目录—>编辑
找到你的包含目录添加就可以了,最好添加三个,我的是这样的:
D:\opencv\build\include
D:\opencv\build\include\opencv
D:\opencv\build\include\opencv2
图片.png
3.添加库目录
依次选择项目—>属性—>VC++目录—>库目录—>编辑
我的是D:\opencv\build\x64\vc15\lib
图片.png
如果编译报错image.png
去掉打勾image.png
4.添加附加依赖项
依次选择项目—>属性—>链接器—>输入—>附加依赖项—>编辑
添加你的库文件名

库文件这样找:

有两个文件opencv_world341d.lib和opencv_world341.lib
如果配置为Debug,选择opencv_world341d.lib
如果为Release,选择opencv_world341.lib
这里注意,如果你下载的是OpenCV2.x版本,这里的库文件比较多,都填进去就可以了。
到这里OpenCV的所有安装部署就结束了,可以进行下一步的使用和学习了。
参考链接:https://blog.csdn.net/maizousidemao/article/details/81474834
OpenCV Tutorials
https://docs.opencv.org/master/d9/df8/tutorial_root.html
版本3.4.7,4.0版本缺少了一些训练用的exe文件。。
1、 准备正负样本
最好为1:3。
正样本

最好自己拍,让物体占满整个画面,这样就不用后续去裁剪。Opencv有个opencv_annotations.exe的接口用于标记物体在图像中的位置(如在命令行
opencv_annotations -a=F:\test\Project1\Project1\annotations.txt -i=F:\test\Project1\Project1\fortest
,-a要生成的描述文件,-i负样本路径),不过不好用,因为后续还需要对正样本进行缩小,加快训练速度。缩小后位置就变化了。白做。缩小后再标记不现实,太小了不好标记。
所以最好让物体占满整个画面,就不需要进行标记或裁剪,后面说原因。
如何是要识别固定的物体,比如商标之类的,目标不存在太多变化,可以用一张图片通过各种扭曲生成多个正样本。CD进入图片文件夹中,命令行输入:
opencv_createsamples -vec pos.vec -num 1000 -w 30 -h 30 -bg neg.txt -img C:\obeject_detetion\xsamples\pos_1\0.jpg
-vec 要生成的vec文件
-num要生成的样本数
-w、-h 要生成样本的宽和高
-bg 背景文件的描述文件目录(不能用绝对路径,会出错,把该文件放在正样本同一目录下)
-img 使用的一张正样本(用于扭曲生成多个正样本)
负样本

[图片上传中...(image.png-3cc16c-1577779623303-0)]
负样本比较随意,只需要是与检测场景相关就好。
2、对样本进行预处理
分别对正负样本进行灰度化处理,其中正样本还需要进行缩放处理。如缩小为4040,加快训练进度。灰度化处理可以使检测效果更好,因为检测时读取的每帧图像也都要进行灰度化。
处理后如图所示
正样本

每张都是4040
负样本

大小不需要统一
一个对图片进行灰度化和缩放的C++程序,也可以用一些软件来完成,如ACDsee,PS等。
#include <iostream>
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
using namespace cv;
using namespace std;
int main(int argc, char *argv[])
{
//const char* filename = argc >= 2 ? argv[1] : "./posresize/1.jpg";
//string strInFileName = parser.get<String>("image");
vector<String> filenames;
String folder = "F:\\程序\\obeject_detetion(C)\\xsamples\\pos"; //要处理的图片目录
glob(folder, filenames);
cout << filenames.size() << endl;
for (size_t i = 0; i < filenames.size(); ++i)
{
//cout << filenames[i] << endl;
string str = filenames[i].substr(folder.length()-1);
//cout << str<< endl;
Mat src = imread(filenames[i], IMREAD_COLOR);
if (src.empty())
{
printf(" Error opening image\n");
cout << filenames[i] << endl; //printf(" Usage:\n %s [image_name-- default lena.jpg] \n", argv[0]);
return EXIT_FAILURE;
}
Mat gray;
cvtColor(src, gray, COLOR_BGR2GRAY); //灰度化
resize(gray, gray, Size(30, 30), 0, 0, INTER_LINEAR); //缩放处理,负样本不需要
imwrite("F:\\程序\\obeject_detetion(C)\\xsamples\\pos_1\\"+to_string(i)+".jpg", gray);//处理后的图片存放目录
}
return 0;
}
或者拍一段视频,获取对每一帧图片作为样本。
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/video.hpp>
#include "opencv2/imgcodecs.hpp"
using namespace cv;
using namespace std;
int main(int argc, char **argv) //把视频每一帧保存为图片
{
const string keys =
"{ h help | | print this help message }"
"{ @image |M4.mp4| path to image file }"; //要处理的视频目录
CommandLineParser parser(argc, argv, keys);
if (parser.has("help"))
{
parser.printMessage();
return 0;
}
string filename = parser.get<string>("@image");
if (!parser.check())
{
parser.printErrors();
return 0;
}
VideoCapture capture(filename);
if (!capture.isOpened()){
//error in opening the video input
cerr << "Unable to open file!" << endl;
return 0;
}
/*Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0,
-1, 5, -1,
0, -1, 0);
namedWindow("Input", WINDOW_AUTOSIZE);
namedWindow("Output", WINDOW_AUTOSIZE);*/
Mat frame;
// Take first frame and find corners in it
int i = 0;
capture >> frame;
while (!frame.empty())
{
/*imshow("frame", frame);
waitKey();*/
//cvtColor(frame, frame, COLOR_BGR2GRAY);
//resize(frame, frame, Size(100, 100), 0, 0, INTER_LINEAR);
/*imshow("Input", frame);
GaussianBlur(frame, frame,Size(5,5),1.5);
filter2D(frame, frame, frame.depth(), kernel);
imshow("Output", frame);
waitKey();*/
static int j = 0;
j++;
if (j > 5) //每隔几帧保存一次
{
imwrite("./videoresult/" + to_string(i++) + ".jpg", frame);//保存目录
j = 0;
}
capture >> frame;
}
return 0;
}
3、生成正负样本描述文件
然后在命令行下 CD 进入正负样本路径下,分别执行
dir /b/s/p/w *.jpg > pos.txt
dir /b/s/p/w *.jpg > neg.txt
如图
正样本描述文件

然后把所有jpg 替换成jpg 1 0 0 40 40,也就是在每一行最后加上 1 0 0 40 40(1物体,x左上角x坐标, y左上角y坐标, w宽, h高)也就是物体所在的矩形位置。因为整个画面都是物体,只有一个物体,而且每一张大小都是40*40,所以是1 0 0 40 40。如图

负样本描述文件

负样本不需要做任何替换。
4、生成正样本的vec文件
命令行下使用命令cd进入正样本目录下后,
opencv_createsamples -info pos.txt -vec pos.vec -num 4200 -w 30 -h 30
(-info 正样本描述文件,-vec 要生成的vec文件,-num要生成的正样本数, -w生成样本的宽,-h生成样本的高)宽和高要和预处理的w,h对应。
如果报错OpenCV(3.4.7) Error: Assertion failed (0 <= roi.x && 0 <= roi.width &,说明有部分图片不是和-w -h对应,好好检查一下是哪些图片,改
5、训练
命令行下
opencv_traincascade -data C:\obeject_detetion\newsamples\classfier -vec C:\obeject_detetion\newsamples\pos2_1\pos.vec -bg C:\obeject_detetion\newsamples\neg_1\neg.txt -w 30 -h 30 -precalcValBufSize 16384 -precalcIdxBufSize 16384 -maxFalseAlarmRate 0.1 -minHitRate 0.999 -mode ALL -numStages 10 -maxWeakCount 200 -numPos 2950 -numNeg 5100
(要替换成自己的路径,参数什么的)
-data 生成的分类器的目录
-vec 上一步4中生成的vec文件目录
-bg 负样本描述文件目录
-numPos 每一阶段使用的正样本数(越多效果越好)
-numNeg 每一阶段使用的负样本数(和正样本数1:3最好,或者1:4)
-w 样本的宽
-h 样本的高
-precalcValBufSize 分配给训练中每阶段中每样本的内存,越大训练越快,但不能太大,不然会报内存不足的错误,因numPos和numNeg太大引起内存不足报错就减小该参数,不报错前提下越大越好
-precalcIdxBufSize 分配给训练中每阶段中每样本的内存,越大训练越快,但不能太大,不然会报内存不足的错误,因numPos和numNeg太大引起内存不足报错就减小该参数,不报错前提下越大越好,两个加起来不能超过电脑内存
-numStages 训练的阶段数,默认20,太多会过拟合,一般13左右就差不多了
-maxFalseAlarmRate 每一阶段负样本被误判的最大错误率,越小越好,不过训练越久
-minHitRate 每一阶段正样本被正确识别的最小正确率,越大越好,不过训练越久,默认0.995,一般不用设置,设置后-numpos不能设置为全部正样本数,会报数说不正样本数不够。。
-mode 训练使用的特征,默认BASIC只使用垂直的特征,ALL使用垂直和旋转45度的特征,效果更好,不过训练越久。
接下来就是等待训练完成了


N为迭代次数,HR为最小正确率,FA为最大错误率,HR和FA分别达到设置的数值后进入下一阶段,等全部阶段都训练完或许提前收敛了就会生成一个.xml的分类器文件,然后就可以用来识别啦!
如果到后面阶段卡住了,负样本加载很慢,是因为错误率已经很低了,或者负样本不够了,这时也可以提前结束训练,Ctrl+C结束, 然后再次输入训练命令,修改-numStages,比如在第5阶段卡住了,那就修改为-numStages 5,然后就会生成一个5层的分类器。
网友评论