OpenCV的常用用法(C++版)
一、简介
OpenCV是一个基于Apache2.0许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在Linux、Windows、Android和Mac OS操作系统上。 它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。
OpenCV用C++语言编写,它具有C ++,Python,Java和MATLAB接口,并支持Windows,Linux,Android和Mac OS,OpenCV主要倾向于实时视觉应用,并在可用时利用MMX和SSE指令, 如今也提供对于C#、Ch、Ruby,GO的支持。
二、OpenCV的基本操作
(1)OpenCV包含的头文件
# include <opencv2/imgcodecs.hpp>
# include <opencv2/highgui.hpp>
# include <opencv2/imgproc.hpp>
# include <opencv2/opencv.hpp>
(2)OpenCV查看图片
int main ( ) {
string path = "Resources/test.png" ;
Mat img = imread ( path) ;
namedWindow ( "Image" ) ;
imshow ( "Image" , img) ;
waitKey ( 6000 ) ;
return 0 ;
}
(3)OpenCV查看视频
int main ( ) {
string path = "Resources/test_video.mp4" ;
VideoCapture cap ( path) ;
Mat img;
while ( true) {
cap. read ( img) ;
imshow ( "Image" , img) ;
waitKey ( 20 ) ;
}
return 0 ;
}
(4)OpenCV查看摄像头
int main ( ) {
VideoCapture cap ( 0 ) ;
Mat img;
while ( true) {
cap. read ( img) ;
imshow ( "Image" , img) ;
waitKey ( 1 ) ;
}
return 0 ;
}
(5)改变图片颜色
void cvtColor ( InputArray src, OutputArray dst, int code, int dstCn = 0 ) ;
-- 返回值:无
-- 参数:
-- InputArray src:传入的图片名称
-- OutputArray dst:传出的图片名称
-- int code:需要改变的颜色,例如灰色为:COLOR_BGR2GRAY
(6)高斯模糊
void GaussianBlur ( InputArray src, OutputArray dst, Size ksize,
double sigmaX, double sigmaY ) ;
-- 返回值:无
-- 参数::
-- InputArray src:传入的图片名称
-- OutputArray dst:传出的图片名称
-- Size ksize:高斯核,通常取0 - 9 ,越高越模糊
-- double sigmaX, double sigmaY:x和y方向上的标准差
(7)边缘检测
void Canny ( InputArray image, OutputArray edges,
double threshold1, double threshold2)
-- 返回值:无
-- 参数:
-- InputArray image:传入的图片名称
-- OutputArray edges:传出的图片名称
-- double threshold1, double threshold2: 二者的取值会决定边缘的清晰与否(15 , 75 )
(8)膨胀(由于在进行边缘检测时可能在某些边缘会断开,经过膨胀会连在一起)
void dilate ( InputArray src, OutputArray dst, InputArray kernel)
-- 返回值:无
-- 参数:
-- InputArray image:传入的图片名称
-- OutputArray edges:传出的图片名称
-- InputArray kernel:结构元素,定义如下:
Mat kernel = getStructuringElement ( MORPH_RECT, Size ( 5 , 5 ) )
(9)腐蚀(经过膨胀后的图像经过腐蚀线条会变细,这样断开的边缘会连接在一块)
void erode ( InputArray src, OutputArray dst, InputArray kernel)
-- 返回值:无
-- 参数:
-- InputArray image:传入的图片名称
-- OutputArray edges:传出的图片名称
-- InputArray kernel:结构元素,定义如下:
Mat kernel = getStructuringElement ( MORPH_RECT, Size ( 5 , 5 ) )
(10)重新定义大小
void resize ( InputArray src, OutputArray dst, Size dsize,double fx = 0 , double fy = 0 )
-- 返回值:无
-- 参数:
-- InputArray image:传入的图片名称
-- OutputArray edges:传出的图片名称
-- Size dsize:size ( ) ; 如果有具体的数字在括号里输入
-- double fx = 0 , double fy = 0 :如果没有具体的数字,后面两位是按照比例进行缩放
(11)裁剪
Rect roi ( 200 , 100 , 300 , 300 ) ;
imgCrop = img ( roi) ;
(12)自行绘制图片的过程
Mat img ( 512 , 512 , CV_8UC3, Scalar ( 255 , 255 , 255 ) ) ;
circle ( img, Point ( 256 , 256 ) , 155 , Scalar ( 0 , 244 , 234 ) , - 1 ) ;
rectangle ( img, Point ( 130 , 226 ) , Point ( 382 , 286 ) , Scalar ( 0 , 0 , 255 ) , - 1 ) ;
line ( img, Point ( 130 , 296 ) , Point ( 382 , 296 ) , Scalar ( 0 , 0 , 255 ) , 2 ) ;
putText ( img, "hello world" , Point ( 180 , 260 ) , FONT_HERSHEY_DUPLEX, 0.75 , Scalar ( 0 , 69 , 0 ) , 2 ) ;
imshow ( "Image" , img) ;
waitKey ( 0 ) ;
(13)图片透视(简单点说就是将一张非平铺的图片输出为平铺)
Point2f src[ 4 ] = { { 777 , 107 } , { 1021 , 82 } , { 840 , 359 } , { 1117 , 337 } } ;
Point2f dst[ 4 ] = { { 0.0f , 0.0f } , { w, 0.0f } , { 0.0f , h} , { w, h} } ;
matrix = getPerspectiveTransform ( src, dst) ;
warpPerspective ( img, imgWarp, matrix, Point ( w, h) ) ;
for ( int i = 0 ; i < 4 ; i++ ) {
circle ( img, src[ i] , 10 , Scalar ( 0 , 0 , 255 ) , - 1 ) ;
(14)颜色检测(这段代码是需要手动来确定图片的色调、饱和度和明度)
cvtColor ( img, imgHSV, COLOR_BGR2HSV) ;
namedWindow ( "Trackbars" , ( 640 , 200 ) ) ;
createTrackbar ( "Hue Min" , "Trackbars" , & hmin, 179 ) ;
createTrackbar ( "Hue Max" , "Trackbars" , & hmax, 179 ) ;
createTrackbar ( "Sat Min" , "Trackbars" , & smin, 255 ) ;
createTrackbar ( "Sat Max" , "Trackbars" , & smax, 255 ) ;
createTrackbar ( "Val Min" , "Trackbars" , & vmin, 255 ) ;
createTrackbar ( "Val Max" , "Trackbars" , & vmax, 255 ) ;
while ( true) {
Scalar lower ( hmin, smin, vmin) ;
Scalar upper ( hmax, smax, vmax) ;
inRange ( imgHSV, lower, upper, mask) ;
imshow ( "Image" , img) ;
imshow ( "Image HSV" , imgHSV) ;
imshow ( "Image mask" , mask) ;
waitKey ( 1 ) ;
}
waitKey ( 0 ) ;
(14)轮廓检测
void getContours ( Mat imgDil, Mat img) {
vector< vector< Point>> contours;
vector< Vec4i> hierarchy;
findContours ( imgDil, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE) ;
vector< vector< Point>> conPoly ( contours. size ( ) ) ;
vector< Rect> boundRect ( contours. size ( ) ) ;
for ( int i = 0 ; i < contours. size ( ) ; i++ ) {
int area = contourArea ( contours[ i] ) ;
string objectType;
if ( area > 1000 ) {
float peri = arcLength ( contours[ i] , true) ;
approxPolyDP ( contours[ i] , conPoly[ i] , 0.02 * peri, true) ;
boundRect[ i] = boundingRect ( conPoly[ i] ) ;
int objCor = ( int ) conPoly[ i] . size ( ) ;
if ( objCor == 3 ) { objectType = "Tri" ; }
else if ( objCor == 4 ) {
float aspRatio = ( float ) boundRect[ i] . width / ( float ) boundRect[ i] . height;
if ( aspRatio > 0.95 && aspRatio < 1.05 ) { objectType = "Square" ; }
else objectType = "Rect" ;
}
else if ( objCor > 4 ) { objectType = "Circle" ; }
rectangle ( img, boundRect[ i] . tl ( ) , boundRect[ i] . br ( ) , Scalar ( 0 , 255 , 0 ) , 5 ) ;
putText ( img, objectType, { boundRect[ i] . x, boundRect[ i] . y - 5 } , FONT_HERSHEY_PLAIN, 1 , Scalar ( 0 , 69 , 255 ) , 1 ) ;
}
}
}
(15)人脸检测
CascadeClassifier faceCascade;
faceCascade. load ( "Resources/haarcascade_frontalface_default.xml" ) ;
if ( faceCascade. empty ( ) ) {
cout << "脸部识别加载失败" << endl;
}
vector< Rect> faces;
Mat img = imread ( "path_to_image.jpg" ) ;
faceCascade. detectMultiScale ( img, faces, 1.1 , 10 ) ;
for ( int i = 0 ; i < faces. size ( ) ; i++ ) {
rectangle ( img, faces[ i] . tl ( ) , faces[ i] . br ( ) , Scalar ( 255 , 0 , 255 ) , 3 ) ;
}
三、总结
上面的内容为OpenCV的一些基本操作,如果只是需要简单的使用OpenCV来完成一些功能,应该已经足够;如果需要使用OpenCV完成更加复杂的图像操作,需要更加深入的去了解CV算法的相关内容。