Opencv图像处理学习笔记(1)——基本API操作
好久没写学习笔记了,今天我又开了一个新坑,因为作者最近正在学习opencv。所以后面我会不断更新关于Opencv的学习笔记,以供作者今后自查温习所用。
在上一篇博客里,我已经介绍了如何安装Opencv并成功在vs2017上搭建程序运行环境,如有疑惑,可自行查阅作者上一篇博客。
下面我将开始介绍关于Opencv的基本API操作和关于图像处理的一些原理。
一.图像的加载、修改、保存操作
1.加载操作(cv::imread)
函数API: Mat imread(const string& filename, int flags=1 )
imread功能是加载图像文件成为一个Mat对象,其中第一个参数表示图像文件名称
第二个参数,表示加载的图像是什么类型,支持常见的三个参数值
IMREAD_UNCHANGED (<0) 表示加载原图,不做任何改变
**IMREAD_GRAYSCALE ( 0)**表示把原图作为灰度图像加载进来
IMREAD_COLOR (>0) 表示把原图作为RGB图像加载进来
注意:OpenCV支持JPG、PNG、TIFF等常见格式图像文件加载
注意:如果第二个形参不设置,则默认采用IMREAD_COLOR读入图片
程序实例:
#include<opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
using namespace cv;
int main(int argc, char** argv) {
Mat src = imread("E:/photoss/dog1.jpeg",IMREAD_GRAYSCALE);//读取相应位置图像,并转化为灰度图像
if (src.empty()) {
std::cout << "无法加载图像\n";
return -1;
}
namedWindow("opencv setup Demo!", CV_WINDOW_AUTOSIZE);
imshow("opencv setup Demo!", src);
waitKey(0);
return 0;
}
程序运行效果:
2.显示图像(cv::namedWindos 与cv::imshow)
namedWindos功能是创建一个OpenCV窗口,它是由OpenCV自动创建与释放,你无需取销毁它。
常见用法namedWindow(“Window Title”, WINDOW_AUTOSIZE)
WINDOW_AUTOSIZE会自动根据图像大小,显示窗口大小,不能人为改变窗口大小
WINDOW_NORMAL,跟QT集成的时候会使用,允许修改窗口大小。
imshow根据窗口名称显示图像到指定的窗口上去,第一个参数是窗口名称,第 二参数是Mat对象
程序示例:
#include<opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
using namespace cv;
int main(int argc, char** argv) {
Mat src = imread("E:/photoss/dog1.jpeg");//读取图片,默认参数设置
if (src.empty()) {
//判断图片是否为空
std::cout << "无法加载图像\n";
return -1;
}
namedWindow("opencv setup Demo!", CV_WINDOW_AUTOSIZE);//定义一个图像显示窗口,
//窗口大小为自动尺寸模式:CV_WINDOW_AUTOSIZE
imshow("opencv setup Demo!", src);
waitKey(0);
return 0;
}
程序运行效果:
3.修改图像(cv::cvtColor)
cvtColor的功能是把图像从一个彩色空间转换到另外一个色彩空间,有三个参数,第一个参数表示源图像、第二参数表示色彩空间转换之后的图像、第三个参数表示源和目标色彩空间如:COLOR_BGR2HLS 、COLOR_BGR2GRAY 等
eg:cvtColor( image, gray_image, COLOR_BGR2GRAY );
其中,最后一个参数dstCn用于指定目标图像的通道数,如果指定的值是默认值0,那么通道数将由输入图像和颜色转换码决定。
cv::cvtColor()支持多种颜色空间之间的转换,其支持的转换类型和转换码如下:
1、RGB和BGR(opencv默认的彩色图像的颜色空间是BGR)颜色空间的转换
cv::COLOR_BGR2RGB
cv::COLOR_RGB2BGR
cv::COLOR_RGBA2BGRA
cv::COLOR_BGRA2RGBA
2、向RGB和BGR图像中增添alpha通道
cv::COLOR_RGB2RGBA
cv::COLOR_BGR2BGRA
3、从RGB和BGR图像中去除alpha通道
cv::COLOR_RGBA2RGB
cv::COLOR_BGRA2BGR
4、从RBG和BGR颜色空间转换到灰度空间
cv::COLOR_RGB2GRAY
cv::COLOR_BGR2GRAY
cv::COLOR_RGBA2GRAY
cv::COLOR_BGRA2GRAY
5、从灰度空间转换到RGB和BGR颜色空间
cv::COLOR_GRAY2RGB
cv::COLOR_GRAY2BGR
cv::COLOR_GRAY2RGBA
cv::COLOR_GRAY2BGRA
6、RGB和BGR颜色空间与BGR565颜色空间之间的转换
cv::COLOR_RGB2BGR565
cv::COLOR_BGR2BGR565
cv::COLOR_BGR5652RGB
cv::COLOR_BGR5652BGR
cv::COLOR_RGBA2BGR565
cv::COLOR_BGRA2BGR565
cv::COLOR_BGR5652RGBA
cv::COLOR_BGR5652BGRA
7、灰度空间域BGR565之间的转换
cv::COLOR_GRAY2BGR555
cv::COLOR_BGR5552GRAY
8、RGB和BGR颜色空间与CIE XYZ之间的转换
cv::COLOR_RGB2XYZ
cv::COLOR_BGR2XYZ
cv::COLOR_XYZ2RGB
cv::COLOR_XYZ2BGR
9、RGB和BGR颜色空间与uma色度(YCrCb空间)之间的转换
cv::COLOR_RGB2YCrCb
cv::COLOR_BGR2YCrCb
cv::COLOR_YCrCb2RGB
cv::COLOR_YCrCb2BGR
10、RGB和BGR颜色空间与HSV颜色空间之间的相互转换
cv::COLOR_RGB2HSV
cv::COLOR_BGR2HSV
cv::COLOR_HSV2RGB
cv::COLOR_HSV2BGR
11、RGB和BGR颜色空间与HLS颜色空间之间的相互转换
cv::COLOR_RGB2HLS
cv::COLOR_BGR2HLS
cv::COLOR_HLS2RGB
cv::COLOR_HLS2BGR
12、RGB和BGR颜色空间与CIE Lab颜色空间之间的相互转换
cv::COLOR_RGB2Lab
cv::COLOR_BGR2Lab
cv::COLOR_Lab2RGB
cv::COLOR_Lab2BGR
13、RGB和BGR颜色空间与CIE Luv颜色空间之间的相互转换
cv::COLOR_RGB2Luv
cv::COLOR_BGR2Luv
cv::COLOR_Luv2RGB
cv::COLOR_Luv2BGR
14、Bayer格式(raw data)向RGB或BGR颜色空间的转换
cv::COLOR_BayerBG2RGB
cv::COLOR_BayerGB2RGB
cv::COLOR_BayerRG2RGB
cv::COLOR_BayerGR2RGB
cv::COLOR_BayerBG2BGR
cv::COLOR_BayerGB2BGR
cv::COLOR_BayerRG2BGR
cv::COLOR_BayerGR2BGR
程序实例:
#include<opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
using namespace cv;
int main(int argc, char** argv) {
Mat src = imread("E:/photoss/dog1.jpeg");//读取图片
if (src.empty()) {
//判断图片是否为空
std::cout << "无法加载图像\n";
return -1;
}
namedWindow("opencv setup Demo!", CV_WINDOW_AUTOSIZE);//定义一个图像显示窗口,
//窗口大小为自动尺寸模式:CV_WINDOW_AUTOSIZE
imshow("opencv setup Demo!", src);//显示输入图像
namedWindow("output windows",CV_WINDOW_AUTOSIZE);//再定义一个图像显示窗口
Mat output_image;//定义一个名为output_image的Mat对象
cvtColor(src, output_image, CV_BGR2HSV);//将原图像由BGR颜色通道转换为HSV颜色通道
//cvtColor(src, output_image, CV_BGR2GRAY);//将原图像由BGR颜色通道转换为灰度图像
imshow("output windows", output_image);
//imwrite("E:/programs/opencv/lesson1/test.png", output_image);
waitKey(0);
return 0;
}
运行效果:
4.保存图像(cv::imwrite)
保存图像文件到指定目录路径
只有8位、16位的PNG、JPG、Tiff文件格式而且是单通道或者三通道的BGR的图像才可以通过这种方式保存
保存PNG格式的时候可以保存透明通道的图片
可以指定压缩参数
#include<opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
using namespace cv;
int main(int argc, char** argv) {
Mat src = imread("E:/photoss/dog1.jpeg");//读取图片
if (src.empty()) {
//判断图片是否为空
std::cout << "无法加载图像\n";
return -1;
}
namedWindow("opencv setup Demo!", CV_WINDOW_AUTOSIZE);//定义一个图像显示窗口,
//窗口大小为自动尺寸模式:CV_WINDOW_AUTOSIZE
imshow("opencv setup Demo!", src);//显示输入图像
namedWindow("output windows",CV_WINDOW_AUTOSIZE);//再定义一个图像显示窗口
Mat output_image;//定义一个名为output_image的Mat对象
cvtColor(src, output_image, CV_BGR2HSV);//将原图像由BGR颜色通道转换为HSV颜色通道
//cvtColor(src, output_image, CV_BGR2GRAY);//将原图像由BGR颜色通道转换为灰度图像
imshow("output windows", output_image);
imwrite("E:/programs/opencv/lesson1/test.png", output_image);//将output_image对象保存到test.png中
waitKey(0);
return 0;
}
运行结果:
二.矩阵的掩膜操作
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.矩阵掩膜操作原理解析
掩膜操作实现图像对比度调整
-红色是中心像素,从上到下,从左到右对每个像素做同样的处理操作,得到最终结果就是对比度提高之后的输出图像Mat对象
相关API:
函数调用filter2D功能来实现矩阵掩膜操作
filter2D( InputArray src, OutputArray dst, int ddepth,InputArray kernel, Point anchor=Point(-1,-1), double delta=0, int borderType=BORDER_DEFAULT );
七个参数分别表示:(原图,目标图,图像深度,核函数,模板中心点,delta,边界类型)
一般卷积操作只涉及到前五个参数。
参数说明:(一般只写前5个参数)
InputArray src: 输入图像
OutputArray dst: 输出图像,和输入图像具有相同的尺寸和通道数量
int ddepth: 目标图像深度,如果没写将生成与原图像深度相同的图像。当ddepth输入值为-1时,目标图像和原图像深度保持一致。
InputArray kernel: 卷积核(或者是相关核),一个单通道浮点型矩阵。如果想在图像不同的通道使用不同的kernel,可以先使用split()函数将图像通道事先分开。
Point anchor: 内核的基准点(anchor),其默认值为(-1,-1)说明位于kernel的中心位置。基准点即kernel中与进行处理的像素点重合的点。
double delta: 在储存目标图像前可选的添加到像素的值,默认值为0。
int borderType: 像素向外逼近的方法,默认值是BORDER_DEFAULT,即对全部边界进行计算。
程序示例:
1.不使用filter2D函数API而自己编写代码实现矩阵掩膜操作:
#include<opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
using namespace cv;
int main(int argc, char** argv) {
Mat src, dst;//定义源图像和目标图像
src = imread