一、图像色彩空间转换
1.1 基本知识
- 色彩空间转换函数:cvtColor
COLOR_BGR2GRAY = 6 //6彩色到灰度
COLOR_GRAY2BGR = 8 //8灰度到彩色
COLOR_BGR2HSV = 40 //40BGR到HSV
COLOR_HSV2BGR = 54 //54HSV到BGR
GRAY:指灰度,只有一个参数灰度值Channel
BGR:指BGR颜色空间,以红绿蓝三基色(0~255)为基础,叠加形成各种颜色
HSV:指六角椎体模型,色调Hue用角度度量(0~180),饱和度Saturation(0 ~ 255),亮度Value(0 ~ 255)
- 图像保存函数:imwrite
第一个参数是图像保存路径
第二个参数是图像内存对象
1.2 创建类
①首先添加一个头文件。
②头文件内定义一个MyDemo类,代码如下
#pragma once
#include <opencv2/opencv.hpp>
using namespace cv;
class MyDemo {
public:
void colorSpace_Demo(Mat &image);
};
③添加包含目录。首先在项目名称上右键-属性,打开属性页后,编辑VC++目录->包含目录这一项,新建项为头文件所在的目录如图。
④创建一个cpp文件,实现刚才定义的类。
#include <mydemo.h>
void MyDemo::colorSpace_Demo(Mat &image) {
Mat gray, hsv;
cvtColor(image, hsv, COLOR_BGR2HSV);
cvtColor(image, gray, COLOR_BGR2GRAY);
imshow("HSV Image", hsv);
imshow("Gray Image", gray);
imwrite("E:/Program/OpenCV/vcworkspaces/opencv_452/img/hsv.png", hsv);
imwrite("E:/Program/OpenCV/vcworkspaces/opencv_452/img/gray.png", gray);
}
1.3 编写主函数
#include <opencv2/opencv.hpp>
#include <iostream>
#include <mydemo.h>
using namespace cv;
int main(int argc, char** argv) {
Mat src = imread("E:/Program/OpenCV/vcworkspaces/opencv_452/img/opencv.jpg");//自己找一张图片
imshow("opencv.jpg", src);
MyDemo demo;
demo.colorSpace_Demo(src);
waitKey(0);
destroyAllWindows();;
return 0;
}
1.4 测试结果
使用技巧:由于RGB三个参数仅代表颜色,HSV分别代表色调、饱和度、亮度。
因此对于一个图片想要调整亮度,可以先转换到HSV色彩空间调节亮度,再返回RGB色彩空间即可。
二、图像对象的创建与复制
2.1 什么是Mat
关于Mat的问题
- 如何操作读进来的图像
- 如何遍历访问图像的每个像素点
- 如何创建一个空图像
在OpenCV中Mat的数据分为两个部分,头部和数据部分。头部包括数据类型、通道数量。
2.2 创建空白图像
创建图像的过程
①所用函数
Mat m_new = Mat::zeros(Size(8, 8),CV_8UC1);
Mat m_new = Mat::ones(Size(8, 8),CV_8UC1);
函数中的参数CV_8UC1,表示8位、unsigned char型、Channel通道数为1。
②添加头文件
接下来写demo尝试创建图像,在头文件内添加一行函数的声明。
#pragma once
#include <opencv2/opencv.hpp>
using namespace cv;
class MyDemo {
public:
void colorSpace_Demo(Mat& image);
void matCreation_Demo(); //这一行是新加的
};
③实现创建图像的函数
在mydemo.cpp文件中添加以下代码实现此函数
void MyDemo::matCreation_Demo() {
//创建空白图像
Mat m_new = Mat::zeros(Size(8, 8),CV_8UC1);
std::cout << "width = " << m_new.cols << "\theight = " << m_new.rows << "\tchannels = " << m_new.channels() << std::endl;
std::cout << m_new << std::endl;
}
④主函数调用并测试
#include <opencv2/opencv.hpp>
#include <iostream>
#include <mydemo.h>
using namespace cv;
int main(int argc, char** argv) {
MyDemo demo;
demo.matCreation_Demo();
waitKey(0);
destroyAllWindows();;
return 0;
}
输出结果如下图所示,是一个8x8的矩阵:
注意事项:
如果将通道数改为3,也就是Mat m_new = Mat::zeros(Size(8, 8),CV_8UC3);
,那么输出结果会变成8x24的矩阵,也就是每个像素点会有三个值:
如果对三通道使用ones进行初始化,那么只会使每个像素点的第一个通道初始化为1,第二、第三通道仍然初始化为0.
可以通过使用Scalar
函数对图像所有像素点同时进行赋值。Scalar的三个参数分别为B、G、R
void MyDemo::matCreation_Demo() {
//创建空白图像
Mat m_new = Mat::ones(Size(8, 8),CV_8UC3);
m_new = Scalar(66, 66, 66);
std::cout << m_new << std::endl;
}
图像在哪里
刚才我们通过io输出,在控制台将图像的像素点值一个一个打印出来。我们当然也可以将它作为一个图像进行输出。只需要将cout换成imshow即可。
void MyDemo::matCreation_Demo() {
//创建空白图像
Mat m_new = Mat::ones(Size(800, 600),CV_8UC3);
m_new = Scalar(66, 66, 66);
imshow("new image",m_new);
}
这就是我们生成出来的一个图像
2.3 图像的复制
对于Mat对象进行赋值操作时,只是相当于两个指针指向了同一块内存空间,只有进行克隆和拷贝操作时,才是真正的复制。
①克隆:clone
m_clone = image.clone();
②拷贝:copyTo
image.copyTo(m_copy);