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.1\build\x64\vc15\bin
• 第二步:项目右键属性
VC++目录--》包含目录
C/C++ ----- Additional Include Directories:
D:\opencv-3.4.1\build\includeD:\opencv-3.4.1\build\include\opencv
D:\opencv-3.4.1\build\include\opencv2
VC++目录--》库目录
Linker ----- Additional Library Directories:
D:\opencv-3.4.1\build\x64\vc15\lib• 第三步:链接器--》输入--》附加依赖项
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...\n");
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...\n");
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>
将不再范围内的像素点归并到范围内,确保RGB值得范围在0~255之间 :
- 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...\n");
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;
}
左图为锐化处理后的图片
函数调用filter2D功能直接进行锐化处理
OpenCV有专门的函数可直接实现如上的效果,如下
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...\n");
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;
}
效果和上面相同