OpenCV
官方链接为:https://www.opencv.org/
官方文档链接为:https://docs.opencv.org/
OpenCV下载及安装
下载:
https://www.opencv.org/releases.html
点击该地址,win下安装点击下图方框,不同环境下载不同类型
win下安装:
win下版本下载完成后直接一个可执行程序(其实是一个自解压的zip文件),双击后直接选择安装的路径即可
选择安装路径:
OpenCV3.4.1在VS2017中的配置
首先了解对应关系:Visual Studio 2017对应vc15
- 第一步:高级系统设置 -- 系统属性 -- 环境变量 -- 用户的变量 -- Path 加入:
D:opencv-3.4.1uildx64vc15in
- 第二步:项目右键属性
VC++目录--》包含目录
C/C++ ----- Additional Include Directories:
D:opencv-3.4.1uildinclude
D:opencv-3.4.1uildincludeopencv
D:opencv-3.4.1uildincludeopencv2
VC++目录--》库目录
Linker ----- Additional Library Directories:
D:opencv-3.4.1uildx64vc15lib
- 第三步:链接器--》输入--》附加依赖项
Linker ----- Additional Dependencies:
(Debug)
opencv_world341d.lib
(release, 可不填)
opencv_world300.lib
配置完成后在项目中编辑如下代码运行进行测试,如果成功即说明配置无误:
// OpenCVTest1.cpp: 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <opencv2/opencv.hpp> #include <iostream> using namespace std; using namespace cv; int main() { Mat src = imread("D:/视频跟踪学习/images and videos/lena.png"); //图片路径自行修改 if (src.empty()) { printf("could not load image... "); return -1; } namedWindow("test opencv", CV_WINDOW_AUTOSIZE); imshow("test opencv", src); waitKey(0); cout << "1244124" << endl; system("pause"); return 0; }
能够弹出图片证明配置成功,可以进行下步学习。
加载图像(cv::imread)
imread的功能是加载图像文件成为一个Mat对象,其中第一个参数表示图像文件名称,第二个参数表示图像时什么类型,第二个参数全体如下
IMREAD_UNCHANGED = -1, //!< If set, return the loaded image as is (with alpha channel, otherwise it gets cropped). IMREAD_GRAYSCALE = 0, //!< If set, always convert image to the single channel grayscale image. IMREAD_COLOR = 1, //!< If set, always convert image to the 3 channel BGR color image. IMREAD_ANYDEPTH = 2, //!< If set, return 16-bit/32-bit image when the input has the corresponding depth, otherwise convert it to 8-bit. IMREAD_ANYCOLOR = 4, //!< If set, the image is read in any possible color format. IMREAD_LOAD_GDAL = 8, //!< If set, use the gdal driver for loading the image. IMREAD_REDUCED_GRAYSCALE_2 = 16, //!< If set, always convert image to the single channel grayscale image and the image size reduced 1/2. IMREAD_REDUCED_COLOR_2 = 17, //!< If set, always convert image to the 3 channel BGR color image and the image size reduced 1/2. IMREAD_REDUCED_GRAYSCALE_4 = 32, //!< If set, always convert image to the single channel grayscale image and the image size reduced 1/4. IMREAD_REDUCED_COLOR_4 = 33, //!< If set, always convert image to the 3 channel BGR color image and the image size reduced 1/4. IMREAD_REDUCED_GRAYSCALE_8 = 64, //!< If set, always convert image to the single channel grayscale image and the image size reduced 1/8. IMREAD_REDUCED_COLOR_8 = 65, //!< If set, always convert image to the 3 channel BGR color image and the image size reduced 1/8. IMREAD_IGNORE_ORIENTATION = 128 //!< If set, do not rotate the image according to EXIF's orientation flag.
如果不设置,默认参数为IMREAD_ANYCOLOR
常用参数如下:
IMREAD_UNCHANGED:加载原图,什么都不做
IMREAD_COLOR :表示吧原作作为BGR模式加载进来
IMREAD_GRAYSCALE : 表示吧原图作为灰度图像加载进来
注意:OpenCV支持JPG,PNG,TIFF等常见格式图像文件加载
显示图像(cv::namedWindow与cv::imshow)
- namedWindoW的功能是创建一个OpenCV窗口,它是有OpenCV自动创建与释放的,你无须去销毁他
- 常见的用法namedWindow("Window Title", WINDOW_AUTOSIZE)
- WINDOW_AUTOSIZE会自动根据图像大小,显示窗口大小,不能人为的改变窗口大小
- WINFOW_NORMAL跟QT集成的时候会使用,允许修改窗口大小
- imshow根据窗口名称显示图像到指定的窗口上去,第一个参数是窗口名称,第二个参数是Mat对象
修改图像(cv::cvtColor)
- cvtColor的功能是把图像从一个彩色空间转换到另外一个色彩空间,有三个参数,第一个参数表示源图像、第二参数表示色彩空间转换之后的图像、第三个参数表示源和目标色彩空间如:COLOR_BGR2HLS、COLOR BGR2GRAY等
cvtColor(image,gray_image,COLOR_BGR2GRAY);
保存图像(cv:imwrite)
- 保存图像文件到指定目录路径,只有8位、16位的PNG、JPG、Tiff文件格式而且是单通道或者三通道的BGR的图像才可以通过这种方式保存
- 保存PNG格式的时候可以保存透明通道的图片
- 可以指定压缩参数
案例:读取图片,然后修改图片,显示出两个图片,最后把修改后的图片保存
// OpenCVTest1.cpp: 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <opencv2/opencv.hpp> #include <iostream> using namespace std; using namespace cv; int main() { Mat src = imread("D:/视频跟踪学习/images and videos/lena.png"); if (src.empty()) { printf("could not load image... "); return -1; } namedWindow("test opencv", CV_WINDOW_AUTOSIZE); imshow("test opencv", src); Mat out_image; //cvtColor(src, out_image, CV_BGR2HLS); //这种转变方式也可以 cvtColor(src, out_image, COLOR_BGR2GRAY); namedWindow("change window", CV_WINDOW_AUTOSIZE); imshow("change window", out_image); imwrite("D:/change.png", out_image); waitKey(0); system("pause"); return 0; }
矩阵的掩膜操作
获取图像像素指针
- CV_Assert(mylmage.depth() == CV_8U);
- Mat.ptr<uchar>(int i=0)获取像素矩阵的指针,索引 i 表示第几行,从0开始计行数。
- 获得当前行指针const uchar* current=mylmage.ptr<uchar>(row);
- ·获取当前像素点P(row,col)的像素值p(row,col)=curent[col]
像素范围处理saturate_cast<uchar>
- saturate_cast<uchar>(-100),返回0。
- saturate_cast<uchar>(288),返回255
- saturate_cast<uchar>(100),返回100
掩膜操作实现图像对比度调整
如上图,红色是中心像素,对每一个点通过周围的四个点,做锐化处理后,得到的图片既是调高对比度后的图片(Mat对象)
公式为I(i,j) = 5 * I(i,j) - [I(i+1,j)+I(i-1,j)+I(i,j-1)+I(i,j+1)]
实现代码如下:
#include <opencv2/opencv.hpp> #include <iostream> using namespace std; using namespace cv; int main() //图片掩膜操作 { Mat src, dst; src = imread("D:/视频跟踪学习/images and videos/lena.png"); if (src.empty()) { printf("could not load image... "); return -1; } namedWindow("test opencv", CV_WINDOW_AUTOSIZE); imshow("test opencv", src); int cols = (src.cols - 1) * src.channels(); //channels是通道,算出来为列,长度 int offsetx = src.channels(); //通道数 int rows = src.rows; //行数,高度 dst = Mat::zeros(src.size(), src.type()); for (int row = 1; row < (rows - 1); row++) //从(1,1)开始,行数外层循环 { const uchar* previous = src.ptr<uchar>(row - 1); //获取当前行的指针 const uchar* current = src.ptr<uchar>(row); //获取上一行的指针 const uchar* next = src.ptr<uchar>(row + 1); //获取下一行指针 uchar* output = dst.ptr<uchar>(row ); //按旧图行数获取新图当前行指针 for (int col = offsetx; col < cols; col++) //列数内层循环 { output[col] = saturate_cast<uchar>(5 * current[col] - (current[col - offsetx] + current[col + offsetx] + previous[col] + next[col])); } } namedWindow("changed opencv", CV_WINDOW_AUTOSIZE); imshow("changed opencv", dst); waitKey(0); return 0; }
左图为锐化处理后的图片
Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, - 1, 0); //定义掩膜 filter2D(src, dst, src.depth(), kernel); //其中src与dst是Mat类型变量、src.depth表示位图深度,有32、24、8等。
计算运行素的代码如下:
double t = getTickCount(); 。。。。。。。。。。。。。。。 。。。。。。。。。。。。。。。 double timeconsume = (getTickCount() - t) / getTickFrequency(); printf("time consume %.2f", timeconsume);
上面简化后的代码:
#include <opencv2/opencv.hpp> #include <iostream> using namespace std; using namespace cv; int main() //图片掩膜操作 { Mat src, dst; src = imread("D:/视频跟踪学习/images and videos/lena.png"); if (src.empty()) { printf("could not load image... "); return -1; } namedWindow("test opencv", CV_WINDOW_AUTOSIZE); imshow("test opencv", src); double t = getTickCount(); Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, - 1, 0); //定义掩膜 filter2D(src, dst, src.depth(), kernel); //其中src与dst是Mat类型变量、src.depth表示位图深度,有32、24、8等。 double timeconsume = (getTickCount() - t) / getTickFrequency(); printf("time consume %.2f", timeconsume); namedWindow("changed opencv", CV_WINDOW_AUTOSIZE); imshow("changed opencv", dst); waitKey(0); return 0; }
效果和上面相同