OpenCV
Table of Contents
1. OpenCV 简介
OpenCV (Open Source Computer Vision) is a library of programming functions mainly aimed at real-time computer vision, originally developed by Intel's research center in Nizhny Novgorod (Russia), later supported by Willow Garage and now maintained by Itseez.
1.1. 从源码安装 OpenCV 3.0.0
下面步骤的测试操作系统为 Mac OS 10.10。
Step 1. Download opencv-3.0.0.zip, and unzip it.
$ cd /full/path/to/opencv-3.0.0
Step 2. Make a build directory.
$ mkdir build $ cd build
Step 3. Configure OpenCV installation.
$ cmake -D CMAKE_INSTALL_PREFIX=/full/path/to/opencv-3.0.0/build ..
说明:这里设置安装时的位置为"/full/path/to/opencv-3.0.0/build",如果不配置,则会安装到系统的默认位置中。
Step 4. Compile the source code.
$ make
Step 5. Install library files and header files into CMAKE_INSTALL_PREFIX.
$ make install
1.1.1. 配置 pkg-config
Copy the pkg-config file opencv.pc to "/usr/local/lib/pkgconfig/opencv3.pc"
$ ln -s /full/path/to/opencv-3.0.0/build/lib/pkgconfig/opencv.pc /usr/local/lib/pkgconfig/opencv3.pc
注:这里没有真正复制,仅是创建了一个软链接。把 opencv.pc 改名为 opencv3.pc 的目的是避免系统中有多个版本的 OpenCV 时出现混乱。
1.1.2. 测试安装是否成功
编译一个自带的 sample,如人脸识别程序 facedetect.cpp。
$ cd /full/path/to/opencv-3.0.0/samples/cpp $ g++ -ggdb `pkg-config --cflags --libs opencv3` facedetect.cpp -o /tmp/facedetect
测试上面编译出来的程序,如:
$ export DYLD_LIBRARY_PATH=/full/path/to/opencv-3.0.0/build/lib:$DYLD_LIBRARY_PATH $ /tmp/facedetect
说明:DYLD_LIBRARY_PATH 是 Mac 系统中用于查找动态库的环境变量,相当于 Linux 中的环境变量 LD_LIBRARY_PATH。
当程序正常运行后,会启动摄像头。我拿了一个“抱婴腰凳”的说明书做测试,上面有 8 个人脸,识别的效果还不错,仅两个侧脸没有识别出来。如图 1 所示。
Figure 1: OpenCV 人脸识别测试示例
1.2. 安装 Python 绑定
如果你只想在 Python 中使用 OpenCV,则安装 Python 绑定即可。如:
$ pip install opencv-python # 仅安装OpenCV core modules $ pip install opencv-contrib-python # 安装OpenCV core modules和contrib modules(这个模块中包含一些有专利保护的算法,如SIFT等等) $ python Python 2.7.11 (default, Dec 26 2015, 17:47:15) [GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import cv2 >>> cv2.__version__ '3.0.0'
参考:
https://pypi.python.org/pypi/opencv-python
https://pypi.python.org/pypi/opencv-contrib-python
2. OpenCV 实例
2.1. 实例:加载和显示图像
2.1.1. Mat 类
在比较旧的 OpenCV 代码中,常用 IplImage 结构来保存加载图像。如:
#include "highgui.h" int main( int argc, char** argv ) { IplImage* img = cvLoadImage( argv[1] ); /* old code */ cvNamedWindow( "Example1", CV_WINDOW_AUTOSIZE ); cvShowImage( "Example1", img ); cvWaitKey(0); cvReleaseImage( &img ); cvDestroyWindow( "Example1" ); }
IplImage 是一个 C 结构,对于一个大型程序来说,如果忘记使用 cvReleaseImage() 释放内存,会造成内存泄漏。
对于新写的程序,推荐使用 Mat类 来存储图片。它是一个 C++类,使用它时不用显式释放内存了(超过作用域时会自动释放内存)。
Mat 的基本介绍,可参考:Mat - The Basic Image Container
要操作 Mat 所表示图像中的每个像素,可参考:How to scan images, lookup tables and time measurement with OpenCV
2.1.2. Mat 类加载显示图像
下面是加载显示图片的实例。代码摘自:http://docs.opencv.org/2.4/doc/tutorials/introduction/display_image/display_image.html
// file display_image.cpp #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <iostream> using namespace cv; using namespace std; int main( int argc, char** argv ) { if( argc != 2) { cout <<" Usage: display_image ImageToLoadAndDisplay" << endl; return -1; } Mat image; image = imread(argv[1], CV_LOAD_IMAGE_COLOR); // Read the file if( image.empty() ) // Check for invalid input { cout << "Could not open or find the image" << std::endl ; return -1; } namedWindow( "Display window", WINDOW_AUTOSIZE ); // Create a window for display. imshow( "Display window", image ); // Show our image inside it. waitKey(0); // Wait for a keystroke in the window return 0; }
用下面命令编译上面程序:
$ g++ `pkg-config --cflags --libs opencv3` display_image.cpp -o display_image
设置好环境变量 LD_LIBRARY_PATH(Mac 系统中对应为 DYLD_LIBRARY_PATH)后,测试程序:
$ ./display_image /Users/cig01/Downloads/opencv-3.0.0/samples/data/lena.jpg
启动正常后,会出现图 2 所示窗口。
Figure 2: OpenCV 实例:加载显示图片
2.2. 实例:反转灰度图像
下面是反转灰度图像的例子。
// file test_negative.cpp #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <iostream> using namespace cv; using namespace std; int main( int argc, char** argv ) { char* imageName = argv[1]; Mat image = imread( imageName, 1 ); if( argc != 2 || !image.data ) { cout <<" No image data" << endl; return -1; } namedWindow( "Original image", CV_WINDOW_AUTOSIZE ); imshow( "Original image", image ); Mat gray_image; cvtColor( image, gray_image, CV_BGR2GRAY ); // 先把彩色图像转换为灰度图像。 namedWindow( "Gray image", CV_WINDOW_AUTOSIZE ); imshow( "Gray image", gray_image ); // 把灰度图像进行“反转变换” gray_image = 255 - gray_image; // 矩阵整体操作,相当于访问每个像素,对其执行 255 - value 操作。 namedWindow( "Gray image (negative)", CV_WINDOW_AUTOSIZE ); imshow( "Gray image (negative)", gray_image ); waitKey(0); return 0; }
我们也可以显式地访问矩阵 Mat 中的每个元素,进行“反转变换”。如:
for( int x = 0; x < gray_image.rows; x++ ) { for( int y = 0; y < gray_image.cols; y++ ) { gray_image.at<uchar>(x,y) = 255 - gray_image.at<uchar>(x,y); // 灰度图像的像素在Mat中是用uchar表示的。 } }
用迭代器也可以访问 Mat 中的每个像素。如上面代码中的两个 for 循环可以用下面代码代替:
for (MatIterator_<uchar> it = gray_image.begin<uchar>(); it != gray_image.end<uchar>(); ++it) { *it = 255 - (*it); }
测试程序:
$ ./test_negative /Users/cig01/Downloads/opencv-3.0.0/samples/data/HappyFish.jpg
启动正常后,会出现如图 3 所示示例。
Figure 3: OpenCV 实例:反转灰度图像
2.3. 实例:转换彩色图像为灰度图像
2.3.1. 函数 cvtColor
在 OpenCV 中,使用函数 cvtColor 可以把图像从一个“颜色空间”转换到另一个“颜色空间”。
OpenCV 默认使用的是“BGR 颜色空间”,在 cvtColor 函数的第 3 个参数中指定 CV_BGR2GRAY 可以把彩色图像转换为灰度图像。要进行其它空间转换的转换,可以指定其它一些值,如 CV_BGR2HSV/CV_BGR2YCrCb 等等。
2.3.2. 使用 cvtColor 转换彩色图像为灰度图像
下面是转换彩色图像为灰度图像的实例。代码摘自:http://docs.opencv.org/2.4/doc/tutorials/introduction/load_save_image/load_save_image.html
// file test_bgr2gray.cpp #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <iostream> using namespace cv; using namespace std; int main( int argc, char** argv ) { char* imageName = argv[1]; Mat image; image = imread( imageName, 1 ); if( argc != 2 || !image.data ) { cout <<" No image data" << endl; return -1; } Mat gray_image; cvtColor( image, gray_image, CV_BGR2GRAY ); // 用cvtColor可以对色彩空间进行转换(这里是把彩色图像转换为灰度图像)。 imwrite( "/tmp/Gray_Image.jpg", gray_image ); // 用imwrite可以保存图像到文件 namedWindow( imageName, CV_WINDOW_AUTOSIZE ); namedWindow( "Gray image", CV_WINDOW_AUTOSIZE ); imshow( imageName, image ); imshow( "Gray image", gray_image ); waitKey(0); return 0; }
编译和测试如下:
$ g++ `pkg-config --cflags --libs opencv3` test_bgr2gray.cpp -o test_bgr2gray $ ./test_bgr2gray /Users/cig01/Downloads/opencv-3.0.0/samples/data/lena.jpg
启动正常后,会出现图 4 所示窗口。
Figure 4: OpenCV 实例:转换彩色图像为灰度图像
2.4. 实例:高斯模糊
通过函数 GaussianBlur 可以对图像进行高斯模糊。下面是实例:
#include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include "opencv2/opencv.hpp" #include "opencv2/imgproc.hpp" #include <iostream> #include <string> using namespace cv; using namespace std; int main(int argc, char *argv[]) { if( argc != 2) { cout <<" Usage: gaussianfilter ImageToProcess" << endl; return -1; } Mat srcImg; srcImg = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE); namedWindow("orignal", 1); imshow("orignal", srcImg); Mat resImg; double sigma = 4.0; GaussianBlur(srcImg, resImg, Size(0, 0), sigma, sigma); // Gaussian blur, 其中Size(0, 0)表示根据sigma计算核的大小 namedWindow("Gaussian blur", 1); imshow("Gaussian blur", resImg); waitKey(0); }
图 5 是运行上面程序进行高斯模糊的例子:
Figure 5: 高斯模糊实例