Opencv:视觉库函数学习文档
一、Opencv环境配置
基于Visual Studio 下C++/Python项目下,在视图-其他窗口-属性管理器中,一般在Debug|X64下创建Microsoft.Cpp.x64.user属性表在VC++目录下,在包含目录下放置以下文件:
D:\opencv\opencv\build\include\opencv2
D:\opencv\opencv\build\include\opencv
D:\opencv\opencv\build\include
在VC++目录下,在库目录下放置以下文件:
D:\opencv\opencv\build\x64\vc14\lib
在链接器目录下,在输入目录下放置以下文件:
opencv_world341.lib
opencv_world341d.lib
二、 读取图像文件
首先引用Opencv库文件
#include <opencv2/opencv.hpp>
using namespace cv;
OpenCV的函数都位于cv这一命名空间下,为了调用OpenCV的函数,需要在每个函数前加上cv::,向编译器说明你所调用的函数处于cv命名空间。为了摆脱这种繁琐的工作,可以使用using namespace cv;指令。
载入图像:引用imread()函数。
Mat src = imread(“D:/Downloads/XXX.jpg”);
实例:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
int main(int argc,char* argv[]) {
Mat src = imread("D:/Downloads/XXX.jpg");
if (src.empty()) {// 判断路径是否正确
printf("Count't open image...\n");
return -1;
}
namedWindow("test image", CV_WINDOW_AUTOSIZE); // 自动分辨窗体大小
imshow("test open stucp", src); // 功能主要载入一张图片
waitKey(0);
/*注释
等待按下函数:参数如果写负数或者0。
当显示图片后,按下任意键后程序退出。如果参数写为3000就是3秒后程序自动退出。
*/
return 0;
}
三、 加载、修改、保存图像
加载图像:cv::imread
修改图像:cv::cvtColor
保存图像:cv::imwrite
- 载入图像(cv::imread)
Imread功能是加载图像文件成为一个Mat对象,其中第一个参数即为图像文件名称,第二个参数,表示加载图像的类型,一般支持参见三种参数值
- IMREAD_UNCHANGED(<0)表示加载原图,不做任何改变
- IMREAD_GRAYSCALE(0)表示吧原图作为灰色图像加载
- IMREAD_COLOR(>0)表示把原图作为RGB图像加载
注意:Opencv支持JPG、PNG、TIFF等常见的格式图像文件
2)显示图像(cv::namedWindos与cv::imshow)
- namedWindos功能是创建一个Opencv窗口,它是由Opencv自动创建与释放,无需取消销毁。
- 参见用法namedWindow(“Windos Title”,WINDOW_AUTOSIZE)
- WINDOW_AUTOSIZE会自动显示窗口大小,不能人为改变大小
- Imshow根据窗口名称显示到指定窗口上,第一个参数为窗口名称,第二个参数为Mat对象
3)修改图像(cv::cvtColor)
cvtColor的功能是把图像从一个彩色空间转换到另一个彩色空间,有三个参数,第一个参数表示原图像、第二个参数表示色彩空间转换后的图像,第三个参数表示原和目标色彩空间:如COLOR_BGR2HLS等等。
样例:
namedWindow("outputs Windows", CV_WINDOW_AUTOSIZE); // 自动分辨窗体大小
Mat output_image;
cvtColor(src, output_image, CV_BGR2GRAY);
imshow("outputs Windows", output_image); // 功能主要载入一张图片
4)保存图像(cv::imwrite)
- 保存文件到指定目录
- 只有8位、16位的PNG,JPEG,TIFF文件格式并且是单通道格式或者三通道RGB格式才可以保存。
- 保存PNG格式可以保存透明通道格式图片
- 可以指定压缩参数
样例:imwrite("D:/Downloads/XXX.tif", output_image);//保存一张图片
四、矩阵的掩膜操作
- 获取图像像素指针
- 掩膜操作解释
- 代码演示
1)、获取图像像素指针 - CV_Assert(myImage.depth() == CV_8U);
- Mat.ptr(int i=0) 获取像素矩阵的指针,索引i表示第几行,从0开始计行数。
- 获得当前行指针const uchar* current= myImage.ptr(row );
- 获取当前像素点P(row, col)的像素值 p(row, col) =current[col]
2)、像素范围处理saturate_cast - saturate_cast(-100),返回 0。
- saturate_cast(288),返回255
- saturate_cast(100),返回100
- 这个函数的功能是确保RGB值得范围在0~255之间
3)、调用filter2D功能
五、 Mat对象
- Mat对象与IplImage对象
- Mat对象使用
- Mat定义数组
1)、Mat对象与IplImage对象 - Mat对象OpenCV2.0之后引进的图像数据结构、自动分配内存、不存在内存泄漏的问题,是面向对象的数据结构。分了两个部分,头部与数据部分
- plImage是从2001年OpenCV发布之后就一直存在,是C语言风格的数据结构,需要开发者自己分配与管理内存,对大的程序使用它容易导致内存泄漏问题
2)、Mat对象构造函数与常用方法
常用方法:
void copyTo(Mat mat)
void convertTo(Mat dst, int type)
Mat clone()
int channels()
int depth()
bool empty();
uchar* ptr(i=0)
3)、Mat对象使用-四个要点
- 输出图像的内存是自动分配的
- 使用OpenCV的C++接口,不需要考虑内存分配问题
- 赋值操作和拷贝构造函数只会复制头部分
- 使用clone与copyTo两个函数实现数据完全复制
六、 图像操作
- 读写图像
- 读写像素
- 修改像素值
1)、读写图像 - imread:可以指定加载为灰度或者RGB图像
- imwrite: 保存图像文件,类型由扩展名决定
2)、读写像素 - 读一个GRAY像素点的像素值(CV_8UC1)
Scalar intensity = img.at(y, x);
或者 Scalar intensity = img.at(Point(x, y)); - 读一个RGB像素点的像素值
Vec3f intensity = img.at(y, x);
float blue = intensity.val[0];
float green = intensity.val[1];
float red = intensity.val[2];
3)、修改像素值 - 灰度图像
img.at(y, x) = 128; - RGB三通道图像
img.at(y,x)[0]=128; // blue
img.at(y,x)[1]=128; // green
img.at(y,x)[2]=128; // red - 空白图像赋值
img = Scalar(0); - ROI选择
Rect r(10, 10, 100, 100);
Mat smallImg = img(r);
4)、Vec3b与Vec3F - Vec3b对应三通道的顺序是blue、green、red的uchar类型数据。
- Vec3f对应三通道的float类型数据
- 把CV_8UC1转换到CV32F1实现如下:
src.convertTo(dst, CV_32F);
反向输出图像通道值
#include <opencv2/opencv.hpp>
#include <iostream>
#include <cmath>
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
Mat src = imread("D:/Downloads/XXX.jpg");
Mat dst, gray_src;
if (src.empty()) {// 判断路径是否正确
printf("Count't open image...\n");
return -1;
}
namedWindow("test image", CV_WINDOW_AUTOSIZE); // 自动分辨窗体大小
imshow("test open stucp", src); // 功能主要载入一张图片
dst.create(src.size(), src.type());//获取对象src的大小,src的类型
int height = src.rows;
int weight = src.cols;
int nc = src.channels();//获取对象src图像通道数量
for (int row = 0; row < height; row++) {
for (int col = 0; col < weight; col++) {
if (nc == 1) {
int gray = gray_src.at<uchar>(row, col);
gray_src.at<uchar>(row, col) = 255 - gray;
}
else if (nc == 3) {
int b = src.at<Vec3b>(row, col)[0];
int g = src.at<Vec3b>(row, col)[1];
int r = src.at<Vec3b>(row, col)[2];
dst.at<Vec3b>(row, col)[0] = 255 - b;
dst.at<Vec3b>(row, col)[1] = 255 - g;
dst.at<Vec3b>(row, col)[2] = 255 - r;
}
}
}
namedWindow("the next image",CV_WINDOW_AUTOSIZE);
imshow("the next image", dst);//输出反向通道的值
waitKey(0);
return 0;
}
七、图像混合
- 理论-线性混合操作
- 相关API (addWeighted)
1)、理论-线性混合操作
其中 的取值范围为0~1之间
2)、相关API (addWeighted)
参数1:输入图像Mat – src1
参数2:输入图像src1的alpha值
参数3:输入图像Mat – src2
参数4:输入图像src2的alpha值
参数5:gamma值
参数6:输出混合图像
注意点:两张图像的大小和类型必须一致才可以
效果呈现
图片1
图片2
效果呈现
参考代码如下:
#include <opencv2/opencv.hpp>
#include <iostream>
#include <cmath>
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
//图像混合操作
//alpha表示通道
/*
在RGB色彩空间三个通道的基础上,还可以加上一个A通道,也叫alpha通道,表示透明度
alpha通道的赋值范围是[0,1],或者[0,255],表示从透明到不透明
*/
Mat src1, src2, dst;
//为后期图像对比做知识铺垫
src1 = imread("C:/Users/Administrator/Desktop/2.jpg");
src2 = imread("C:/Users/Administrator/Desktop/3.jpg");
if (!src1.data) {
cout << "could not load image1..." << endl;
return -1;
}
if (!src2.data) {
cout << "could not load image2..." << endl;
return -1;
}
double alpha = 0.5;
//attention please(important):the image must coincide,and size together!
//if two images size difference, must return -1
if (src1.rows == src2.rows && src1.cols == src2.cols && src1.type() == src2.type()) {
addWeighted(src1, alpha, src2, (1.0 - alpha), 0.0, dst);
//multiply(src1, src2, dst, 1.0);
imshow("Logo1", src1);
imshow("Logo2", src2);
namedWindow("blend demo", CV_WINDOW_AUTOSIZE);
imshow("blend demo", dst);
}
else {
printf("could not blend images , the size of images is not same...\n");
return -1;
}
waitKey(0);
return 0;
}