OpenCV(C++版本)基础相关(2):图像的读取与显示、颜色空间转换、创建和赋值、像素的读写操作、像素的算术操作


知识来源:哔哩哔哩。以下内容仅为学习笔记,不做其他用途。

续前节OpenCV(C++版本)基础相关(1):VS2017与OpenCV4.5.1安装配置教程

一、图片的读取与显示

知识点:

  • imread 图片读取
  • imshow 图片显示
#include <opencv.hpp>
#include<iostream>

using namespace std;
using namespace cv;

int main(int argc ,char**argv)
{
	Mat src = imread("D:\\opencv\\pictures\\lena.jpeg", IMREAD_GRAYSCALE);//读入灰度图片
	namedWindow("输入窗口",WINDOW_FREERATIO);				//创建一个新窗口,“输入窗口”表示窗口名称,WINDOW_FREERATIO表示自由比例
	imshow("输入窗口", src);								//显示图片
	waitKey(0);												//表示等待,可以插入具体时间,单位为ms
	destroyAllWindows();								    //销毁建立的所有窗口

	return 0;
}

在这里插入图片描述

二、颜色空间的转换

知识点:

  • cvtColor 色彩空间转换函数
  • imwrite 图片保存

2.1 创建一个头文件quickopencv.h

#include<opencv2/opencv.hpp>
using namespace cv;

class QuickDemo //QuickDemo对象
{
public:
	void colorSpace_Demo(Mat &imge); //定义一个颜色空间Demo类
};

需要对将当前项目的目录包含进来
在这里插入图片描述

2.2 创建一个C++文件quickdemo.cpp

#include<quickopencv.h>
void QuickDemo::colorSpace_Demo(Mat &image)
{
	Mat dst1, dst2;//定义2个图像矩阵类
	cvtColor(image, dst1, COLOR_BGR2HSV);//将图像由BGR转化为HSV
	cvtColor(image, dst2, COLOR_BGR2GRAY);//将图像由BGR转化为灰度图像
	imshow("HSV", dst1);//原本输出的 HSV 的取值范围分别是 0-360, 0-1, 0-1;但是为了匹配目标数据类型 OpenCV 将每个通道的取值范围都做了修改,于是就变成了 0-180, 0-255, 0-255
	imshow("灰度", dst2);
	imwrite("D:/opencv/pictures/hsv.jpg", dst1);//保存图片,前面是保存图的地址,后面是保存图的名称
	imwrite("D:/opencv/pictures/gray.jpg", dst2);
}

2.3 测试文件test.cpp

#include<opencv2/opencv.hpp>
#include<iostream>
#include<quickopencv.h>

using namespace std;
using namespace cv;
int main(int argc,char **argv)
{

	Mat src = imread("D:/opencv/pictures/3.jpeg", IMREAD_ANYCOLOR);//B,G,R蓝绿红通道图像
	
	if (src.empty())
	{
		printf("could not load image");			//如果路径不正确,则显示无法导入图片。
		return -1;
	}
	
	namedWindow("输入窗口", WINDOW_FREERATIO);	//创建一个自由的比例窗口
	imshow("输入窗口", src);					//在窗口显示图像

	QuickDemo qd;								//调用之前创建的类对象	
	qd.colorSpace_Demo(src);

	waitKey(0);									//暂停程序,等待一个按键输入,单位ms
	destroyAllWindows();						//销毁所有创建的窗口
	return 0;
}

在这里插入图片描述

三、图像对象的创建和赋值

用到的知识点:

  • 创建空白图像,ones()zeros()
  • 克隆赋值 //m1 = image.clone()或者//image.copyTo(m2);
  • 改变三通道值m3 = Scalar(255, 0, 0);
  • 直接赋值时为同体,复制时为不同体

3.1 quickopencv.h

#include<opencv2/opencv.hpp>
using namespace cv;

class QuickDemo //QuickDemo对象
{
public:
	void mat_creation_demo();
};

3.2 QuickDemo.cpp

#include<quickopencv.h>
void QuickDemo::mat_creation_demo()
{
	//Mat m1, m2;
	//m1 = image.clone();
	//image.copyTo(m2);

	//创建空白图像,一种是ones,另一种是zeros.
	//Mat m3 = Mat::ones(Size(8, 8), CV_8UC1);//8*8的单通道无符号字符串
	Mat m3 = Mat::zeros(Size(400, 400), CV_8UC3);//创建大小为Size的CV8位的无符号的3通道的unsigned char
	//std::cout << "Width:" << m3.cols << "Height:" << m3.rows << "Channels:" << m3.channels()<<std::endl;
	//std::cout << m3 << std::endl;

	m3 = Scalar(255, 0, 0); 
	//imshow("创建窗口",m3);//纯蓝色图像

	情况一:直接赋值时,如果m4改变,m3也会改变;
	//Mat m4 = m3;
	//m4 = Scalar(0, 255, 255);
	//imshow("创建窗口1", m3);//黄色图像
	//imshow("创建窗口2", m4);//黄色图像

	//情况二:克隆时,如果m4改变,m3不会改变;
	Mat m4 = m3.clone();//克隆
	m4 = Scalar(0, 255, 255);
	imshow("创建窗口1", m3);//蓝色图像
	imshow("创建窗口2", m4);//黄色图像
}

3.3 test.cpp

#include<opencv2/opencv.hpp>
#include<iostream>
#include<quickopencv.h>

using namespace std;
using namespace cv;
int main(int argc,char **argv)
{

	Mat src = imread("D:/opencv/pictures/3.jpeg", IMREAD_ANYCOLOR);//B,G,R蓝绿红通道图像
	
	if (src.empty())
	{
		printf("could not load image");			//如果路径不正确,则显示无法导入图片。
		return -1;
	}
	
	//namedWindow("输入窗口", WINDOW_FREERATIO);	//创建一个自由的比例窗口
	//imshow("输入窗口", src);					//在窗口显示图像

	QuickDemo qd;								//调用之前创建的类对象	
	//qd.colorSpace_Demo(src);
	qd.mat_creation_demo();
	waitKey(0);									//暂停程序,等待一个按键输入,单位ms
	destroyAllWindows();						//销毁所有创建的窗口
	return 0;
}

在这里插入图片描述

四、图像像素的读写操作

用到的知识点:

  • 获取像素坐标及通道数 int w = image.cols; int h = image.rows; int dims = image.channels();分为单通道灰度图像和三通道图像
  • image.at<uchar>(row, col):C++中的模板函数,模板数据类型为uchar,参数为像素坐标row, col
  • 访问时,包括数组遍历方式指针方式

4.1 quickopencv.h

#include<opencv2/opencv.hpp>
using namespace cv;

class QuickDemo //QuickDemo对象
{
public:
	void pixel_visit_demo(Mat &imge);
	
};

4.2 QuickDemo.cpp

#include<quickopencv.h>
#include<iostream>


//void QuickDemo::pixel_visit_demo(Mat &image)
//{
//	int w = image.cols;
//	int h = image.rows;
//	int dims = image.channels();
//	//方式一:数组遍历
//	for (int row = 0; row < h; row++)
//	{
//		for (int col = 0; col < w; col++)
//		{
//			if (dims == 1)//灰度图像
//			{
//				int pv = image.at<uchar>(row, col);//获取该点的像素值
//				image.at<uchar>(row, col) = 255 - pv;//对该点的像素值进行重新赋值
//			}
//			if (dims == 3)//彩色图像
//			{
//				Vec3b bgr = image.at<Vec3b>(row, col);//三通道,三个值
//				image.at<Vec3b>(row, col)[0] = 255 - bgr[0];
//				image.at<Vec3b>(row, col)[1] = 255 - bgr[1];
//				image.at<Vec3b>(row, col)[2] = 255 - bgr[2];//对每个点的像素值进行重新赋值
//			}
//		}
//	}
//	imshow("像素读写显示", image);
//}

void QuickDemo::pixel_visit_demo(Mat &image)
{
	int w = image.cols;
	int h = image.rows;
	int dims = image.channels();
	//方式二:指针实现
	for (int row = 0; row < h; row++)
	{
		uchar *current_row = image.ptr<uchar>(row);
		for (int col = 0; col < w; col++)
		{
			if (dims == 1)//灰度图像
			{
				int pv = *current_row;//获取该点的像素值
				*current_row++ = 255 - pv;//对该点的像素值进行重新赋值
			}
			if (dims == 3)//彩色图像
			{
				*current_row++ = 255 - *current_row;
				*current_row++ = 255 - *current_row;
				*current_row++ = 255 - *current_row;
			}
		}
	}
	imshow("像素读写显示", image);
}

4.3 test.cpp

#include<opencv2/opencv.hpp>
#include<iostream>
#include<quickopencv.h>

using namespace std;
using namespace cv;
int main(int argc,char **argv)
{

	Mat src = imread("D:/opencv/pictures/xzpq.jpeg", IMREAD_ANYCOLOR);//B,G,R蓝绿红通道图像
	
	if (src.empty())
	{
		printf("could not load image");			//如果路径不正确,则显示无法导入图片。
		return -1;
	}
	
	namedWindow("输入窗口", WINDOW_AUTOSIZE);	//创建一个自动尺寸的比例窗口
	imshow("输入窗口", src);					//在窗口显示图像

	QuickDemo qd;								//调用之前创建的类对象	
	//qd.colorSpace_Demo(src);
	//qd.mat_creation_demo();
	qd.pixel_visit_demo(src);
	waitKey(0);									//暂停程序,等待一个按键输入,单位ms
	destroyAllWindows();						//销毁所有创建的窗口
	return 0;
}

在这里插入图片描述

五、图像像素的算术操作

用到的知识点:

  • saturate_cast(p1[0] + p2[0]);防止颜色溢出操作,小于0就是0,大于255就是255
  • add(image, m, dst);//1 加法操作
  • subtract(image, m, dst); //2 减法操作
  • multiply(image, m, dst); //3 乘法操作
  • divide(image, m, dst); //4 除法操作

5.1 quickopencv.h

#include<opencv2/opencv.hpp>
using namespace cv;

class QuickDemo //QuickDemo对象
{
public:

	void operators_demo(Mat &imge);
	
};

5.2 QuickDemo.cpp

#include<quickopencv.h>
#include<iostream>


void QuickDemo::operators_demo(Mat &image)
{
	Mat dst = Mat::zeros(image.size(), image.type());
	Mat m = Mat::zeros(image.size(), image.type());
	m = Scalar(50, 50, 50);
	//一、具体代码实现
	//加法操作具体实现
	//int h = image.rows;
	//int w = image.cols;
	//int dims = image.channels();
	//for (int row = 0; row < h; row++)
	//{
	//	for (int col = 0; col < w; col++)
	//	{
	//		Vec3b p1 = image.at<Vec3b>(row, col); 
	//		Vec3b p2 = m.at<Vec3b>(row, col);
	//		dst.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(p1[0] + p2[0]);//saturate_cast为了防止颜色溢出操作,小于0就是0,大于255就是255
	//		dst.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(p1[1] + p2[1]);
	//		dst.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(p1[2] + p2[2]);
	//	}
	//}
	//imshow("加法操作", dst);

	//二、函数调用实现
	//1 加法操作
	add(image, m, dst);
	imshow("加法操作", dst);

	//2 减法操作
	//subtract(image, m, dst);
	//imshow("减法操作", dst);

	//3 乘法操作
	//multiply(image, m, dst);
	//imshow("乘法操作", dst);

	//4 除法操作
	//divide(image, m, dst);
	//imshow("除法操作", dst);

}

5.3 test.cpp

#include<opencv2/opencv.hpp>
#include<iostream>
#include<quickopencv.h>

using namespace std;
using namespace cv;
int main(int argc,char **argv)
{

	Mat src = imread("D:/opencv/pictures/xzpq.jpeg", IMREAD_ANYCOLOR);//B,G,R蓝绿红通道图像
	
	if (src.empty())
	{
		printf("could not load image");			//如果路径不正确,则显示无法导入图片。
		return -1;
	}
	
	namedWindow("输入窗口", WINDOW_AUTOSIZE);	//创建一个自动尺寸的比例窗口
	imshow("输入窗口", src);					//在窗口显示图像

	QuickDemo qd;								//调用之前创建的类对象	
	qd.operators_demo(src);
	waitKey(0);									//暂停程序,等待一个按键输入,单位ms
	destroyAllWindows();						//销毁所有创建的窗口
	return 0;
}

加法操作
在这里插入图片描述

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值