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
#include
#include
#include
(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算法的相关内容。