C/C++图像处理实验(一)——Mat与数组转换

简介

由于曾经做过一些嵌入式的图像处理算法,感觉在单片机上做算法开发和验证非常麻烦,想在PC机上实现后直接移植到单片机即可,所以创建了这个专栏,学习一下图像处理算法。嵌入式的图像处理算法的开发中,图像数据一般都是存储在数组中,而在电脑上常用的图像处理库是OpenCV,其数据存储在Mat类中,故第一步应该实现这两种数据的互转。

准备工作

  • 安装Visual Studio
  • 安装OpenCV

数据类型转换

嵌入式开发中图像数据存储在数组中,但是OpenCV的图像数据是存储在Mat类中,所以为了模拟嵌入式图像处理流程,需要实现数组与Mat类型的互转。

灰度图像与数组互转

首先是灰度图像的Mat与数组互转,图像大小为512*512。
主函数部分负责读取图像并存为Mat类型,然后Mat类型转为二维数组后再转回Mat类型数据,并将Mat类型数据显示出来进行验证。

#include <opencv2/opencv.hpp>
#include "test_algorithm/test.h"
using namespace cv;
int main()
{
	Mat image_gray = imread("./test.png",0);
	Mat image_restore(Height, Width, CV_8UC1);
	unsigned char img_gray[Height][Width];
	Mat2array(image_gray, img_gray,Height,Width);
	image_restore = array2Mat(img_gray,Height,Width);
	imshow("image", image_gray);
	imshow("image_restore", image_restore);
	waitKey(0);
	return 0;
}

Mat数据类型转为数据的过程:

//实现OpenCV的Mat数据类转为unsigned char类型的二维数组
void Mat2array(cv::Mat image_gray, unsigned char img_gray[][Width], unsigned int height, unsigned int width)
{
	for (unsigned int i = 0; i < height; i++)
	{
		for (unsigned int j = 0; j < width; j++)
		{
			img_gray[i][j] = image_gray.at<uchar>(i, j);
		}
	}
}

二维数组转回Mat数据类型的过程:

//实现unsigned char类型的二维数组转为OpenCV的Mat数据类
cv::Mat array2Mat(unsigned char img_gray[][Width],unsigned int height,unsigned int width)
{
	 cv::Mat image_gray(Height, Width, CV_8UC1);
	for (unsigned int i = 0; i < height; i++)
	{
		for (unsigned int j = 0; j < width; j++)
		{
			image_gray.at<uchar>(i, j)= img_gray[i][j];
		}
	}
	return image_gray;
}
彩色图像与数组互转

主函数部分,图像大小为512*512:

int main()
{
	Mat image = imread("./test.png");
	Mat image_restore(Height, Width, CV_8UC3);
	unsigned char img_rgb[Height][Width][3];
	Mat2array_RGB(image, img_rgb,Height,Width);
	image_restore = array2Mat_RGB(img_rgb,Height,Width);
	imshow("image", image);
	imshow("image_restore", image_restore);
	waitKey(0);
	return 0;
}

在OpenCV中,彩色图像的Mat数据的排列顺序为BGR,而不是RGB,使用转换过程中需要注意。

//彩色图像Mat转为array,三维数组的形状为img_rgb[Height][Width][3],三个通道依次为BGR
void Mat2array_RGB(cv::Mat image_bgr, unsigned char img_rgb[][Width][3], unsigned int height, unsigned int width)
{
	for (unsigned int i = 0; i < height; i++)
	{
		for (unsigned int j = 0; j < width; j++)
		{
			unsigned int temp = (i * height + j) * 3;
			img_rgb[i][j][0] = image_bgr.data[temp+2];
			img_rgb[i][j][1] = image_bgr.data[temp+1];
			img_rgb[i][j][2] = image_bgr.data[temp];//因为OpenCV默认的图像格式为BGR,此处为了转为RGB
		}
	}
}
//将三维数组重新转为彩色图像Mat
cv::Mat array2Mat_RGB(unsigned char img_rgb[][Width][3], unsigned int height, unsigned int width)
{
	cv::Mat image(Height, Width, CV_8UC3);
	for (unsigned int i = 0; i < height; i++)
	{
		for (unsigned int j = 0; j < width; j++)
		{
			unsigned int temp = (i * height + j) * 3;
			image.data[temp]= img_rgb[i][j][2];
			image.data[temp + 1]= img_rgb[i][j][1];
			image.data[temp + 2]= img_rgb[i][j][0];
		}
	}
	return image;
}

总结

  1. 完成上述步骤的作用是为了将Mat类型转为嵌入式中常见的数组类型,在PC端上设计出图像处理算法,然后就可以直接移植到嵌入式芯片即可,降低开发难度。
  2. 在图像算法开发过程中,如果涉及数据类型的转换,一定要注意转换双方的异同。生活日常使用的图像格式一般为RGB,但是要注意OpenCV默认的格式为BGR,减少错误。
  3. 在一些低端的单片机中进行图像算法开发,存储图像数据的数组一般都是使用全局变量,虽然会占用较多的内存且容易导致误操作,但是受限于单片机的性能,频繁地在函数中创建和销毁数组显然不太现实,这一点与在PC端开发图像算法不太一样。
  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在这个问题中,用户提供了两段代码,分别是引用\[1\]和引用\[2\]。这两段代码都是用来在一个数组中查找指定数的位置。 引用\[1\]是一个C++代码示例,它使用了iostream和stdio.h头文件,并使用了命名空间std。代码中使用了一个while循环来不断读取输入的n值,然后创建一个大小为n的整型数组a,并通过for循环读取数组的元素。接下来,代码读取了一个整数m,并使用for循环遍历数组a,查找是否有与m相等的元素。如果找到了相等的元素,则将其位置赋值给变量t,并跳出循环。最后,根据t的值输出结果。 引用\[2\]是另一个C代码示例,它使用了stdio.h头文件。代码中同样使用了一个while循环来不断读取输入的n值,然后创建一个大小为n的整型数组a,并通过for循环读取数组的元素。接下来,代码读取了一个整数m,并使用for循环遍历数组a,查找是否有与m相等的元素。如果找到了相等的元素,则将其位置赋值给变量count,并将flag设置为1,表示找到了。最后,根据flag的值输出结果。 综上所述,这两段代码都是用来在一个数组中查找指定数的位置。它们的实现方式略有不同,但都能达到相同的目的。 #### 引用[.reference_title] - *1* [1143: 零起点学算法50——数组中查找数](https://blog.csdn.net/weixin_43965597/article/details/113104995)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [问题 C: 零起点学算法82——数组中查找数](https://blog.csdn.net/chenhannan0024/article/details/127568844)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值