OpenCV Basics - Others
1. YUV && YUVI420
- YUV,是一种颜色编码方法, 考虑到人类的感知能力,允许降低色度的带宽。“Y”表示明亮度(Luminance)即灰度值,“U”和“V”则是色度、浓度(Chrominance)
- 分成两个存储格式:
- 紧缩格式(packed formats):将Y、U、V值存储成Macro Pixels数组,和RGB的存放方式类似。
- 平面格式(planar formats):将Y、U、V的三个分量分别存放在不同的矩阵中,方便取出不同的平面
- YUV中只传送Y通道信息,显示完整的黑白图像,兼容黑白电视
- 对于UV通道,可以降采样,从而降低带宽,有3种方式:
- YUV 4:4:4采样,每一个Y对应一组UV分量,没有降低存储
- YUV 4:2:2采样,每两个Y共用一组UV分量:YUYV或者UYVY顺序排列存储,存储变为2/3。另:YUV422P,即平面格式,存完所有的Y,再存U,最后V
- YUV 4:2:0采样,每四个Y共用一组UV分量:YV12,YU12,只有Planar模式,Y00,01,10,11共用U00和V00,3个平面依次存储YYYYYYYY UU VV;NV12,NV21,2个平面,UV合为一个平面交替存储YYYYYYYY UVUV。存储变为1/2,即UV都是之前的1/4
2. OpenCV编译
a. OpenCV 3.3.1, world和static_lib不可同时enable
否则会报错:Error LNK1181 cannot open input file ‘opencv_calib3d.lib’
官方解释 Static opencv_world is not supported - this configuration make no sense (no improvements from regular static build). 就是说world是为了方便,如果是dll只拷贝一个即可,static lib本身不需要dll,编译后即打包进可执行文件,没必要整出一个world来
b. 编译OpenCV,删减版,体积是1/5
- BUILD_CUDA等非build_opencv开头的,都关掉,只保留BUILD_WITH_DEBUG_INFO
- BUILD_opencv开头的,只保留:calib3d,core,features2d,flann,highgui,imgcodecs,imgproc,shape,video,videoio
- WITH_开头的,只保留:JPEG,VFW(windows打开camera/video需要),WIN32UI。With_TBB可以不打勾,这样打包dll时都能打包进去,不需要依赖tbb.dll
- opencv_dnn开头的,全部关掉
- 参考配置opencv_config.cmake
c. BUILD_WITH_STATIC_CRT设置为false,否则编译static lib的话默认是true
d. build script
e. Mac和Linux编译OpenCV之后,OpenCVConfig.cmake没有默认安装到install根目录,OpenCV_DIR指向share/OpenCV/即可。cmake相关文件在那里,切不可自己从外边拷贝一份进去
f. 如果用高版本gcc(>=5)编译,需要在根目录的CMakelist.txt里加如下编译选项
Note: 另外,同一个工程引用不同的第三方lib,都需要用同一个版本的gcc编译,否则会引入未知奇怪的错误!
其中:
-
_GLIBCXX_USE_CXX11_ABI: 对于link时报错undefined reference std::__cxx11::basic_string,gcc官方说明(gcc高于5默认打开了_GLIBCXX_USE_CXX11_ABI):
If you get linker errors about undefined references to symbols that involve types in the std::__cxx11 namespace or the tag [abi:cxx11] then it probably indicates that you are trying to link together object files that were compiled with different values for the _GLIBCXX_USE_CXX11_ABI macro. This commonly happens when linking to a third-party library that was compiled with an older version of GCC. If the third-party library cannot be rebuilt with the new ABI then you will need to recompile your code with the old ABI.
- set(CMAKE_CXX_STANDARD 11):对于link时报错undefined reference to ‘operator delete(void*, unsigned long)’,是因为gcc6/7 or higher,默认的delete函数是这样的形式,也就是c++14中的形式,强制都设置成c11能避免很多问题
- ld程序版本不一致,也会有问题:unrecognized relocation。比如用ld 2.26编译好了opencv,给2.24ld的机器用,link的时候必然报错。解决方法是降级编译opencv的ld,或升级用opencv的机器的ld:
“unrecognized relocation” occurs when the relocation type is greater than the greatest known relocation type in your version of ld
g. opencv依赖protobuf,避免与其他库依赖的protobuf冲突ref
- opencv中,opencv_dnn依赖与protobuf,可以直接关掉,干脆不依赖protobuf:-DBUILD_opencv_dnn=OFF -DBUILD_PROTOBUF=OFF
- 如果确实需要,那就用本地同一套protobuf,opencv自己下载的protobuf源码可能是3.3.1,需要关掉:
- -D BUILD_PROTOBUF=OFF PROTOBUF_UPDATE_FILES=ON
- -D PROTOBUF_INCLUDE_DIR=… Protobuf_PROTOC_EXECUTABLE=… Protobuf_LIBRARY=…
3. OpenCV的CMake集成
4. FFMPEG视频编解码
-
On Linux and other Unix flavors, OpenCV uses default or user-built ffmpeg/libav libraries. If user builds ffmpeg/libav from source and wants OpenCV to stay BSD library, not GPL/LGPL, should use –enabled-shared and make sure that no GPL components are enabled.
-
If you do not want to use FFMPEG at all, regardless of whether it’s installed on your system or not, configure and build OpenCV using CMake with WITH_FFMPEG=OFF flag. OpenCV will then use AVFoundation (OSX), GStreamer (Linux) or other available backends supported by opencv_videoio module.
-
There is also our self-contained motion jpeg codec, which you can use without any worries. It handles CV_FOURCC(‘M’, ‘J’, ‘P’, ‘G’) streams within an AVI container (“.avi”).