本教程将向您展示如何使用神经网络来提高色卡检测算法的准确性。
构建
构建OpenCV时,运行以下命令以构建所有contrib模块:
cmake -D OPENCV_EXTRA_MODULES_PATH=<opencv_contrib>/modules/
或者只构建mcc模块:
cmake -D OPENCV_EXTRA_MODULES_PATH=<opencv_contrib>/modules/mcc
或者确保在CMake的GUI版本中选中mcc模块:cmake-gui。
示例源码
您可以通过执行以下命令运行示例代码:
<opencv_build_directory>/bin/example_mcc_chart_detection_with_network -t=<色卡类型> -m=<神经网络路径> -pb=<模型pbtxt路径> -v=<可选视频路径,未提供则使用网络摄像头.mp4> --ci=<可选摄像头ID,仅在未提供视频时需要> --nc=<可选图像中色卡最大数量> --use_gpu <可选是否使用GPU>
``'
* -t=# 色卡类型,0(标准),1(DigitalSG),2(乙烯基)
* --ci=# 摄像头ID,0(默认为主摄像头),1(次摄像头)等
* --nc=# 默认值为1,表示只检测最佳色卡
示例
在CPU上简单运行(不使用GPU):/home/opencv/build/bin/example_mcc_chart_detection_with_network -t=0 -m=/home/model.pb –pb=/home/model.pbtxt -v=mcc24.mp4
在GPU上运行:/home/opencv/build/bin/example_mcc_chart_detection_with_network -t=0 -m=/home/model.pb –pb=/home/model.pbtxt -v=mcc24.mp4 –use_gpu
在GPU上运行并检测最佳5个色卡(检测结果可能少于5个,但不会超过5个):/home/opencv/build/bin/example_mcc_chart_detection_with_network -t=0 -m=/home/model.pb –pb=/home/model.pbtxt -v=mcc24.mp4 –use_gpu –nc=5
12const char *about =
"使用神经网络进行基本色卡检测";
14 "{ help h usage ? | | 显示此消息 }"
15 "{t | 0 | chartType: 0-标准, 1-DigitalSG, 2-乙烯基, 默认:0}"
16 "{m | | 模型文件路径,如果您没有模型,可以在文档中找到链接}"
18 "{pb | | pbtxt 文件路径,与模型文件一起提供}"
20 "{v | | 视频文件输入,如果省略,则输入来自摄像头}"
21 "{ci | 0 | 如果输入不是来自视频 (-v),则为摄像头 ID}"
22 "{nc | 1 | 图像中色卡的最大数量}"
23 "{use_gpu | | 如果要使用GPU,请添加此标志}"};
25int main(
int argc,
char *argv[])
34 if (parser.has(
"help"))
36 parser.printMessage();
40 int t = parser.get<
int>(
"t");
43 TYPECHART chartType = TYPECHART(t);
45 string model_path = parser.get<
string>(
"m");
46 string pbtxt_path = parser.get<
string>(
"pb");
48 int camId = parser.get<
int>(
"ci");
49 int nc = parser.get<
int>(
"nc");
54 video = parser.get<
String>(
"v");
56 bool use_gpu = parser.has(
"use_gpu");
68 inputVideo.
open(video);
73 inputVideo.
open(camId);
92 if (!detector->setNet(net))
94 cout <<
"加载模型失败:终止" << endl;
98 while (inputVideo.
grab())
100 Mat image, imageCopy;
103 imageCopy = image.
clone();
106 if (!detector->process(image, chartType, nc,
true))
114 std::vector<Ptr<mcc::CChecker>> checkers = detector->getListColorChecker();
124 imshow(
"图像结果 | 按q或esc退出", image);
125 imshow(
"原始图像", imageCopy);
126 char key = (char)
waitKey(waitTime);
用于命令行解析。
定义 utility.hpp:890
CV_NODISCARD_STD Mat clone() const
创建数组和底层数据的完整副本。
用于从视频文件、图像序列或摄像头捕获视频的类。
定义 videoio.hpp:766
virtual bool open(const String &filename, int apiPreference=CAP_ANY)
打开视频文件或捕获设备或IP视频流进行视频捕获。
virtual bool retrieve(OutputArray image, int flag=0)
解码并返回抓取的视频帧。
virtual bool grab()
从视频文件或捕获设备抓取下一帧。
此类允许创建和操作全面的人工神经网络。
定义 dnn.hpp:475
void setPreferableBackend(int backendId)
要求网络使用支持的特定计算后端。
void setPreferableTarget(int targetId)
要求网络在特定目标设备上进行计算。
std::string String
定义 cvstd.hpp:151
std::shared_ptr< _Tp > Ptr
定义 cvstd_wrapper.hpp:23
#define CV_Assert(expr)
在运行时检查条件,如果失败则抛出异常。
定义 base.hpp:359
Net readNetFromTensorflow(CV_WRAP_FILE_PATH const String &model, CV_WRAP_FILE_PATH const String &config=String())
读取以TensorFlow框架格式存储的网络模型。
void imshow(const String &winname, InputArray mat)
在指定的窗口中显示图像。
int waitKey(int delay=0)
等待按键按下。
int main(int argc, char *argv[])
定义 highgui_qt.cpp:3
解释
设置头文件和命名空间
如果需要,您可以像上面的代码一样设置命名空间。
创建检测器对象
这只是创建对象。
加载模型
加载模型,这里提供的模型是用TensorFlow训练的,所以我们用TensorFlow加载它,但如果您有在其他框架中训练的其他模型,也可以使用。
(可选) 将DNN后端设置为CUDA
模型在CUDA上运行速度快得多,所以如果可能,请使用CUDA。
运行检测器
detector->process(image, chartType, max_number_charts_in_image, true);
如果检测器成功检测到至少一个图表,则返回true,否则返回false。在上面给出的代码中,如果未检测到任何图表,我们将打印一条失败消息。否则,如果成功,颜色图表列表将存储在检测器本身中,我们将在下一步中看到如何提取它。第四个参数用于决定是否使用网络。
获取颜色校正板列表
std::vector<cv::Ptr<mcc::CChecker>> checkers;
detector->getListColorChecker(checkers);
所有检测到的颜色校正板现在都存储在“checkers”向量中。
将颜色校正板绘制回图像
逐个循环遍历所有校正板,然后绘制它们。