OpenCV Memo

有关 OpenCV 的安装和 (Python) 接口使用

安装

OpenCV 2.4

1
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D WITH_TBB=ON -D BUILD_NEW_PYTHON_SUPPORT=ON -D WITH_V4L=ON -D INSTALL_C_EXAMPLES=ON -D INSTALL_PYTHON_EXAMPLES=ON -D BUILD_EXAMPLES=ON -D WITH_QT=ON -D WITH_OPENGL=OFF -D WITH_OPENMP=ON -D WITH_CUDA=OFF ..

OpenCV 3.x.x

Ubuntu

安装编译依赖

1
2
3
4
5
6
sudo apt install --assume-yes build-essential cmake git
sudo apt install --assume-yes build-essential pkg-config unzip ffmpeg qtbase5-dev python-dev python3-dev python-numpy python3-numpy
sudo apt install --assume-yes libopencv-dev libgtk-3-dev libdc1394-22 libdc1394-22-dev libjpeg-dev libpng12-dev libtiff5-dev libjasper-dev
sudo apt install --assume-yes libavcodec-dev libavformat-dev libswscale-dev libxine2-dev libgstreamer0.10-dev libgstreamer-plugins-base0.10-dev
sudo apt install --assume-yes libv4l-dev libtbb-dev libfaac-dev libmp3lame-dev libopencore-amrnb-dev libopencore-amrwb-dev libtheora-dev
sudo apt install --assume-yes libvorbis-dev libxvidcore-dev v4l-utils

从 github 上获取 OpenCV 源码, 并且同时获取 opencv_contrib 的源码
Itseez/opencv clone opencv 的源码
Itseez/opencv_contrib clone opencv contrib 的源码, 这里面包含了 SIFT 等算法的代码
分别进入上述两个源码的目录, 然后分别 checkout 到 v3.1.0
进入 opencv 的源码目录, 创建 build 目录 mkdir build
进入 上述 build 目录, 执行下面的命令

1
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D WITH_TBB=ON -D WITH_V4L=ON -D WITH_QT=ON -D WITH_OPENGL=ON -D WITH_CUBLAS=ON -DCUDA_NVCC_FLAGS="-D_FORCE_INLINES" -D WITH_CUDA=ON -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules ..

如果不打算启用 CUDA, 把上述命令中有关 CUDA 的选项关闭.

编译和安装
经典的方法

1
2
3
4
sudo make install
sudo /bin/bash -c 'echo "/usr/local/lib" > /etc/ld.so.conf.d/opencv.conf'
sudo ldconfig
sudo apt-get update

推荐方法(使用 checkinstall)

1
2
sudo apt-get install checkinstall
sudo checkinstall

CentOS

安装依赖

1
2
pip install numpy
yum install -y cmake python-devel gcc gcc-c++ gtk2-devel libv4l-devel ffmpeg-devel gstreamer-plugins-base-devel libpng-devel libjpeg-turbo-devel jasper-devel openexr-devel libtiff-devel libwebp-devel tbb-devel eigen3-devel

安装 Python3, 见 Python Memo, 然后需要确保在 $PATH 中可以找到 python3

1
ln -s /usr/bin/python3.6 /usr/bin/python3

注意 cmake 的时候选项

1
2
# -DWITH_FFMPEG=ON, 打开 video 的支持
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D WITH_TBB=ON -D WITH_V4L=ON -D WITH_QT=OFF -D WITH_OPENGL=ON -D WITH_CUBLAS=OFF -D WITH_CUDA=OFF -D WITH_LAPACK=OFF -DWITH_FFMPEG=ON -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib-3.2.0/modules -DCMAKE_INSTALL_PREFIX=$(python3 -c "import sys; print(sys.prefix)") -DPYTHON_EXECUTABLE=$(which python3) ..

如果安装 Python2版本, 去掉上面的

1
-DCMAKE_INSTALL_PREFIX=$(python3 -c "import sys; print(sys.prefix)") -DPYTHON_EXECUTABLE=$(which python3)

下面看情况, 可以修改 PYTHONPATH 实现, 即把 /usr/local/lib/python2.7/site-packages 加到环境变量前边, 优先搜索
Python wrapper

1
sudo mv /usr/local/lib/python2.7/site-packages/cv2.so /usr/lib/python2.7/site-packages

Coding

读取视频为帧数据:

1
2
3
4
5
6
import cv2
import sys
cap = cv2.VideoCapture(sys.argv[1])
while(cap.isOpened()):
ret, frame = cap.read() # frame 中即为读取的图像数据, ret 表示是否读取成功
cap.release()

读取/处理/生成视频

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import cv2
import sys
import numpy as np
import requests
import commentjson as json
def predict(mat, width, height):
url = "http://10.84.146.38:8080"
ret, raw_img = cv2.imencode(".jpg", mat)
img = {"image": bytearray(raw_img)}
res = requests.post(url, files=img)
contour = json.loads(res.text)["result"]
contour = [np.array(c) for c in contour]
cv2.drawContours(mat, contour, -1, (255, 0, 0), cv2.FILLED)
return mat.copy()
cap = cv2.VideoCapture(sys.argv[1])
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)+0.5)
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)+0.5)
out = cv2.VideoWriter(sys.argv[2], fourcc, 10.0, (width, height))
counts = 0
while(cap.isOpened()):
ret, frame = cap.read()
if ret is True:
frame = predict(frame, width, height)
out.write(frame)
counts+=1
print(counts)
else:
break
cap.release()
out.release()

灰度拉伸

cv2.normalize(src[, dst[, alpha[, beta[, norm_type[, dtype[, mask]]]]]]) –> dst
设置 norm_type=cv2.NORM_MINMAX
alpha: 拉伸后的最小值
beta: 拉伸后的最大值
例如, 拉伸到 0 到 255

1
dst = cv2.normalize(src=src, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX)

像素值的线性变换

cv2.convertScaleAbs(src[, dst[, alpha[, beta]]]) –> dst
\[ g(x)=\alpha \cdot f(x) + \beta \]
计算之后, 大于 255 的值被截断到 255

填充 contours

关键点是 cv2.FILLED

1
cv2.drawContours(zeros, [np.array(c) for c in contours], -1, (255, 255, 255), cv2.FILLED)

直接使用内存中的数据

1
mat = cv2.imdecode(np.asarray(bytearray(open(f))), 1)