引言
這一系列文章總結(jié)了常用的計(jì)算機(jī)視覺(jué)算法及其 OpenCV (C++) 實(shí)現(xiàn)。
這些文章最初是作者本人學(xué)習(xí)下邊這本書(shū)的筆記:
Robert Laganiere. OpenCV 3 Computer Vision Application Programming Cookbook. 2017
然后添加了一些總結(jié),增補(bǔ)了一些理論推導(dǎo)。
發(fā)布這些文章的目的是方便作者本人及感興趣的讀者查閱。
文中的示例代碼可以在原書(shū)作者的 github repo 中查看
https://github.com/laganiere/OpenCV3Cookbook
安裝
- 平臺(tái): ubuntu18.04 + python 3.6
安裝步驟主要參考這篇文章:https://www.pyimagesearch.com/2018/05/28/ubuntu-18-04-how-to-install-opencv/
安裝過(guò)程中如果遇到 cuda 路徑的問(wèn)題,解決方案如下:https://www.cnblogs.com/thmx/p/8565530.html
準(zhǔn)備工作
- 安裝開(kāi)發(fā)者工具
sudo apt update
sudo apt upgrade
sudo apt install build-essential cmake unzip pkg-config
- 安裝 image I/O package,以便 opencv 處理這些圖片格式
sudo apt install libjpeg-dev libpng-dev libtiff-dev
- 安裝 jasper library,其中包含了多種圖像操作庫(kù)
sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu xenial-security main"
sudo apt update
sudo apt install libjasper1 libjasper-dev
- 安裝視頻流相關(guān) package
sudo apt install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev
sudo apt install libxvidcore-dev libx264-dev
- 安裝 opencv 中 highgui module 的依賴(lài) GTK library
sudo apt install libgtk-3-dev
- 下述 library 可以?xún)?yōu)化 opencv 的某些操作
sudo apt install libatlas-base-dev gfortran
- 安裝 python 3.6 的相關(guān) headers 和 libraries
sudo apt install python3.6-dev
# 如果是其他版本的 python,例如 python 2.7,則可以用如下命令
# sudo apt install python2.7-dev
獲取 OpenCV
OpenCV 從 3.0 版本開(kāi)始分成了兩個(gè)部分
opencv :包含成熟算法的主源碼庫(kù)
opencv_contrib:最近加入的更先進(jìn)的算法庫(kù)或者在活躍更新中的庫(kù),也包含一些付費(fèi)的庫(kù)
從 github 上可以獲取最新的源碼:
cd ~
git clone https://github.com/Itseez/opencv.git
git clone https://github.com/Itseez/opencv_contrib.git
或者下載特定版本的壓縮包 (以3.2版本為例)
wget https://github.com/opencv/opencv/archive/3.2.0.tar.gz
tar -xvzf 3.2.0.tar.gz
wget https://github.com/opencv/opencv_contrib/archive/3.2.0.zip
unzip 3.2.0.zip
為了方便起見(jiàn),以上解壓的文件夾分別改名為 opencv 和 opencv_contrib
編譯與安裝
上述下載的是 OpenCV 的源碼,我們需要編譯成二進(jìn)制文件才能被其他程序調(diào)用。
要區(qū)分源碼和編譯好的二進(jìn)制文件
要查詢(xún)?cè)创a,就去找剛才下載的文件;
要調(diào)用 OpenCV 庫(kù)函數(shù),目錄在編譯的目標(biāo)地址中。
編譯時(shí), OpenCV 會(huì)根據(jù)本機(jī)環(huán)境,自動(dòng)設(shè)置某些功能是否啟用,也可以通過(guò)參數(shù)配置進(jìn)行個(gè)性化的編譯:
cd ~/opencv
mkdir build
cd build
cmake -D CMAKE_BUILD_TYPE=RELEASE \
-D CMAKE_INSTALL_PREFIX=/usr/local \
-D WITH_CUDA=OFF \
-D INSTALL_PYTHON_EXAMPLES=ON \
-D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib/modules \
-D OPENCV_ENABLE_NONFREE=ON \
-D BUILD_EXAMPLES=ON ..
上述 cmake 配置過(guò)程中經(jīng)常如下問(wèn)題
-
最常遇到的是網(wǎng)絡(luò)鏈接的問(wèn)題,導(dǎo)致
ippicv,boostdesc,vgg等文件無(wú)法下載,這里關(guān)鍵是raw.githubusercontent.com這個(gè)地址無(wú)法鏈接。一個(gè)解決方案是將該地址替換為代理地址。
具體設(shè)置如下:- ippicv 下載:將
opencv/3rdparty/ippicv/downloader.cmake中的下載地址https://raw.githubusercontent.com/...替換為https://ghproxy.com/https://raw.githubusercontent.com/,即在原地址前邊添加代理網(wǎng)址https://ghproxy.com/ - boostdesc, vgg 下載:將
opencv_contrib/modules/xfeatures2d/cmake路徑下的兩個(gè)文件download_boostdesc.cmake和download_vgg.cmake中的 raw.githubusercontent.com 網(wǎng)址也修改為添加代理的地址。
- ippicv 下載:將
如果出現(xiàn)
stdlib.h: No such file or directory這類(lèi)錯(cuò)誤,需要在 cmake 命令中添加參數(shù)-D ENABLE_PRECOMPILED_HEADERS=OFF
- 如果出現(xiàn)
opencv2/xfeatures2d/cuda.hpp: No such file or directory之類(lèi)的錯(cuò)誤,參考這篇文章:https://www.cnblogs.com/thmx/p/8565530.html
實(shí)際上這個(gè)cuda.hpp文件在~/opencv_contrib/modules/xfeatures2d/include/opencv2/xfeatures2d目錄下,可以直接在報(bào)錯(cuò)的文件中,指明完整的路徑,例如:
#include "<YOUR_PATH>/opencv_contrib/modules/xfeatures2d/include/opencv2/xfeatures2d/cuda.hpp"
對(duì)于其他類(lèi)似的問(wèn)題,也可以用這種直接提供絕對(duì)路徑的方法,可以避免找不到文件的問(wèn)題。
- 如果出現(xiàn)
‘CODEC_FLAG_GLOBAL_HEADER’ was not declared in this scope,‘AVFMT_RAWPICTURE’ was not declared in this scope之類(lèi)的錯(cuò)誤,可以將下列預(yù)處理指令加入文件opencv/modules/highgui/src/cap_ffmpeg_impl.hpp的頭部:
#define AV_CODEC_FLAG_GLOBAL_HEADER (1 << 22)
#define CODEC_FLAG_GLOBAL_HEADER AV_CODEC_FLAG_GLOBAL_HEADER
#define AVFMT_RAWPICTURE 0x0020
上述配置沒(méi)有問(wèn)題之后,進(jìn)行下邊的編譯和安裝:
make -j8 # 多用幾個(gè)線(xiàn)程提高編譯效率,但也可能把機(jī)子卡死
sudo make install # 默認(rèn)安裝到 /usr/local/bin 目錄中
sudo ldconfig # 更新動(dòng)態(tài)鏈接庫(kù)
檢查安裝是否成功
可用如下命令查看動(dòng)態(tài)鏈接庫(kù)中是否有了 opencv :
ldconfig -p | grep opencv # -p = print
或者嘗試用 pkg-config 查找 opencv
pkg-config --modversion opencv
結(jié)果應(yīng)為剛剛安裝的 opencv 版本號(hào),例如
3.2.x
卸載 opencv
進(jìn)入前邊的 build 文件夾,也就是之前使用 make 命令的文件夾。
剛才用了命令 make install,卸載只需要 make uninstall。
然后刪掉所有的 opencv 和 opencv_contrib 源碼文件夾即可。
OpenCV 結(jié)構(gòu)
文檔位置
我們?cè)谡{(diào)用 opencv 時(shí)只需要用到相關(guān)的頭文件和庫(kù)文件。
編譯時(shí)可以設(shè)置這些文件的存放位置,默認(rèn)位置如下:
- 頭文件存放在 /usr/local/include/opencv2
- 庫(kù)文件存放在 /usr/local/lib
主要 modules
-
core:這是必須加載的,包含所有的基本對(duì)象類(lèi)型和基本操作 -
highgui( 在 opencv 3 版本中拆分成了 imgcodecs, videoio, highgui):如果要顯示圖像,就必須加載這個(gè),同時(shí)也包含了用戶(hù)交互工具 -
imgproc:包含基本的圖像變換操作,例如圖像濾波、圖像幾何變換等 -
video:包含讀、寫(xiě)視頻流的操作,跟蹤、背景切割等 -
calib3d:包含相機(jī)校準(zhǔn)和三維重建相關(guān)的算法,例如基本的多視角幾何算法、立體攝像頭標(biāo)定、物體姿態(tài)估計(jì)、立體相似性算法、3D 信息重建等。 -
features2d:包含 2D 特征檢測(cè)、描述、匹配算法 -
objdetect:包含特定物體檢測(cè)算法,例如臉、行人,也可以訓(xùn)練檢測(cè)其他物體。 -
ml:包含了很多機(jī)器學(xué)習(xí)算法,基本上是統(tǒng)計(jì)模型和分類(lèi)算法。 -
flann:Fast Library for Approximate Nearest Neighbors. 這個(gè) module 一般不會(huì)被直接調(diào)用,而是在其他 module 進(jìn)行最近鄰搜索中使用。 -
gpu(在 opencv 3 中被拆分成多個(gè) cuda* modules):包含了專(zhuān)門(mén)為 CUDA GPU 優(yōu)化的算法實(shí)現(xiàn),涵蓋了上述部分 module 中的功能。 -
photo:包含計(jì)算攝影(computational photography)的算法,例如照片修復(fù)、去噪之類(lèi)的 -
stitching:提供了圖像拼接整個(gè)流程算法
另外,除了標(biāo)準(zhǔn)的 opencv 庫(kù),還有一個(gè) opencv_contrib 庫(kù),里面包含了最新的、尚未被集成到標(biāo)準(zhǔn)庫(kù)中的算法,以及 non-free 的算法。
調(diào)用方式
在 c++ 中 include 時(shí)可以只寫(xiě)
#include <opencv2/opencv.hpp>
打開(kāi) opencv.hpp 源文件可以看到它實(shí)際上包含了所有的其他頭文件??紤]到 C++ 編譯流程,頭文件是要被加載到 .cpp 文件中的,因此用這種方式 include 頭文件肯定沒(méi)有問(wèn)題,但是 more than enough ,編譯時(shí)間比較長(zhǎng)。
更好的辦法是指明要添加的具體的頭文件,例如
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
這樣做的好處一方面是編譯時(shí)間短,另一方面是強(qiáng)化記憶,迫使編程人員清楚的知道程序中的函數(shù)來(lái)自哪個(gè) OpenCV 模塊。
另外,關(guān)于 opencv 具體模塊的調(diào)用還有兩種常見(jiàn)的形式,例如調(diào)用 highgui 模塊:
- 方式一:
#include <opencv2/highgui/highgui.hpp> - 方式二:
#include <opencv2/highgui.hpp>
這兩種方式涉及到 openv 2.4 和 opencv 3 之間的區(qū)別。
這里有 OpenCV 官方的解釋
https://docs.opencv.org/3.2.0/db/dfa/tutorial_transition_guide.html
總結(jié)來(lái)說(shuō):
- 在 opencv 2.4 中,所有的頭文件都在相應(yīng)的 module 文件夾下,因此必須要用方式一調(diào)用。
- 在 opencv 3 中,與 module 文件夾同級(jí)目錄中添加了相應(yīng)的頭文件,因此可以直接用方式二調(diào)用,而不需要再進(jìn)入 module 文件夾。如果很重視程序的向后兼容性問(wèn)題,在 opencv 3 中也要用方式一調(diào)用頭文件。