OpenCV(一)图像读取与新建、图像显示、操作图像像素(2种涂色并比较算法优劣、输出RGB)

本文详细介绍了使用OpenCV进行图像处理的基本操作,包括读取与新建图像、显示图像以及操作图像像素。特别地,通过对比逐RGB涂色(单循环)与逐行涂色(双循环)两种方法的实现代码和运行效果,探讨了它们在效率上的差异,并提供了实际运行时间的比较。
摘要由CSDN通过智能技术生成

目录

一、读取图像与新建图像

1、读取图像

2、新建图像

二、显示图像

1、过程

2、代码

3、运行效果

三、操作图像像素

1、逐RGB涂色(单循环)(快)

1-1、过程

2-2、代码 

2-3、运行结果

2、逐行涂色(双循环)(慢)

3、算法快慢比较

总代码


一、读取图像与新建图像

注:如果是添加新图(非读取),必须要新建图像,否则会报错(没有初值)。 

总而言之,图像必须有初值,这个初值要么读取获得,要么新建获得。

1、读取图像

img = imread("Resource/test.jpg");

2、新建图像

dst = Mat::zeros(img.size(), img.type());

分别需要填入图片大小图片类型 。

二、显示图像

1、过程

1、打开图像;

2、新建窗口

3、在窗口中显示图像

2、代码

//显示图像
#include <iostream>
#include<opencv2/opencv.hpp>
using namespace cv;
using namespace std;

int main()
{
	//1、打开图像
	Mat img = imread("Resource/test.png");
	//图像为空
	if (img.empty())
		cout << "can not find the image!\n";

	//设置窗口(可以不要)
	namedWindow("图像", WINDOW_AUTOSIZE);		//新建一个显示窗口,命名并指定窗口的类型(这里为固定)
	//											WINDOW_NORMAL		//可调控

	//2、在窗口中显示
	imshow("图像", img);

	waitKey(0);				//等待
}

3、运行效果

三、操作图像像素

三通道RGB):

1、逐RGB涂色(单循环)(快)

1-1、过程

指针指向首元素地址

//获取矩阵数据的起始地址
uchar* p = image.ptr<uchar>(0);
//图像的指针用法举例
cv::Mat image = cv::Mat(400, 600, CV_8UC1);    //定义了一个Mat变量image。
uchar * data00 = image.ptr<uchar>(0);          //data00是指向image第1行第1个元素的指针。
uchar * data10 = image.ptr<uchar>(1);          //data10是指向image第1行第1个元素的指针。
uchar * data01 = image.ptr<uchar>(0)[1];       //data01是指向image第1行第2个元素的指针。

一共运行length次,lengthrgb总数

//总RGB个数
	int length = image.cols * image.rows * image.channels();
	//总RGB个数 = 行数*列数*通道数	  (总像素=行数*列数	转化为RGB->乘RGB数量(即通道数)
	//三通道:RGB

2-2、代码 

//逐RGB涂色(单循环)
void setAllWhite(Mat& image)
{
	int i;

	//总RGB个数
	int length = image.cols * image.rows * image.channels();
	//总RGB个数 = 行数 * 列数 * 通道数					(总像素=行数*列数		转化为RGB->乘RGB数量(即通道数)
	//三通道:RGB

	//获取矩阵数据的起始地址
	uchar* p = image.ptr<uchar>(0);

	///逐rgb涂色
	for (i = 0; i < length; i++)
	{
		//data[i] = 150;				
		(*p++) = 150;				//涂色(逐RGB)
	}
}

2-3、运行结果

2、逐行涂色(双循环)(慢)

(同上)指针指向首元素地址

//获取矩阵数据的起始地址
uchar* p = image.ptr<uchar>(0);
//图像的指针用法举例
cv::Mat image = cv::Mat(400, 600, CV_8UC1);    //定义了一个Mat变量image。
uchar * data00 = image.ptr<uchar>(0);          //data00是指向image第1行第1个元素的指针。
uchar * data10 = image.ptr<uchar>(1);          //data10是指向image第1行第1个元素的指针。
uchar * data01 = image.ptr<uchar>(0)[1];       //data01是指向image第1行第2个元素的指针。

 逐行 涂色image.rows,再在循环中逐rgb涂色image.cols * image.channels()。

//逐行涂色(双循环)
void setAllWhiteRows(Mat& image)
{
	int i, j;

	//获取矩阵数据的起始地址
	uchar* p = image.ptr<uchar>(0);

	for (i = 0; i < image.rows; i++)										//逐行
	{
		for (j = 0; j < image.cols * image.channels(); j++)		//逐rgb
		{
			(*p++) = 150;				//涂色(逐RGB)
		}
	}
}

3、算法快慢比较

运用时间获取函数colck()开始时计时一次结束时计时一次差值即为算法运行时间。

clock()返回ms,需要获取s,所以除1000

//比较两种算法的运行速度
void compareTime(Mat& image)
{
	int count = 10;
	long begin, end;

	//统计单循环方式(逐像素)运行时间
	begin = clock();
	while (count-- > 0)
		setAllWhite(image);				//运行
	end = clock();
	printf("Single loop time is %f .\n", (double)(end - begin) / (double)CLOCKS_PER_SEC);
	//																	clock()以ms计,需要除1000才能获取到s

	//统计双循环方式(逐行)运行时间
	count = 10;
	begin = clock();
	while (count-- > 0)
		setAllWhiteRows(image);		//运行
	end = clock();
	printf("Double loop time is %f \n", (double)(end - begin) / (double)CLOCKS_PER_SEC);
}

总代码

//图像逐像素的操作
//单循环:逐个对每个像素进行赋值
//双循环:逐行对每个像素进行赋值
#include <iostream>
#include<opencv2/opencv.hpp>
using namespace cv;
using namespace std;

//逐RGB涂色(单循环)
void setAllWhite(Mat& image)
{
	int i;

	//总RGB个数
	int length = image.cols * image.rows * image.channels();
	//总RGB个数 = 行数 * 列数 * 通道数					(总像素=行数*列数		转化为RGB->乘RGB数量(即通道数)
	//三通道:RGB

	//获取矩阵数据的起始地址
	uchar* p = image.ptr<uchar>(0);

	///逐rgb涂色
	for (i = 0; i < length; i++)
	{
		//data[i] = 150;				
		(*p++) = 150;				//涂色(逐RGB)
	}
}

//逐行涂色(双循环)
void setAllWhiteRows(Mat& image)
{
	int i, j;

	//获取矩阵数据的起始地址
	uchar* p = image.ptr<uchar>(0);

	for (i = 0; i < image.rows; i++)										//逐行
	{
		for (j = 0; j < image.cols * image.channels(); j++)		//逐rgb
		{
			(*p++) = 150;				//涂色(逐RGB)
		}
	}
}

//比较两种算法的运行速度
void compareTime(Mat& image)
{
	int count = 10;
	long begin, end;

	//统计单循环方式(逐像素)运行时间
	begin = clock();
	while (count-- > 0)
		setAllWhite(image);				//运行
	end = clock();
	printf("Single loop time is %f .\n", (double)(end - begin) / (double)CLOCKS_PER_SEC);
	//																	clock()以ms计,需要除1000才能获取到s

	//统计双循环方式(逐行)运行时间
	count = 10;
	begin = clock();
	while (count-- > 0)
		setAllWhiteRows(image);		//运行
	end = clock();
	printf("Double loop time is %f \n", (double)(end - begin) / (double)CLOCKS_PER_SEC);
}

//输出RGB
void Print(Mat& image)
{
	int i, length;
	const uchar* p = image.ptr<uchar>(0);		//指向首个指针
	length = image.rows;									//*image.cols		这里只输出一行
	cout << "\nPrint one row pixels:\n";
	for (i = 0; i < length; i++)
	{
		printf("%2d", *p++);
	}
	cout << endl;
}

int main()
{
	Mat img = imread("Resource/test.png");			//打开图片
	if (img.empty())
	{
		printf("could not load the image..");
		return -1;
	}

	//显示图像
	namedWindow("初始图像", WINDOW_AUTOSIZE);
	imshow("初始图像", img);
	Print(img);									//输出RGB

	//涂色与算法比较
	compareTime(img);						//比较两种算法运行时间
	//setAllWhite(img);							//逐RGB涂色
	//setAllWhiteRows(img);					//逐行涂色

	//显示图像
	namedWindow("涂色图像", WINDOW_AUTOSIZE);
	imshow("涂色图像", img);
	Print(img);										//输出RGB

	waitKey(0);										//等待
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_(*^▽^*)_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值