diff --git "a/OpenCV/OpenCV 4.5.2 \345\217\221\345\270\203-2021-04-06.md" "b/OpenCV/OpenCV 4.5.2 \345\217\221\345\270\203-2021-04-06.md" new file mode 100644 index 0000000000000000000000000000000000000000..c5307badca56035b205607eeb500fa0dcbc57134 --- /dev/null +++ "b/OpenCV/OpenCV 4.5.2 \345\217\221\345\270\203-2021-04-06.md" @@ -0,0 +1,81 @@ +**春季更新OpenCV 4.5.2发布了!** + +来看看4.5.2都有哪些重要改进: + +- **core模块**:增加并行后端的支持。特殊编译的OpenCV可以允许选择并行后端,并/或通过plugin动态载入。 +- **imgpro模块**:增加智能剪刀功能(如下演示)。CVAT标注工具已经集成此功能,可在线体验https://cvat.org。 + +- **videoio模块**:改进硬件加速的视频编解码任务。从4.5.2开始,新的内置属性让用户更容易使用API + +``` +VideoCapture capture(filename, CAP_FFMPEG, + { + CAP_PROP_HW_ACCELERATION, VIDEO_ACCELERATION_ANY, + } +); +``` + +- **DNN模块:** + +- - 改进TensorFlow解析错误的调试 + + - 改进layers和activations,支持更多模型 + + - - 优化NMS处理、DetectionOutput + - 修复Div with constant、MatMul、Reshape(TensorFlow) + - 支持Mish ONNX子图、NormalizeL2(ONNX)、LeakyReLU(TensorFlow)、TanH(Darknet)、SAM(Darknet)和Exp + + - 支持*OpenVINO* 2021.3 release支持 + +- **G-API模块:** + +- - Python支持 + + - - 引入新的Python后端:G-API可以运行Python的任意kernels作为pipeline的一部分 + - 扩展G-API Python绑定的推理支持 + - G-API Python绑定增加更多的图数据类型支持 + + - 推理支持 + + - - OpenVINO推理后端引入动态输入/CNN reshape功能 + - OpenVINO推理后端引入异步执行支持:推理可以在多个request并行运行以增加流密度/处理量 + - ONNX后端扩展对INT64/INT32数据类型的支持,OpenVINO后端扩展对INT32的支持 + - ONNX后端引入cv::GFrame/cv::MediaFrame和常量支持 + + - 媒体支持 + + - - 在绘制/渲染接口引入cv::GFrame/cv::Media支持 + - Streaming模式引入multi-stream输入支持以及帧同步以支持某些情况如Stereo + - 增加Y和UV操作以访问图级别cv::GFrame的NV12数据;若媒体格式不同,转换是同时的 + + - 运算符和核 + + - - 增加新操作(MorphologyEx, BoundingRect, FitLine, FindLine, FindContours, KMeans, Kalman, BackgroundSubtractor)的性能测试 + - 修复PlaidML后端的RMat输入支持 + - 增加Fluid AbsDiffC, AddWeighted和位操作的ARM NEON优化 + + - 其他静态分析和警告修复 + +- **文档:** + +- - [GSoC]增加TF和PyTorch分类转换案例 + - [GSoC]增加TF和PyTorch分割转换案例 + - [GSoC]增加TF和PyTorch检测转换案例 + +- **社区贡献:** + +- - core:增加带cuda stream标志的cuda::Stream构造函数 + - highgui:Win32上的OpenGL暴露VSYNC窗口属性 + - highgui:Win32上的pollKey()实现 + - imgcodecs:增加PNG的Exif解析 + - imgcodecs:OpenEXR压缩类型可选 + - imgproc:优化connectedComponents + - videoio:Android NDK摄像头支持 + - (opencv_contrib):腾讯微信QR码识别模块 + - (opencv_contrib):实现cv::cuda::inRange() + - (opencv_contrib):增加Edge Drawing Library中的算法 + - (opencv_contrib):Viz模块增加Python绑定 + +更多详细信息请参考: + +https://github.com/opencv/opencv/wiki/ChangeLog#version452 \ No newline at end of file diff --git "a/OpenCV/OpenCV\344\270\255\345\215\225\347\233\256\346\240\207\350\267\237\350\270\252\347\256\227\346\263\225DaSiamRPN\347\232\204C++\345\256\236\347\216\260-2021-03-09.md" "b/OpenCV/OpenCV\344\270\255\345\215\225\347\233\256\346\240\207\350\267\237\350\270\252\347\256\227\346\263\225DaSiamRPN\347\232\204C++\345\256\236\347\216\260-2021-03-09.md" new file mode 100644 index 0000000000000000000000000000000000000000..19dcfbfa31eeafec01d292b27aba62e0ea91848a --- /dev/null +++ "b/OpenCV/OpenCV\344\270\255\345\215\225\347\233\256\346\240\207\350\267\237\350\270\252\347\256\227\346\263\225DaSiamRPN\347\232\204C++\345\256\236\347\216\260-2021-03-09.md" @@ -0,0 +1,114 @@ +单目标跟踪是计算机视觉中的一个基本问题。在如今深度学习时代也涌现出多种基于深度学习的单目标跟踪算法,其中基于SiamFC(双流网络)的单目标跟踪算法占据了半壁江山。DaSiamRPN就是典型的基于SiamFC的方法。 + +GSoC 2020为OpenCV增加了Python版本的DaSiamRPN,后来发现大家对C++版本的需求挺强烈的,于是我就为OpenCV贡献了一个C++版本的DaSiamRPN。 + +对于DaSiamRPN,在inference阶段,模型的主要结构如下图所示: + +![](./imgs/24.jpg) + +其中**黄色的CNN网络**和**橙色的Conv网络**是模型文件,DaSiamRPN最后的输出有两个分别为分类分支:17 x 17 x 2k 和 回归分支:17 x 17 x 4k。 + +在实际代码中我们将上图中的模型整合成三个模型:siamRPN,siamKernelCL1,siamKernelR1。其中siamRPN是主要模型,会在每一帧的跟踪中用到,而siamKernelCL1和siamKernelR1仅会在设定模板参数时用到。注意:图中的两个黄色的CNN是公用参数的,详细介绍请看原文[1]。 + +C++版本使用了与Python版本同样的逻辑和模型文件,下面简单介绍一下实现的主要逻辑。 + +在单目标跟踪中,首先需要设定模板参数,如以下代码所示: + +``` +siamRPN.setInput(blob); // blob 为输入的template +Mat out1; +siamRPN.forward(out1, "63"); // 63层的输出为文中描述的黄色CNN的输出 +siamKernelCL1.setInput(out1); // 分别作为回归和分类分支的输入 +siamKernelR1.setInput(out1); + +Mat cls1 = siamKernelCL1.forward(); // 获取模板分类分支的特征 +Mat r1 = siamKernelR1.forward(); // 获取模板回归分支的特征 +std::vector r1_shape = { 20, 256, 4, 4 }, cls1_shape = { 10, 256, 4, 4 }; + +siamRPN.setParam(siamRPN.getLayerId("65"), 0, r1.reshape(0, r1_shape)); // 将获取到的参数写入主模型 +siamRPN.setParam(siamRPN.getLayerId("68"), 0, cls1.reshape(0, cls1_shape)); +``` + +设定模板参数之后进入跟踪主循环: + +``` +// 主循环 +for (int count = 0; ; ++count) +{ + cap >> image; + // ... + float score = trackerEval(image, trackState, siamRPN); // 每一帧的跟踪计算 + + // 绘制图像 + Rect rect = { + int(trackState.targetBox.x - int(trackState.targetBox.width / 2)), + int(trackState.targetBox.y - int(trackState.targetBox.height / 2)), + int(trackState.targetBox.width), + int(trackState.targetBox.height) + }; + + Mat render_image = image.clone(); + rectangle(render_image, rect, Scalar(0, 255, 0), 2); + // ... + imshow(winName, render_image); + + int c = waitKey(1); + if (c == 27 /*ESC*/) + break; +} +``` + +其中上述的`trackerEval`函数即为跟踪目标的计算,主体如下所示: + +``` +float trackerEval(Mat img, trackerConfig& trackState, Net& siamRPN) +{ + // 第一步:确认搜索区域。跟踪算法根据前一帧中目标位置确定搜索区域 + float searchSize = float((trackState.instanceSize - trackState.exemplarSize) / 2); + float pad = searchSize / scaleZ; + float sx = sz + 2 * pad; + + Mat xCrop = getSubwindow(img, targetBox, (float)cvRound(sx), trackState.avgChans); + + static Mat blob; + std::vector outs; + std::vector outNames; + Mat delta, score; + Mat sc, rc, penalty, pscore; + + // 第二步:用siamRPN网络推理 + blobFromImage(xCrop, blob, 1.0, Size(trackState.instanceSize, trackState.instanceSize), Scalar(), trackState.swapRB, false, CV_32F); + + siamRPN.setInput(blob); + + outNames = siamRPN.getUnconnectedOutLayersNames(); + siamRPN.forward(outs, outNames); + + delta = outs[0]; + score = outs[1]; + // score 和 delta即为文章开头结构图中的两个输出矩阵 + score = score.reshape(0, { 2, trackState.anchorNum, trackState.scoreSize, trackState.scoreSize }); + delta = delta.reshape(0, { 4, trackState.anchorNum, trackState.scoreSize, trackState.scoreSize }); + // 第三步:后处理 + // ...太长,这里省略 + return score.at(bestID); // 返回最好的跟踪框 +} +``` + +运行效果: + +![](./imgs/25.png) + +算法存在的问题:模型训练集中包含的小物体较少,该算法在目标为小物体情况下的性能较弱,只能重新训练解决这个问题。 + +全部代码请参考: + +https://github.com/opencv/opencv/blob/master/samples/dnn/dasiamrpn_tracker.cpp + +参考资料: + +1. 原始论文:https://arxiv.org/abs/1808.06048 + +2. 原始PyTorch实现:https://github.com/foolwood/DaSiamRPN + +3. OpenCV中Python实现:https://github.com/opencv/opencv/blob/master/samples/dnn/dasiamrpn_tracker.py \ No newline at end of file diff --git "a/OpenCV/OpenCV\344\270\255\347\232\204\345\271\266\350\241\214\350\256\241\347\256\227parallel_for_(1)-2021-04-07.md" "b/OpenCV/OpenCV\344\270\255\347\232\204\345\271\266\350\241\214\350\256\241\347\256\227parallel_for_(1)-2021-04-07.md" new file mode 100644 index 0000000000000000000000000000000000000000..28a0f98bb60efc2e0b50a57e4c134a6b54c9dcbe --- /dev/null +++ "b/OpenCV/OpenCV\344\270\255\347\232\204\345\271\266\350\241\214\350\256\241\347\256\227parallel_for_(1)-2021-04-07.md" @@ -0,0 +1,167 @@ +OpenCV中的parallel_for_为用户提供了快速并行化代码的途径。 + +先来看一个用parallel_for_并行化矩阵相乘的简单例子。这个例子是对输入为128x128x32进行核为3x3x64的卷积操作。 + +直接计算的代码如下: + +``` +void conv3x3(const Mat& inp, const Mat& weights, Mat& out) +{ + int out_cn = weights.size[0]; + int inp_cn = weights.size[1]; + int kh = weights.size[2], kw = weights.size[3]; + int inp_h = inp.size[1], inp_w = inp.size[2]; + int out_h = inp_h - kh + 1, out_w = inp_w - kw + 1; + int size[] = {out_cn, out_h, out_w}; + + CV_Assert( inp.size[0] == inp_cn && kw == 3 && kh == 3 ); + + out.create(3, size, CV_32F); + + for( int oc = 0; oc < out_cn; oc++ ) + for( int y = 0; y < out_h; y++ ) + { + int iidx[] = { 0, y, 0 }; + int widx[] = { oc, 0, 0, 0 }; + int oidx[] = { oc, y, 0 }; + + const float* iptr0 = inp.ptr(iidx); // &inp[0, y, 0] + const float* wptr0 = weights.ptr(widx); // &weights[oc, 0, 0, 0] + float* optr = out.ptr(oidx); // &out[oc, y, 0] + + for( int x = 0; x < out_w; x++ ) + { + float sum = 0.f; + for( int ic = 0; ic < inp_cn; ic++ ) + { + const float* iptr = iptr0 + x + ic*(inp_h*inp_w); // &inp[ic, y, x] + const float* wptr = wptr0 + ic*(kw*kh); // &weights[oc, ic, 0, 0] + + sum += iptr[0]*wptr[0] + iptr[1]*wptr[1] + iptr[2]*wptr[2] + + iptr[inp_w]*wptr[3] + iptr[inp_w+1]*wptr[4] + iptr[inp_w+2]*wptr[5] + + iptr[inp_w*2]*wptr[6] + iptr[inp_w*2+1]*wptr[7] + iptr[inp_w*2+2]*wptr[8]; + } + optr[x] = sum; + } + } +} +``` + +使用parallel_for_进行并行计算的代码如下: + +``` +void conv3x3_parallel(const Mat& inp, const Mat& weights, Mat& out) +{ + int out_cn = weights.size[0]; + int inp_cn = weights.size[1]; + int kh = weights.size[2], kw = weights.size[3]; + int inp_h = inp.size[1], inp_w = inp.size[2]; + int out_h = inp_h - kh + 1, out_w = inp_w - kw + 1; + int size[] = {out_cn, out_h, out_w}; + + CV_Assert( inp.size[0] == inp_cn && kw == 3 && kh == 3 ); + + out.create(3, size, CV_32F); + + // 用parallel_for_按ch进行并行计算 + parallel_for_(Range(0, out_cn), [&](const Range& r) + { + for( int oc = r.start; oc < r.end; oc++ ) + for( int y = 0; y < out_h; y++ ) + { + int iidx[] = { 0, y, 0 }; + int widx[] = { oc, 0, 0, 0 }; + int oidx[] = { oc, y, 0 }; + + const float* iptr0 = inp.ptr(iidx); // &inp[0, y, 0] + const float* wptr0 = weights.ptr(widx); // &weights[oc, 0, 0, 0] + float* optr = out.ptr(oidx); // &out[oc, y, 0] + + for( int x = 0; x < out_w; x++ ) + { + float sum = 0.f; + for( int ic = 0; ic < inp_cn; ic++ ) + { + const float* iptr = iptr0 + x + ic*(inp_h*inp_w); // &inp[ic, y, x] + const float* wptr = wptr0 + ic*(kw*kh); // &weights[oc, ic, 0, 0] + + sum += iptr[0]*wptr[0] + iptr[1]*wptr[1] + iptr[2]*wptr[2] + + iptr[inp_w]*wptr[3] + iptr[inp_w+1]*wptr[4] + iptr[inp_w+2]*wptr[5] + + iptr[inp_w*2]*wptr[6] + iptr[inp_w*2+1]*wptr[7] + iptr[inp_w*2+2]*wptr[8]; + } + optr[x] = sum; + } + } + }); +} +``` + +来运行一下 + +``` +int main(int argc, char** argv) +{ + const int inp_h = 128, inp_w = 128, inp_cn = 32; + const int out_cn = 64; + const int kh = 3, kw = 3; + + Mat inp, w, out_ref, out_curr; + gen_inp(inp_cn, inp_h, inp_w, inp); + gen_weights(out_cn, inp_cn, kh, kw, w); + + conv3x3(inp, w, out_ref); + conv3x3(inp, w, out_curr); + double t = (double)getTickCount(); + conv3x3(inp, w, out_curr); + t = (double)getTickCount() - t; + + double t2 = (double)getTickCount(); + conv3x3_parallel(inp, w, out_curr); + t2 = (double)getTickCount() - t2; + + printf("conv3x3 time = %.1fms\n", t * 1000 / getTickFrequency()); + printf("conv3x3_parallel time = %.1fms\n", t2 * 1000 / getTickFrequency()); + + return 0; +} +``` + +conv3x3和conv3x3_parallel在我的笔记本电脑上运行时间对比如下: + +![](./imgs/7.png) + +对比conv3x3和conv3x3_parallel的内部实现,基本相同,只是conv3x3_parallel代码中多了一句用parallel_for_按照输出通道的数量进行并行计算。parallel_for_根据用户计算机上的并行框架在其内部完成了代码的并行化,非常简便易用! + +使用parallel_for_的一个前提条件是OpenCV需要与并行框架一起编译。OpenCV中支持以下并行框架,并按照下面的顺序选取进行处理: + +- Intel TBB (第三方库,需显式启用) +- C=并行C/C++编程语言扩展 (第三方库,需显式启用) +- OpenMP (编译器集成, 需显式启用) +- APPLE GCD (苹果系统自动使用) +- Windows RT并发(Windows RT自动使用) +- Windows并发(运行时部分, Windows,MSVC++ >= 10自动使用) +- Pthreads + +在刚发布的[OpenCV 4.5.2版本](http://mp.weixin.qq.com/s?__biz=MjM5NTE3NjY5MA==&mid=2247485520&idx=1&sn=fbdcafdbdecb75cb327cbc91f280960d&chksm=a6fdc1cd918a48dbcd156126656c8c6a5c29618bf57669d1d5045573b3d7cc6e911b978967e6&scene=21#wechat_redirect),增加了支持并行框架的选择。特殊编译的OpenCV可以允许选择并行后端,并/或通过plugin动态载入。如: + +``` +# TBB plugin +cd plugin_tbb +cmake /modules/core/misc/plugins/parallel_tbb +cmake --build . --config Release + +# OpenMP plugin +cd plugin_openmp +cmake /modules/core/misc/plugins/parallel_openmp +cmake --build . --config Release +``` + +第二个条件是所要完成的计算任务是适宜并可以进行并行化的。简言之,可以分解成多个子任务并且没有内存依赖的就容易并行化。例如,对一个像素的处理并不与其他像素的处理冲突,计算机视觉相关的任务多数情况下容易进行并行化。 + +参考资料: + +[1] https://docs.opencv.org/master/d7/dff/tutorial_how_to_use_OpenCV_parallel_for_.html + +[2] https://github.com/opencv/opencv/wiki/ChangeLog + +[3] https://github.com/opencv/opencv/pull/19470 \ No newline at end of file diff --git a/OpenCV/README.md b/OpenCV/README.md new file mode 100644 index 0000000000000000000000000000000000000000..11850cb5c13abf12146d0e989e6b7755bcc40617 --- /dev/null +++ b/OpenCV/README.md @@ -0,0 +1,19 @@ +# OpenCV_技术文章 + +企业技术文章精选,**觉得不错的话别忘了点个Star哈**。 + +计划每天更新,欢迎大家一起来完善,也欢迎大家成为贡献者,有什么问题可以直接私信我或者提Issue + +**有文章投稿的欢迎哈,我这边可以帮忙内推CSDN公众号等渠道** + +**微信联系方式,搜索:mynamemao** + +**2021-05-25新增**[用OpenCV实现条形码识别-2021-04-22](./用OpenCV实现条形码识别-2021-04-22.md) + +**2021-05-25新增**[OpenCV中的并行计算parallel_for_(1)-2021-04-07](./OpenCV中的并行计算parallel_for_(1)-2021-04-07.md) + +**2021-05-25新增**[OpenCV 4.5.2 发布-2021-04-06](./OpenCV 4.5.2 发布-2021-04-06.md) + +**2021-05-25新增**[用OpenCV实现超轻量的NanoDet目标检测模型-2021-03-17](./用OpenCV实现超轻量的NanoDet目标检测模型-2021-03-17.md) + +**2021-05-25新增**[OpenCV中单目标跟踪算法DaSiamRPN的C++实现-2021-03-09](./OpenCV中单目标跟踪算法DaSiamRPN的C++实现-2021-03-09.md) \ No newline at end of file diff --git a/OpenCV/imgs/1.png b/OpenCV/imgs/1.png new file mode 100644 index 0000000000000000000000000000000000000000..7c127b5a90d6065041ee9e89d4d48218e9338db4 Binary files /dev/null and b/OpenCV/imgs/1.png differ diff --git a/OpenCV/imgs/10.jpg b/OpenCV/imgs/10.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7a68321f34bc9853c18815ec0df1b4c5d0ecee34 Binary files /dev/null and b/OpenCV/imgs/10.jpg differ diff --git a/OpenCV/imgs/10.webp b/OpenCV/imgs/10.webp new file mode 100644 index 0000000000000000000000000000000000000000..6abf68f5b5b199dce91e3670e8e9dcb007e4aacf Binary files /dev/null and b/OpenCV/imgs/10.webp differ diff --git a/OpenCV/imgs/11.jpg b/OpenCV/imgs/11.jpg new file mode 100644 index 0000000000000000000000000000000000000000..277ab14c958ac573544dd7c236a785e2e02ecf0b Binary files /dev/null and b/OpenCV/imgs/11.jpg differ diff --git a/OpenCV/imgs/11.webp b/OpenCV/imgs/11.webp new file mode 100644 index 0000000000000000000000000000000000000000..7f1e368e2ee2fcc6e018266c43f73116504b12c3 Binary files /dev/null and b/OpenCV/imgs/11.webp differ diff --git a/OpenCV/imgs/12.jpg b/OpenCV/imgs/12.jpg new file mode 100644 index 0000000000000000000000000000000000000000..df7e13d2b53f9ef1c40a3a008a36f3cab008b016 Binary files /dev/null and b/OpenCV/imgs/12.jpg differ diff --git a/OpenCV/imgs/12.webp b/OpenCV/imgs/12.webp new file mode 100644 index 0000000000000000000000000000000000000000..6749f0c614eaf9d599846a0975102385744205ca Binary files /dev/null and b/OpenCV/imgs/12.webp differ diff --git a/OpenCV/imgs/13.jpg b/OpenCV/imgs/13.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c2c20764108d2e24ee262d8c62ea4d2a32f4e212 Binary files /dev/null and b/OpenCV/imgs/13.jpg differ diff --git a/OpenCV/imgs/13.webp b/OpenCV/imgs/13.webp new file mode 100644 index 0000000000000000000000000000000000000000..671299d65ae9ef206fbd2054ea405fc32f98cf8a Binary files /dev/null and b/OpenCV/imgs/13.webp differ diff --git a/OpenCV/imgs/14.jpg b/OpenCV/imgs/14.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d13ae0fe8aed1c9c87da1d12a72bebf7acb0adb5 Binary files /dev/null and b/OpenCV/imgs/14.jpg differ diff --git a/OpenCV/imgs/14.webp b/OpenCV/imgs/14.webp new file mode 100644 index 0000000000000000000000000000000000000000..0f7d4706e548db5b23b396e3230664e67972ae59 Binary files /dev/null and b/OpenCV/imgs/14.webp differ diff --git a/OpenCV/imgs/15.jpg b/OpenCV/imgs/15.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3824e48e4de3b386188732ffd1618aa5bb64037b Binary files /dev/null and b/OpenCV/imgs/15.jpg differ diff --git a/OpenCV/imgs/15.webp b/OpenCV/imgs/15.webp new file mode 100644 index 0000000000000000000000000000000000000000..c6874b7c269d8057c3c088b871ce468b2200a0db Binary files /dev/null and b/OpenCV/imgs/15.webp differ diff --git a/OpenCV/imgs/16.jpg b/OpenCV/imgs/16.jpg new file mode 100644 index 0000000000000000000000000000000000000000..62b2690f90bea586de7e03dda0de663fad2b6c43 Binary files /dev/null and b/OpenCV/imgs/16.jpg differ diff --git a/OpenCV/imgs/16.webp b/OpenCV/imgs/16.webp new file mode 100644 index 0000000000000000000000000000000000000000..0c1b7740deb592799548125498d215d072fb3c0a Binary files /dev/null and b/OpenCV/imgs/16.webp differ diff --git a/OpenCV/imgs/17.jpg b/OpenCV/imgs/17.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5692c10c628092cea4b601c33a253db38b622531 Binary files /dev/null and b/OpenCV/imgs/17.jpg differ diff --git a/OpenCV/imgs/17.webp b/OpenCV/imgs/17.webp new file mode 100644 index 0000000000000000000000000000000000000000..6a937000ad31c6097f8da7df16eefd134ebbc3c8 Binary files /dev/null and b/OpenCV/imgs/17.webp differ diff --git a/OpenCV/imgs/18.jpg b/OpenCV/imgs/18.jpg new file mode 100644 index 0000000000000000000000000000000000000000..793f0b6e711573e742249a4cf40350b884f5f9bd Binary files /dev/null and b/OpenCV/imgs/18.jpg differ diff --git a/OpenCV/imgs/18.webp b/OpenCV/imgs/18.webp new file mode 100644 index 0000000000000000000000000000000000000000..dd2d280442cdebfea89e7c7b3f418e43d00e4707 Binary files /dev/null and b/OpenCV/imgs/18.webp differ diff --git a/OpenCV/imgs/19.jpg b/OpenCV/imgs/19.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6feef17eb7dd170f9017f24b2dad9fa5a5370c60 Binary files /dev/null and b/OpenCV/imgs/19.jpg differ diff --git a/OpenCV/imgs/19.webp b/OpenCV/imgs/19.webp new file mode 100644 index 0000000000000000000000000000000000000000..82f2d00cfd53e03d32ac8a399176777b85c5ca60 Binary files /dev/null and b/OpenCV/imgs/19.webp differ diff --git a/OpenCV/imgs/2.png b/OpenCV/imgs/2.png new file mode 100644 index 0000000000000000000000000000000000000000..7555198804d0b32a8902e44bf0058ca93b843705 Binary files /dev/null and b/OpenCV/imgs/2.png differ diff --git a/OpenCV/imgs/20.jpg b/OpenCV/imgs/20.jpg new file mode 100644 index 0000000000000000000000000000000000000000..aceb863c0146262de7019a03e53d6e0d48794c18 Binary files /dev/null and b/OpenCV/imgs/20.jpg differ diff --git a/OpenCV/imgs/20.webp b/OpenCV/imgs/20.webp new file mode 100644 index 0000000000000000000000000000000000000000..7b311c4acd0063f9678d1db9cba46433539608c6 Binary files /dev/null and b/OpenCV/imgs/20.webp differ diff --git a/OpenCV/imgs/21.jpg b/OpenCV/imgs/21.jpg new file mode 100644 index 0000000000000000000000000000000000000000..38274173dce6e15361a0f253f26caf55f143a7e8 Binary files /dev/null and b/OpenCV/imgs/21.jpg differ diff --git a/OpenCV/imgs/21.webp b/OpenCV/imgs/21.webp new file mode 100644 index 0000000000000000000000000000000000000000..4d0d8a8255c724c7e51d97aadb466900370e9acd Binary files /dev/null and b/OpenCV/imgs/21.webp differ diff --git a/OpenCV/imgs/22.jpg b/OpenCV/imgs/22.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ef801e7ce08f834e8c1935d241734a6d693c9afd Binary files /dev/null and b/OpenCV/imgs/22.jpg differ diff --git a/OpenCV/imgs/22.webp b/OpenCV/imgs/22.webp new file mode 100644 index 0000000000000000000000000000000000000000..7340862c1ac169af8558c4f2cfb173c49510544c Binary files /dev/null and b/OpenCV/imgs/22.webp differ diff --git a/OpenCV/imgs/23.jpg b/OpenCV/imgs/23.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f103c13feb1a46a75f98e1b5e2f699524083c3b4 Binary files /dev/null and b/OpenCV/imgs/23.jpg differ diff --git a/OpenCV/imgs/23.webp b/OpenCV/imgs/23.webp new file mode 100644 index 0000000000000000000000000000000000000000..593a00a85f750bd744b78bc0e8a207b046eb513f Binary files /dev/null and b/OpenCV/imgs/23.webp differ diff --git a/OpenCV/imgs/24.jpg b/OpenCV/imgs/24.jpg new file mode 100644 index 0000000000000000000000000000000000000000..827fed3f3002d199c1acf8f43f5d8b1204f723b5 Binary files /dev/null and b/OpenCV/imgs/24.jpg differ diff --git a/OpenCV/imgs/24.webp b/OpenCV/imgs/24.webp new file mode 100644 index 0000000000000000000000000000000000000000..0d29b965cb25f4d361bfe6bc58e4e8c450d264b7 Binary files /dev/null and b/OpenCV/imgs/24.webp differ diff --git a/OpenCV/imgs/25.png b/OpenCV/imgs/25.png new file mode 100644 index 0000000000000000000000000000000000000000..f6a91c02dcfa007185aa06ef5f5507e2a32e4270 Binary files /dev/null and b/OpenCV/imgs/25.png differ diff --git a/OpenCV/imgs/3.png b/OpenCV/imgs/3.png new file mode 100644 index 0000000000000000000000000000000000000000..14b8eeaa68b04d00b9c8a4643d2ab8c0b86d8e4c Binary files /dev/null and b/OpenCV/imgs/3.png differ diff --git a/OpenCV/imgs/4.png b/OpenCV/imgs/4.png new file mode 100644 index 0000000000000000000000000000000000000000..a26756adb62cb4dfc4a46e38a027100cb4078891 Binary files /dev/null and b/OpenCV/imgs/4.png differ diff --git a/OpenCV/imgs/5.png b/OpenCV/imgs/5.png new file mode 100644 index 0000000000000000000000000000000000000000..880e1a2b548de58f4e1fc4cbd60c3034120c6010 Binary files /dev/null and b/OpenCV/imgs/5.png differ diff --git a/OpenCV/imgs/6.png b/OpenCV/imgs/6.png new file mode 100644 index 0000000000000000000000000000000000000000..7b84f056607c07bec9ac83eb42e5d038a34a57b4 Binary files /dev/null and b/OpenCV/imgs/6.png differ diff --git a/OpenCV/imgs/7.png b/OpenCV/imgs/7.png new file mode 100644 index 0000000000000000000000000000000000000000..bf14c7c3316fd0c2635dd507392fda94a2bdf667 Binary files /dev/null and b/OpenCV/imgs/7.png differ diff --git a/OpenCV/imgs/8.jpg b/OpenCV/imgs/8.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a0ca988d7bfde79031e99df6429ac26e16e0e45e Binary files /dev/null and b/OpenCV/imgs/8.jpg differ diff --git a/OpenCV/imgs/8.webp b/OpenCV/imgs/8.webp new file mode 100644 index 0000000000000000000000000000000000000000..d0f629bef82ad390bab4d92ff799d8378761e6f5 Binary files /dev/null and b/OpenCV/imgs/8.webp differ diff --git a/OpenCV/imgs/9.jpg b/OpenCV/imgs/9.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9ae15592c8e0f7d52cc346ad080cdf7aa4f5353f Binary files /dev/null and b/OpenCV/imgs/9.jpg differ diff --git a/OpenCV/imgs/9.webp b/OpenCV/imgs/9.webp new file mode 100644 index 0000000000000000000000000000000000000000..e1ab07a24467b0bcd159470569c61297bd2b507e Binary files /dev/null and b/OpenCV/imgs/9.webp differ diff --git "a/OpenCV/\347\224\250OpenCV\345\256\236\347\216\260\346\235\241\345\275\242\347\240\201\350\257\206\345\210\253-2021-04-22.md" "b/OpenCV/\347\224\250OpenCV\345\256\236\347\216\260\346\235\241\345\275\242\347\240\201\350\257\206\345\210\253-2021-04-22.md" new file mode 100644 index 0000000000000000000000000000000000000000..d29aac2e6a6dff08aa5eec119599c2cfc63497c9 --- /dev/null +++ "b/OpenCV/\347\224\250OpenCV\345\256\236\347\216\260\346\235\241\345\275\242\347\240\201\350\257\206\345\210\253-2021-04-22.md" @@ -0,0 +1,97 @@ +作者:梁峻豪,王天麒,孙中夏 (南方科技大学计算机科学与工程系) + +最近,我们为OpenCV贡献了一维条形码识别模块,代码收录在: + +https://github.com/opencv/opencv_contrib/tree/master/modules/barcode。 + +我们收集的数据集(数据集地址:https://github.com/SUSTech-OpenCV/BarcodeTestDataset, + +共250张条码图片)上进行了测试,我们的识别算法正确率达到了96%,速度为20ms每张图像。作为对比,我们也测试了ZXing在该数据集上的表现,其正确率为64.4%,速度为90ms每张图像。 + +注:测试速度不包含初始化以及读图时间。同时,我们的算法是C++实现,ZXing是Java实现。另外,对于用图片数据集进行的测试,ZXing99%的时间是在做彩色图到灰度图的转换。 + +本文将对此模块的原理和使用方式进行介绍。 + +# 条形码介绍 + +条形码是将宽度不等的多个黑条和空白,按照一定的编码规则排列,用以表达一组信息的图形标识符,如下图所示: + +![](./imgs/1.png) + +条码区域与其他图像相比有如下两个重要特点:第一,条码区域内的条空是平行排列的,方向趋于一致;第二,为了条码的可识读性,条码在制作时条和空之间有着较大的反射率差,从而条码区域内的灰度对比度较大,而且边缘信息丰富。 + +# 基于方向一致性的条码定位算法 + +根据条形码方向趋于一致的特点,我们可以将图像分块,通过计算每个块内**梯度方向的一致性**,来滤除那些**低一致性**的块。下图是筛选过后剩下的块: + +![](./imgs/2.png) + +由于包含条码区域的块**一定连续存在**的特性,我们可以通过对这些图像块再进行一个改进的**腐蚀**操作过滤掉部分背景图像块。下图是滤除部分背景图像块后剩余的块: + +![](./imgs/3.png) + +得到这些块之后,我们再根据每个图像块内的**平均梯度方向进行连通**。因为如果是相邻的图像块都属于同一个条码的话,那么他们的平均梯度方向也一定相同。 + +得到连通区域之后我们再根据条码图像的特性进行筛选,比如连通区域内的梯度大于阈值的点的比例,组成连通区域的图像块数量等。 + +最后,用**最小外接矩形**去拟合每个连通区域,并计算外界矩形的方向是否和连通区域内的平均梯度方向一致,过滤掉差距较大的连通区域。将平均梯度方向作为矩形的方向,并将矩形作为最终的定位框。 + +![](./imgs/4.png) + +# 条形码解码 + +目前我们支持了三种类型的条码解码,它们分别是EAN13、 EAN8 和UPC-A。(下图为EAN13 条码示例) + +![](./imgs/5.png) + +条码的识别主要流程如下图: + +![](./imgs/6.png) + +其中: + +1. 优化的超分辨率策略指的是对较小的条码进行**超分辨率放大**,不同大小条码做不同处理。 + +2. 解码算法的核心是基于条码编码方式的**向量距离计算**。因为条码的编码格式为固定的数个"条空",所以可以在约定好"条空"间隔之后。将固定的条空读取为一个向量,接下来与约定好的编码格式相匹配,取匹配程度最高的编码为结果。 + +3. 在解码步骤中,解码的单位为一条线,由于噪点,条空的粘连等原因,单独条码的解码结果存在较大的不确定性,因此我们加入了对**多条线的扫码**,通过对均匀分布的扫描与解码,能够将二值化过程中的一些不完美之处加以抹除。 + + **具体实现为**:首先在检测线上寻找起始符,寻找到起始符之后,对前半部分进行读取与解码,接着寻找中间分割符,接着对后半部分进行读取与解码,最后寻找终结符,并对整个条码进行首位生成与校验(此处以EAN13格式举例,不同格式不尽相同)。最后,每条线都会存在一个解码结果,所以对其进行投票,只将最高且总比例在有效结果50%以上的结果返回。这一部分我们基于ZXing的算法实现做了一些改进(投票等)。 + +4. **更换二值化和解码器**指的是在为解码成功遍历使用每种解码器和二值化尝试解码。 + +# 使用方式 + +C++ + +``` +#include "opencv2/barcode.hpp" +#include "opencv2/imgproc.hpp" + +using namespace cv; + +Ptr bardet = makePtr("sr.prototxt", "sr.caffemodel"); //如果不使用超分辨率则可以不指定模型路径 +Mat input = imread("your file path"); +Mat corners; //返回的检测框的四个角点坐标,如果检测到N个条码,那么维度应该是[N][4][2] +std::vector decoded_info; //返回的解码结果,如果解码失败,则为空string +std::vector decoded_format; //返回的条码类型,如果解码失败,则为BarcodeType::NONE +bool ok = bardet->detectAndDecode(input, decoded_info, decoded_format, corners); +``` + +Python + +``` +import cv2 + +bardet = cv2.barcode_BarcodeDetector() +img = cv2.imread("your file path") +ok, decoded_info, decoded_type, corners = bardet.detectAndDecode(img) +``` + +更多使用方式请参考文档: + +https://docs.opencv.org/master/dc/df7/classcv_1_1barcode_1_1BarcodeDetector.html + +# 参考文献 + +王祥敏,汪国有. 一种基于方向一致性的条码定位算法[EB/OL]. 北京:中国科技论文在线 [2015-04-22]. http://www.paper.edu.cn/releasepaper/content/201504-338. \ No newline at end of file diff --git "a/OpenCV/\347\224\250OpenCV\345\256\236\347\216\260\350\266\205\350\275\273\351\207\217\347\232\204NanoDet\347\233\256\346\240\207\346\243\200\346\265\213\346\250\241\345\236\213-2021-03-17.md" "b/OpenCV/\347\224\250OpenCV\345\256\236\347\216\260\350\266\205\350\275\273\351\207\217\347\232\204NanoDet\347\233\256\346\240\207\346\243\200\346\265\213\346\250\241\345\236\213-2021-03-17.md" new file mode 100644 index 0000000000000000000000000000000000000000..9cfba447de84d9c1f60d949b160e2bbdffc9ce7a --- /dev/null +++ "b/OpenCV/\347\224\250OpenCV\345\256\236\347\216\260\350\266\205\350\275\273\351\207\217\347\232\204NanoDet\347\233\256\346\240\207\346\243\200\346\265\213\346\250\241\345\236\213-2021-03-17.md" @@ -0,0 +1,85 @@ +本文用OpenCV部署了超轻量目标检测模型NanoDet,实现了C++和Python两个版本,并对此进行了解析。 + +2020年,在深度学习目标检测领域诞生了yolov4,yolov5和nanodet这些优秀的检测模型,有许多的微信公众号报道这些算法模型。深度学习目标检测方法可划分为 Anchor-base 和 Anchor-free 两大类,nanodet是一个速度超快和轻量级的移动端 Anchor-free 目标检测模型,并且它的精度不亚于yolo系列的。 + +nanodet通过一些论文里的trick组合起来得到了一个兼顾精度、速度和体积的检测模型。作者用到的一些trick,主要参考自:(1)参考FCOS 式的单阶段 anchor-free 目标检测模型,FCOS特点是让模型学习feature map中每个位置到检测框的四条边的距离,如下图所示。 + +![](./imgs/8.jpg) + +(2)使用 ATSS 进行目标采样,该方法提出了自适应训练样本选择方法,该方法根据目标的统计特征(方差和均值)自动划分正训练样本和负训练样本,弥合了基于锚的探测器与无锚探测器之间的差距。(3)使用 Generalized Focal Loss 损失函数执行分类和边框回归(box regression),该函数能够去掉 FCOS 的 Centerness 分支,省去这一分支上的大量卷积,从而减少检测头的计算开销。 + +为了达到轻量化的目的,作者在设计网络结构时,使用 ShuffleNetV2 1.0x 作为骨干网络,他去掉了该网络的最后一层卷积,并且抽取 8、16、32 倍下采样的特征输入到 PAN 中做多尺度的特征融合。 + +在FPN模块里,去掉所有卷积,只保留从骨干网络特征提取后的 1x1 卷积来进行特征通道维度的对齐,上采样和下采样均使用插值来完成。与 YOLO 使用的 concat操作不同,项目作者选择将多尺度的 Feature Map 直接相加,使整个特征融合模块的计算量变得非常小。 + +在检测头模块里,使用了共享权重的检测头,即对 FPN 出来的多尺度 Feature Map 使用同一组卷积预测检测框,然后每一层使用一个可学习的 Scale 值作为系数,对预测出来的框进行缩放。与此同时,使用了 Group Normalization(GN)作为归一化方式.FCOS 的检测头使用了 4 个 256 通道的卷积作为一个分支,也就是说在边框回归和分类两个分支上一共有 8 个 c=256 的卷积,计算量非常大。为了将其轻量化,项目作者首先选择用深度可分离卷积替换普通卷积,并且将卷积堆叠的数量从 4 个减少为 2 组。在通道数上,将 256 维压缩至 96 维,之所以选择 96,是因为需要将通道数保持为 8 或 16 的倍数,能够享受到大部分推理框架的并行加速。 + +最后,项目作者借鉴了 YOLO 系列的做法,将边框回归和分类使用同一组卷积进行计算,然后 split 成两份。最后,项目作者借鉴了 YOLO 系列的做法,将边框回归和分类使用同一组卷积进行计算,然后 split 成两份,这样就组成了nanodet网络。 + +作者把nanodet发布在github上,项目地址: https://github.com/RangiLyu/nanodet, + +下载代码和模型文件到本地,按照README文档运行一个前向推理程序。接下来,我阅读前向推理主程序demo.py文件,尝试理解在运行这个主程序时需要调用哪些函数和.py文件。在前向推理主程序demo.py文件,对一幅图片做目标检测是在Predictor类的成员函数inference里实现的,它里面包含了对输入图片做预处理preprocess,前向计算forward和后处理postprocess这三个步骤。Predictor类的定义如下图所示 + +![](./imgs/9.jpg) + +对输入原图做预处理,预处理模块是使用Pipeline类实现,对应的代码是 + +![](./imgs/10.jpg) + +看到这段代码时,我有些懵逼了。第一次见到functools.partial这个模块,我百度查了一下它的作用是包装函数,接着看warp_resize函数,这个函数对应的代码很复杂,里面有多个if条件判断,调用了多个自定义函数。限于篇幅,在这里展示部分截图代码,如下图所示 + +![](./imgs/11.jpg) + +从代码不难猜测出warp_resize函数的作用是对原图做resize,于是我把warp_resize函数返回的图像做可视化并打印出图像的尺寸是高宽:320x320,可视化结果如下图所示。 + +![](./imgs/12.jpg) + +从图中可以看到,warp_resize函数是保持原图高宽比的resize,短边剩下的部分用黑色像素填充。这种功能在ultralytics的yolov3和yolov5代码仓库里有一个letterbox函数实现的,在letterbox函数使用opencv库里的resize和copyMakeBorder就可以实现保持高宽比的resize,这种方法简洁明了。接着我对warp_resize函数和letterbox函数对同一幅图片做保持原图高宽比的resize的结果比较。可视化结果如下,从视觉上看不出它们有何差异。把这两幅图的像素矩阵做减法比较,发现它们并不等于0,也是是说它们的像素值还是有差异的。 + +![](./imgs/13.jpg) + +接着看预处理模块Pipeline类里的第二个函数color_aug_and_norm,代码截图如下。可以看出,这个函数的作用是对输入图片的RGB三通道分别做减均值除以标准差的操作,不过在最开始对img除以255,在最后对均值和标准差分别除以255,这三次除以255是完全没必要的,因为在最后一步 (img - mean) / std,分子分母可以约掉1/255,这和img,mean,std不做除以255这一步计算,直接(img - mean) / std是等价的。 + +![](./imgs/14.jpg) + +综上所述,在预处理模块Pipeline类包含了很多冗余的计算,图像预处理本身是一个简单问题,但是在官方代码里却把简单问题搞复杂化了。 + +官方代码仓库(https://github.com/RangiLyu/nanodet) + +里提供了基于 ncnn 推理框架的实现,基于mnn,libtorch,openvino的实现,但是没有基于Opencv的dnn模块的实现。于是我就编写一套基于Opencv的dnn模块的实现,程序里包含Python和C++两个版本的代码。 + +**地址是**: **https://github.com/hpc203/nanodet-opncv-dnn-cpp-python** + +在这套程序里,图像预处理模块沿用了ultralytics代码仓库里的letterbox函数使用opencv库里的resize和copyMakeBorder就可以实现保持高宽比的resize。此外,在网上有很多介绍nanodet网络结构的文章,但是在文章里没有对nanodet后处理模块做详细介绍的。因此,在编写这套程序时,我最关注的是nanodet的后处理模块,在nanodet网络输出之后,经过怎样的矩阵计算之后得到检测框的左上和右下两个顶点的坐标(x,y)的值的。接下来,我结合代码来理解后处理模块的运行原理。首先,原图经过预处理之后形成一个320x320的图片作为nanodet网络的输入,经过forward前向计算后会得到40x40,20x20,10x10这三种尺度的特征图(换言之就是原图缩小8倍,16倍,32倍),在程序代码里设断点调试,查看中间变量,截图如下: + +![](./imgs/23.jpg) + +![](./imgs/15.jpg) + +从上图可以看到,经过forward前向计算后,有6个输出矩阵。第1个输出的维度是(1600,80),它对应的是40x40的特征图(拉平后是长度为1600的向量,也就是说一共有1600个像素点)里的每个像素点在coco数据集的80个类别里的每个类的置信度。第2个输出的维度是(1600,32),它对应的是40x40的特征图(拉平后是长度为1600的向量,也就是说一共有1600个像素点)里的每个像素点的检测框的预测偏移量,可以看到这个预测偏移量是一个长度为32的向量,它可以分成4份,每份向量的长度为8,接下来的第3,4,5,6个输出矩阵的意义以此类推。 + +前面讲到过nanodet的特点是让神经网络学习feature map中每个位置到检测框的四条边的距离,接下来我们继续在程序里设断点调试,来理解这4份长度为8的预测偏移量是如何经过一系列的矩阵计算后得到到检测框的四条边的距离。代码截图如下: + +![](./imgs/16.jpg) + +从上图可以看到,把形状为(1600,32)的矩阵reshape成(6400,8)的矩阵bbox_pred,其实就等同于把每一行切分成4份组成新的矩阵,然后做softmax变换,把数值归一化到0至1的区间内。继续调试接下来的一步,代码截图如下: + +![](./imgs/17.jpg) + +可以看到project是一个长度8的向量,元素值是从0到7。形状为(6400,8)的矩阵bbox_pred与向量project做乘法得到6400的列向量,然后reshape为(1600,4)的矩阵,接下来乘以缩放步长。这时候就得到的形状为(1600,4)的矩阵bbox_pred,它的几何意义就是40x40的特征图里的每个像素点到检测框的四条边的距离。有了这个值之后,接下来的计算就简单了,在此不做详细讲述,可以参阅我的代码。简单来说就是计算特征图的每个像素点在coco数据集里的80类里的最大score值作为类别置信度,然后把特征图的所有像素点的类别置信度从高到低排序,取前topk个像素点,然后根据上一步计算出的到检测框四条边的距离换算出检测框的左上和右下两个顶点的(x,y)值,最后做NMS去除重叠的检测框。为了更好的理解从nanodet输出特征图到最终计算出目标检测框的左上和右下顶点坐标(x,y)值的这个过程,我在草稿纸上画图演示,如下所示: + +![](./imgs/18.jpg) + +![](./imgs/19.jpg) + +![](./imgs/20.jpg) + +在编写完调用opencv的做nanodet目标检测的程序后,为了验证程序的有效性,从COCO数据集里选取几张图片测试并且与官方代码做比较,官方代码是用python编写的调用pytorch框架做目标检测的。结果如下,左边的图是官方代码的可视化结果,右边的图是opencv做nanodet目标检测的可视化结果。 + +![](./imgs/21.jpg) + +把官方代码和我编写的代码做了一个性能比较的实验,实验环境是ubuntu系统,8G显存的gpu机器。在实验中读取一个视频文件,对视频里的每一帧做目标检测,分别运行官方的调用pytorch框架做目标检测的python代码和我编写的调用opencv做目标检测的python代码,在terminal终端输入top查看这两个程序运行时占用的内存,截图如下。第一行是opencv做nanodet目标检测程序运行时占用的内存,第二行是官方代码运行时占用的内存,可以看到使用opencv做nanodet目标检测对内存的消耗明显要低于官方代码的pytorch框架做nanodet目标检测的。 + +![](./imgs/22.jpg) + +**Github传送门**:**https://github.com/hpc203/nanodet-opncv-dnn-cpp-python** \ No newline at end of file diff --git a/README.md b/README.md index 9b46cbb96d6340257724b47998d2c4b7043cebb0..d82b1ac437038ed4cdf737d51aa63fa34ed7bc02 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ 企业技术文章精选,**觉得不错的话别忘了点个Star哈**。 -计划每天更新 +计划每天更新,欢迎大家一起来完善,也欢迎大家成为贡献者,有什么问题可以直接私信我或者提Issue **有文章投稿的欢迎哈,我这边可以帮忙内推CSDN公众号等渠道** @@ -44,16 +44,14 @@ 往期精彩链接: [点击这里](./人人都是产品经理) -## 我爱计算机视觉 - -**2021-05-24-新增**[推荐几篇新出的 CVPR 2021开源论文,含图像分割、域适应、图像检索、视线估计等](./我爱计算机视觉/推荐几篇新出的 CVPR 2021开源论文,含图像分割、域适应、图像检索、视线估计等.md) - -**2021-05-24-新增**[ICCV2021多模态视频分析与推理比赛参赛邀请](./我爱计算机视觉/ICCV2021多模态视频分析与推理比赛参赛邀请.md) - -往期精彩链接: [点击这里](./我爱计算机视觉) - ## NVIDIA英伟达 **2021-05-24-新增**[AI 艺术画廊 —— 用 AI 诠释艺术与音乐 一](./NVIDIA英伟达/AI 艺术画廊 —— 用 AI 诠释艺术与音乐 一.md) 往期精彩链接: [点击这里](./NVIDIA英伟达) + +## OpenCV + +**2021-05-25-新增**[用OpenCV实现条形码识别](./OpenCV/用OpenCV实现条形码识别.md) + +往期精彩链接: [点击这里](./OpenCV) diff --git "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/ICCV2021\345\244\232\346\250\241\346\200\201\350\247\206\351\242\221\345\210\206\346\236\220\344\270\216\346\216\250\347\220\206\346\257\224\350\265\233\345\217\202\350\265\233\351\202\200\350\257\267.md" "b/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/ICCV2021\345\244\232\346\250\241\346\200\201\350\247\206\351\242\221\345\210\206\346\236\220\344\270\216\346\216\250\347\220\206\346\257\224\350\265\233\345\217\202\350\265\233\351\202\200\350\257\267.md" deleted file mode 100644 index af00c0ca8d0ca1920a5de4f3ef9cb23888cbe919..0000000000000000000000000000000000000000 --- "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/ICCV2021\345\244\232\346\250\241\346\200\201\350\247\206\351\242\221\345\210\206\346\236\220\344\270\216\346\216\250\347\220\206\346\257\224\350\265\233\345\217\202\350\265\233\351\202\200\350\257\267.md" +++ /dev/null @@ -1,27 +0,0 @@ -ICCV2021 “多模态视频分析与推理比赛”开放注册。此次比赛提供四项分任务竞赛: - -- 视频问答(Video Question Answering); -- 基于骨架的动作识别(Skeleton-based Action Recognition); -- 基于鱼眼视频的动作识别(Fisheye Video-based Action Recognition); -- 行人重识别(Person Re-Identification)。 - -第一个视频问答的比赛是基于最新的VideoQA数据集:SUTD-TrafficQA。这个数据集重点关注基于交通事件的视频推理,包含了6个非常有挑战性的推理任务。SUTD-TrafficQA 包含有10,080个真实场景的视频和62,535个人工标注的问题。下图是SUTD-TrafficQA数据集中的一个例子。 - -![](./imgs/9.jpg) - -另外三个竞赛(基于骨架的动作识别,基于鱼眼视频的动作识别和行人重识别)是基于最新的,有挑战性的基于无人机视角的视频理解数据集,UAV-Human。UAV-Human重点关注从无人机视角来理解推理人类行为,包含了67,428个视频样本,6种不同的模态,4个人类行为理解任务和119个视频主题。下图包含UAV-Human数据中的多种样例。 - -![](./imgs/10.jpg) - -下面是本次比赛的时间安排表: - -| 比赛报名开放 | 2021.05.20 | -| ---------------------------- | ---------- | -| 训练数据发布 | 2021.06.09 | -| 测试数据发布 | 2021.06.13 | -| 结果提交开放以及比赛报名结束 | 2021.06.25 | -| 结果提交关闭 | 2021.07.05 | - -欢迎大家参加比赛,获胜队伍将会被邀请到ICCV2021 Workshop介绍自己的工作。有关本次比赛的更多详细信息,请访问网站: - -https://sutdcv.github.io/multi-modal-video-reasoning \ No newline at end of file diff --git "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/1.jpg" "b/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/1.jpg" deleted file mode 100644 index 7b2ca44d8b2c4f30146dc53390183ddb14af0df5..0000000000000000000000000000000000000000 Binary files "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/1.jpg" and /dev/null differ diff --git "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/1.webp" "b/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/1.webp" deleted file mode 100644 index dce90aa6b7561d94e43acbf7277dcefc934b1577..0000000000000000000000000000000000000000 Binary files "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/1.webp" and /dev/null differ diff --git "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/10.jpg" "b/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/10.jpg" deleted file mode 100644 index e48b42f96154b67a34e789e80f6eec0352247a4f..0000000000000000000000000000000000000000 Binary files "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/10.jpg" and /dev/null differ diff --git "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/10.webp" "b/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/10.webp" deleted file mode 100644 index d162c39339e5a7d84440951f270ee326dc5bfde9..0000000000000000000000000000000000000000 Binary files "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/10.webp" and /dev/null differ diff --git "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/2.jpg" "b/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/2.jpg" deleted file mode 100644 index 8f34b77bc89d9a146d606a0cdd448dfd7dc2bca2..0000000000000000000000000000000000000000 Binary files "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/2.jpg" and /dev/null differ diff --git "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/2.webp" "b/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/2.webp" deleted file mode 100644 index 47711a5d37f599525eb347861f3068d755d36676..0000000000000000000000000000000000000000 Binary files "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/2.webp" and /dev/null differ diff --git "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/3.jpg" "b/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/3.jpg" deleted file mode 100644 index 526c26fdf322a4da2acc04d3edf0d94ac2ffeb96..0000000000000000000000000000000000000000 Binary files "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/3.jpg" and /dev/null differ diff --git "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/3.webp" "b/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/3.webp" deleted file mode 100644 index b27ff3eb7ecadf6787179faa121ace565d199f7d..0000000000000000000000000000000000000000 Binary files "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/3.webp" and /dev/null differ diff --git "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/4.png" "b/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/4.png" deleted file mode 100644 index 9f2db6a97a6d40b5b68a5fe0a1a5af2bdd64ac56..0000000000000000000000000000000000000000 Binary files "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/4.png" and /dev/null differ diff --git "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/5.jpg" "b/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/5.jpg" deleted file mode 100644 index 6801ade463007ca06e73dde92f843a73ddd6ed11..0000000000000000000000000000000000000000 Binary files "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/5.jpg" and /dev/null differ diff --git "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/5.webp" "b/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/5.webp" deleted file mode 100644 index 248abd30aed53aac93bcb8d804098de0a65f4b3b..0000000000000000000000000000000000000000 Binary files "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/5.webp" and /dev/null differ diff --git "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/6.jpg" "b/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/6.jpg" deleted file mode 100644 index 4107712b9645339f768f60a157057409a640a45e..0000000000000000000000000000000000000000 Binary files "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/6.jpg" and /dev/null differ diff --git "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/6.webp" "b/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/6.webp" deleted file mode 100644 index 3e454b2b938456c6b703c78c5a8bad75238b640e..0000000000000000000000000000000000000000 Binary files "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/6.webp" and /dev/null differ diff --git "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/7.jpg" "b/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/7.jpg" deleted file mode 100644 index 69904a1f2761740d98428124209235f2582911ed..0000000000000000000000000000000000000000 Binary files "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/7.jpg" and /dev/null differ diff --git "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/7.webp" "b/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/7.webp" deleted file mode 100644 index cbb035a6a64ed5a9e3ffbb88321dbb7aff46b044..0000000000000000000000000000000000000000 Binary files "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/7.webp" and /dev/null differ diff --git "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/8.jpg" "b/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/8.jpg" deleted file mode 100644 index 9129138b1fa48262a740a53e88cb051d55e01474..0000000000000000000000000000000000000000 Binary files "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/8.jpg" and /dev/null differ diff --git "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/8.webp" "b/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/8.webp" deleted file mode 100644 index ae75c8b3f554a3485714b5fba489f8a7314fe756..0000000000000000000000000000000000000000 Binary files "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/8.webp" and /dev/null differ diff --git "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/9.jpg" "b/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/9.jpg" deleted file mode 100644 index b5af16fdab50077fe0fb36812caf193e6380d5ad..0000000000000000000000000000000000000000 Binary files "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/9.jpg" and /dev/null differ diff --git "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/9.webp" "b/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/9.webp" deleted file mode 100644 index 424f48907d89bd21fe331d085dca45db90a9527b..0000000000000000000000000000000000000000 Binary files "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/imgs/9.webp" and /dev/null differ diff --git "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/\346\216\250\350\215\220\345\207\240\347\257\207\346\226\260\345\207\272\347\232\204 CVPR 2021\345\274\200\346\272\220\350\256\272\346\226\207\357\274\214\345\220\253\345\233\276\345\203\217\345\210\206\345\211\262\343\200\201\345\237\237\351\200\202\345\272\224\343\200\201\345\233\276\345\203\217\346\243\200\347\264\242\343\200\201\350\247\206\347\272\277\344\274\260\350\256\241\347\255\211.md" "b/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/\346\216\250\350\215\220\345\207\240\347\257\207\346\226\260\345\207\272\347\232\204 CVPR 2021\345\274\200\346\272\220\350\256\272\346\226\207\357\274\214\345\220\253\345\233\276\345\203\217\345\210\206\345\211\262\343\200\201\345\237\237\351\200\202\345\272\224\343\200\201\345\233\276\345\203\217\346\243\200\347\264\242\343\200\201\350\247\206\347\272\277\344\274\260\350\256\241\347\255\211.md" deleted file mode 100644 index a80de0d36f1b3bba94fb9f5a4e88a80406d43c69..0000000000000000000000000000000000000000 --- "a/\346\210\221\347\210\261\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/\346\216\250\350\215\220\345\207\240\347\257\207\346\226\260\345\207\272\347\232\204 CVPR 2021\345\274\200\346\272\220\350\256\272\346\226\207\357\274\214\345\220\253\345\233\276\345\203\217\345\210\206\345\211\262\343\200\201\345\237\237\351\200\202\345\272\224\343\200\201\345\233\276\345\203\217\346\243\200\347\264\242\343\200\201\350\247\206\347\272\277\344\274\260\350\256\241\347\255\211.md" +++ /dev/null @@ -1,118 +0,0 @@ -CV君一直在整理 CVPR 2021 论文: - -https://github.com/52CV/CVPR-2021-Papers - -本文分享几篇近期值得关注的 CVPR 2021 的开源论文,包括图像到图像翻译、全景分割、语义分割、域适应、图像检索、无监督学习,以及一篇关于首次对从人们相互注视的图像/视频中学习弱监督的三维视线范式(LAEO)的研究。 - -相信其中有些工作肯定会让你大开眼界。 - -# High-Resolution Photorealistic Image Translation in Real-Time: A Laplacian Pyramid Translation Network - -来自香港理工大学&阿里达摩院 - -作者称是首个在 4K 分辨率图像上实时实现逼真 I2IT(图像到图像翻译) 的工作。其次,在轻量级和快速的推理模型,仍然在转换能力和逼真度方面在逼真的I2IT应用上实现了可比或优越的性能。定性和定量的结果都表明,所提出的方法与先进的方法相比表现良好。 - -- 论文链接:https://arxiv.org/abs/2105.09188 -- 项目链接:https://github.com/csjliang/LPTN - -![](./imgs/1.jpg) - -标签:图像到图像翻译 - -# PPR10K: A Large-Scale Portrait Photo Retouching Dataset with Human-Region Mask and Group-Level Consistency - -来自香港理工大学&阿里达摩院 - -与一般的人像照片修饰任务不同,portrait photo retouching(PPR)的目的是提高一组外观扁平的人像照片的视觉质量,有其特殊的实际要求,如 human-region priority(HRP)和 group-level consistency(GLC)。HRP 要求对更多关注 human regions(人体区域),GLC 则要求将一组人像照片修饰成一致的色调。而在现有的一般照片修饰数据集上训练的模型,很难满足 PPR 的这些要求。 - -为了促进这一高频任务的研究,作者在本次工作中构建了一个大规模的 PPR 数据集:PPR10K,并称这是首个此类相关的数据集。PPR10K 共包含 1,681 个组和 11,161 张高质量的原始人像照片。以及人类区域的高分辨率分割掩码。每张原始照片都由三位专家进行修饰,并对每组照片进行精心调整,使其色调一致。作者定义了一套评估 PPR性能的客观指标,并提出了学习具有良好 HRP 和 GLC 性能的 PPR 模型的策略。而 PPR10K 数据集为研究自动 PPR 方法提供了一个很好的基准,实验证明,所提出的学习策略能够有效地提高修饰性能。 - -- 论文链接:https://arxiv.org/abs/2105.09180 -- 项目链接:https://github.com/csjliang/PPR10K - -![](./imgs/2.jpg) - -标签:portrait photo retouching+数据集 - -# Railroad is not a Train: Saliency as Pseudo-pixel Supervision for Weakly Supervised Semantic Segmentation - -来自延世大学&成均馆大学 - -现有的使用图像级弱监督的弱监督语义分割(WSSS)研究的局限性有:sparse object coverage(稀疏的对象覆盖),不准确的对象边界,以及来自非目标对象的共同出现的像素。 - -本次工作所提出方案:提出 Explicit Pseudo-pixel Supervision(EPS),通过结合两个弱监督从像素级反馈中学习;图像级标签通过 localization map,以及来自现成的显著检测模型提供丰富边界的 saliency map 来提供目标身份。作者进而又设计一种联合训练策略,可以充分利用两种信息之间的互补关系。所提出方法可以获得准确的物体边界,并摒弃共同出现的像素,从而显著提高 pseudo-masks 的质量。 - -结论:实验结果表明,所提出方法通过解决 WSSS 的关键挑战而明显优于现有方法,并在 PASCAL VOC 2012 和MS COCO 2014 数据集上取得了新的 SOTA。 - -- 论文链接:https://arxiv.org/abs/2105.08965 -- 项目链接:https://github.com/halbielee/EPS - -![](./imgs/3.jpg) - -# Exemplar-Based Open-Set Panoptic Segmentation Network - -来自首尔大学&Adobe Research - -该文先是定义开放集全景分割(OPS)任务,并通过深入分析其固有的挑战,利用合理的假设使其可行。通过重新组织 COCO 构建一个全新的 OPS 基准,并作为 Panoptic FPN 的变种展示其基线的性能。EOPSN 是基于典范理论的开放集全景分割框架,在检测和分割未知类别的例子方面被实验证明是有效的。 - -- 论文链接:https://arxiv.org/abs/2105.08336 -- 项目链接:https://github.com/jd730/EOPSN -- 主页地址:https://cv.snu.ac.kr/research/EOPSN/ - -![](./imgs/4.png) - -标签:全景分割+开放集 - -# Learning to Relate Depth and Semantics for Unsupervised Domain Adaptation - -来自苏黎世联邦理工学院 - -提出一种在 UDA 背景下进行语义分割和单目深度估计的新方法。亮点如下:Cross-Task Relation Layer(CTRL),为域对齐学习一个联合特征空间;该联合空间编码特定任务的特征和跨任务的依赖关系,显示对UDA有用;semantic refinement head(SRH)有助于学习任务的关联性;深度离散技术有利于学习不同语义类别和深度级别之间的独特关系;iterative self-learning(ISL)方案通过利用目标域的高置信度预测,进一步提高模型的性能。 - -在三个具有挑战性的 UDA 基准上,所提出的方法始终大幅超越先前的工作。 - -- 论文链接:https://arxiv.org/abs/2105.07830 -- 项目链接:https://github.com/susaha/ctrl-uda - -![](./imgs/5.jpg) - -标签:域适应 - -# Prototype-supervised Adversarial Network for Targeted Attack of Deep Hashing - -来自哈工大(深圳)&鹏城实验室&港中文&深圳市大数据研究院&电子科技大学&Koala Uran Tech - -该文提出一个用于灵活的 targeted hashing attack(定向哈希攻击)的 prototype-supervised adversarial network(ProS-GAN),包括一个 PrototypeNet,一个生成器和一个判别器。实验证明,ProS-GAN 可以实现高效和卓越的攻击性能,比最先进的深度哈希的定向攻击方法具有更高的可迁移性。 - -- 论文链接:https://arxiv.org/abs/2105.07553 -- 项目链接:https://github.com/xunguangwang/ProS-GAN - -![](./imgs/6.jpg) - -标签:图像检索+对抗攻击 - -# Weakly-Supervised Physically Unconstrained Gaze Estimation - -来自英伟达&罗切斯特理工大学&Lunit Inc - -本次工作所探讨的问题是从人类互动的视频中进行弱监督的视线估计,基本原理是利用人们在进行 "相互注视"(LAEO)活动时存在的与视线相关的强烈的几何约束这一发现。通过提出一种训练算法,以及为该任务特别设计的几个新的损失函数,可以从 LAEO 标签中获得可行的三维视线监督信息。在两个大规模的 CMU-Panoptic 和 AVA-LAEO 活动数据集的弱监督下,证明了半监督视线估计的准确性和对最先进物理无约束的自然 Gaze360 视线估计基准的跨域泛化的显著改善。 - -- 论文链接:https://arxiv.org/abs/2105.09803 -- 项目链接:https://github.com/NVlabs/weakly-supervised-gaze - -![](./imgs/7.jpg) - -标签:CVPR 2021 Oral+视线估计 - -# SMURF: Self-Teaching Multi-Frame Unsupervised RAFT with Full-Image Warping - -来自谷歌&Waymo - -SMURF 是一种用于无监督学习光流的方法,在所有的基准上提高了 36% 到 40%(相比之前最好的方法UFlow),甚至超过了一些有监督的方法,如 PWC-Net 和 FlowNet2。该方法是将有监督光流的结构改进,即RAFT 模型,与无监督学习的新思路相结合,包括一个序列感知的自监督损失,一个处理帧外运动的技术,以及一个从多帧视频数据中有效学习的方法,同时仍然只需要两帧推理。 - -- 论文链接:https://arxiv.org/abs/2105.07014 -- 项目链接:https://github.com/google-research/google-research/tree/master/smurf - -![](./imgs/8.jpg) - -标签:无监督学习 \ No newline at end of file