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