vlambda博客
学习文章列表

构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受

前言

在编写实际项目的过程中,我需要实现绿色主题的“伪彩色”变换。在目前提供的模板中,只有summer最为接近,但是它的颜色太浅了,看上去不是很清晰。所以我结合ocean和summer两种现有模板,构建了deepgreen这个模板。它能够实现绿色主题的显著的伪彩色变换。本文记录了我发现问题、分析问题、编写代码、为OpenCV提供pull request的全过程。希望能够为有相关需求的工程师提供帮助。信息量比较大,表述不清楚的地方欢迎讨论。

基本情况

01


cv::applyColorMap()能够实现预定义的伪彩色,这个是众所周知的事情。





除了这些预置的变换,如果我想实现新的变换,一般的方法是做LUT变换



构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受


但是,这段代码只是给调用方法,没有具体说明这里的LUT色板是如何构建的,你如果想做这个调色板还是需要自己找。我在做一个实际项目的时候,甲方就反馈,希望提供一种个比较深的绿色,由此开启整个关于applyColorMap()的探索。

参考OpenCV的代码进行修改,达到目的

02


能够找到重要的参考,主要就是OpenCV自己的代码:colormap.cpp


构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受

截取其中一个colormap的实现,比如"ocean"



构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受


明显这个colormap中最主要的成分就是rgb的大矩阵,它返回的结果是LUT。关键问题是这样的矩阵如何获得?想搞懂这里的文档,需要特定的基础知识。此外,我们深入研究的话,就可以发现这里OpenCV实现的不仅仅是LUT,还有其它很多东西。比如3通道,比如插值等。为了实现这些功能,它添加了很多函数,如果想把这些函数集成过来,可能会花费较多精力。反之,我认为更直接可行的方法,就是修改现有的OpenCV代码,重新生成dll文件。

为了实现甲方要求,套用ocean的色彩对summer进行修改,其中只是修改了一个地方,那就是将ocean中的blue通道和green通道进行了替换。

构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受

修改前后的效果

从而将绿色的成分更多的凸显出来。修改的代码通过Git的版本控制,可以比较明显地看出来(附录3).

https://gitee.com/helu2007/opencv/commit/e34c1c2e228a86d5833222da155766be84ef6e8e?view=parallel

下图的例子中,可以发现已经正确调用并且COLORMAP_DEEPGREEN这个常量也是自定义。


构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受
构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受
构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受

这里实现的效果很好。但是时间长了,麻烦就来了,随着OpenCV的不断升级,后面的版本可能都需要做同样的修改。我也开始寻找相关解决方法。

有两种方法:一种方法,我可以构建自己专用OpenCV,这个版本的OpenCV中应该有我自己的代码,也能够更新官网代码。这样每次大的升级,我只需要重新编译一下就可以了;另一种方法,如果我能够将这段代码并到OpenCV中,那是最好的,我用起来方便、别人也可以用得着。

构建自己专用OpenCV

03


如果是自用的话,我建议使用Gitee。其主要原因是由于github的网络限制,所以直接通过其下载代码容易出现各种错误。

Gitee的一大特色,就是可以直接创建github上opencv的clone。(附录5)



构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受


而后我们可以将gitee上代码git到本地,修改,编译。



构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受




构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受


确保能够正确调用后,我们需要将这里的代码提交到gitee上去。



构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受


能够看到,这里的modules由于我们的修改,已经发生了变化。



构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受


由于gitee上的这个库是我们自己控制的,直接push上去,过程中需要输gitee的密码。



构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受
构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受


能够看到这次提交的对比。这样我们的代码就保存下来了。

但是同时需要注意的是,Gitee上的OpenCV是和原始库“脱轨”的,它除了一个“强制刷新”其它什么都做不了。而GitHub非常强的一个功能,是提供下图这个"behind".



构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受


这个behind是最为重要的,它可以使得我们的代码自动更新。这样的话我才能够维护一个最新的库。

将自己的代码并到OpenCV中(pull request)

04


pull request才是开源的本质,好的代码一定要融合到基库中,如果你的代码不好就融合不进去,通过这个过程中,我们才能够写出“正确、清晰、有弹性"的优秀代码。抱着”试试看“的态度,我将这里的修改提交GitHub。(由于网速问题,我基本上都是在网站上手工修改)


构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受

并且借助工具,填写英文文档。


构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受
构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受

小结

睡了一觉以后,发现opencv member 给出了许多反馈,整理一下

1、如何使用github的方法,甚至给出了具体命令

git checkout -b feat_deep_green_colormap

2、提示同时提供文档,并且给出链接

https://github.com/opencv/opencv/pull/15388

3、给出提交代码和需要解决的问题提出相关建议,并且直指问题核心!

https://matplotlib.org/tutorials/colors/colormaps.html

4、提出代码建议:建议按照字母顺序进行排列,并且要求提供注释

5、给出了规范的提交,并且是非常对口的。

这个是非常激动人心的,只要你是认认真真地去提交代码,就会有优秀的工程师教你如何做对,比如这里给出了非常对口的指导:

对口指导


构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受



构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受


构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受

处理视觉效果

https://ai.googleblog.com/2019/08/turbo-improved-rainbow-colormap-for.html

它来自于google的一篇研究,并且提供了参考代码

https://gist.github.com/mikhailov-work/6a308c20e494d9e0ccc29036b28faa7a

大家看最后我的提交,基本上就是参考的#15338,以后很多地方都可以继续参考。GitHub还有一项非常厉害的功能,就是AutoBoot(附录6),以及《OpenCV PR 成功的收获和感悟》


构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受
构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受
构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受

反思小结

05


现在看来,想充分使用git的功能,必须满足:

1、持续更新;

2、网络通畅;

3、本地部署。

一方面,如果希望有一个自己能够使用的专用库,这个库一定要来自实际需求,如果可以。我希望能够经过autobot检验,如果不可以,至少要是本地能够编译的;

一方面,如果下次遇到类似的问题,或者马上提出新的问题,将其提交到opencv绝对是最好的选择。成功的提交,才能够给出最多的价值体验。

感悟

OpenCV

这是我第二次为OpenCV提供代码,从我的经验来看:
1、使用git而不是直接zip下载的方式来使用opencv代码,才是正确方式。但是也必须灵活使用现有工具和资源;
2、为opencv贡献代码是非常好的学习git和opencv的最佳途径,这是其它场所无法提供的学习方式。

附录 ●

关于这个问题的其它尝试和一些相关的内容,放在附录里面,有空可以看看:

01

构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受

寻求直接修改代码解决方法

这里我还是需要寻找能够和OpenCV代码共存的方式。最简单的方法就是在GOCVHelper中添加相应的修改。首先要做的,就是能够继承  public ColorMap

但是如果我想直接引用ColorMap的话,会出现这个问题



构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受


由于种种原因,这里的ColorMap只是作为一个编译期间可用的类,没有被开放出来,也就是我不能直接修改。

02

构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受

一个小tip

配置项目属性的时候,选择刚刚生成的bin目录



构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受


这样会优先使用修改后的dll,从而不会影响通用的OpenCV.dll。

03

构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受

我具体修改了什么代码?



构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受
构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受
构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受
构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受
构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受


这里的几个修改,都是比较简单的。其中注意不能有中文(包括注释,不符合编码习惯)

重新生成的时候,生成install就可以。注意lib/dll/include都需要使用最新的

04

构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受

vs调用的配置使用。(三个地方分别对应dll include lib)



构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受
构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受
构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受


05

构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受

码云有一个“强制同步”这个是可以用的,主要用于维护自己的库和远程下载,我们可以将GITHUB上的库clone到码云上下载,一般速度较快。



构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受


此外,很多常见库,码云官方也都提供了下载。



构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受


06

构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受

实现成功autobot的要点

注意!一定要采用特征分支!比如我这里



构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受


是jsxyhelu:add_deepgreen_colormap 向opencv:3.4中进行pr。在网站中创建特征分支的方法是直接在这里输入你的新bransh名称。



构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受


团队详情

OpenCV中国团队于2019年9月由深圳市人工智能与机器人研究院支持成立,非营利目的,致力于OpenCV的开发、维护和推广工作。

构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受
构建自己的专用OpenCV----记录一次由applyColorMap()引发的探索,本文提及代码已经被OpenCV接受

-长按关注-

本文经作者jsxyhelu授权OpenCV中国团队转载

更多精彩内容“阅读原文”

右边给我一朵小花花