上位机图像处理和嵌入式模块部署(极致成本下的图像处理)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

目前,大家都习惯了特定的图像处理方式,要么是windows上位机来处理,要么是arm soc来进行处理,要么是fpga或者是nvidia gpu来对图像进行处理。但是,这几种方法都有一个共同的特点,那就是对处理器的性能要求高。大家有没有想过,假设运算资源不是很充足,获取的图像分辨率不是很高,在这种情况下还要对图像处理的话,或者是完成特定的一个功能,我们是不是就要想想别的办法了。这样的话,soc是不可能了,mcu也许比较合适一点。此外,opencv库也不好使了,算法也需要我们自己用c写出来。

为了说明这种情况下,图像应该怎么处理,我们不妨借助于qt来仿真一下整个流程。

1、创建一个基于widget的qt工程

首先创建一个qt工程,主要是替我们完成图像的解析和保存。

2、借助于qt实现图像的加载和保存

这里创建qt的目的,主要还是为了演示一下怎么用qt来打开图像和保存图像。实际在嵌入式模块执行的时候,一般我们可以直接拿到图像裸数据的,也不存在文件解析的地方。

复制代码
#include <QImage>
#include <QDebug>
#include <malloc.h>
#include <assert.h>

// generate binary image here
static unsigned char* p_mem = NULL;
void generate_binary_img(unsigned char* p_char, int width, int height);

void processImage(QString inputPath, QString outputPath)
{
	// load image
	QImage inputImage(inputPath);
	if (inputImage.isNull())
	{
		qDebug() << "Failed to load image";
		return;
	}

	// get image info
	int width = inputImage.width();
	int height = inputImage.height();
	p_mem = (unsigned char*)malloc(width * height);
	assert(p_mem);

	// loop to process pixel
	unsigned char* p_data = p_mem;
	for (int y = 0; y < height; ++y)
	{
		for (int x = 0; x < width; ++x)
		{
			QRgb pixel = inputImage.pixel(x, y);

			// get data
			int red = qRed(pixel);
			int green = qGreen(pixel);
			int blue = qBlue(pixel);

			// get gray
			int gray = qGray(red, green, blue);

			// save gray to matrix memory
			*p_data= gray;
			p_data++;
		}
	}

	// process binary here
	generate_binary_img(p_mem, width, height);

	// loop to save pixel
	for (int y = 0; y < height; ++y)
	{
		for (int x = 0; x < width; ++x)
		{
			// set gray
			unsigned char gray = p_mem[y * width + x];
			inputImage.setPixel(x, y, qRgb(gray, gray, gray));
		}
	}

	// save data
	if (!inputImage.save(outputPath))
	{
		qDebug() << "Failed to save processed image";
	}

	// free data here
	if(p_mem) free(p_mem);
}

代码当中有两个地方需要注意一下,第一个地方,它生成了gray灰度值,并且把这个数值保存到了p_mem指向的空间里面。第二个地方,它把来自于p_mem的数据,保存到inputImage的下面。这两个部分中间的generate_binary_image函数,才是我们需要真正处理的地方。

3、编写纯图像算法

纯图像算法,一般就是对内存数据进行操作和处理。操作的方法,通常就是数字图像处理和分析的基本方法。编写的过程中,尽量参照算法的基本逻辑来。同时,参考一下效率,

复制代码
void generate_binary_img(unsigned char* p_char, int width, int height)
{
	unsigned char* p_outer;
	unsigned char* p_inner;
	int x, y;

	for (y = 0, p_outer = p_char; y < height; ++y, p_outer += width)
	{
		p_inner = p_outer;
		for (x = 0; x < width; ++x, ++p_inner)
		{
			if (*p_inner > 120)
				*p_inner = 255;
			else
				*p_inner = 0;
		}
	}
}

4、文件整合和处理

所有的内容都准备好之后,就可以加入main函数,实现代码的测试了。这部分内容比较简单,大家直接看代码就好了。目前整个过程都是在windows平台完成的,主要还是因为windows上面开发和调试比较方便。

复制代码
int main()
{
	// set input and output path
	QString inputPath = "D:/lena.bmp";
	QString outputPath = "D:/lena_binary.bmp";

	// process image
	processImage(inputPath, outputPath);
	return 0;
}

5、从soc到mcu

和soc相比较,mcu的算力、内存和flash都是不足的,所以一般为了处理图像,会找一些频率高一点的mcu,比如400m的h7。内存方面,mcu通常只有1m左右,这部分未必能够满足需要,通常会外扩一个sram chip。flash的话,通常不做要求,如果要数据导出的话,裸数据存到micro sd卡即开。保存的方式,可以直接是二进制保存,没必要保存成为bmp格式,到时候自己写一个解析的上位机即可。

6、软件编写

因为mcu的库比较少,语法支持上面也比较有限,所以大家编写算法的时候尽可能简单明了,不要用太多的语法糖。如果是为了提高效率,尽量使用空间换时间的方法来解决。另外,mcu虽然性能差一点,但是胜在稳定性和成本方面,作为产品开发来说,也是很好的一个选择,大家不必过多地去矮化mcu。只要能满足需求,降低成本,就是好的方案、优秀的方案。

相关推荐
小鸡吃米…3 分钟前
自然语言处理 —— 信息检索
人工智能·自然语言处理·nlp
WJSKad123517 分钟前
[特殊字符] SecRoBERTa:网络安全AI新里程碑[特殊字符]️
人工智能·安全·web安全
zach012726 分钟前
GEO优化的算力贫困悖论:基于数字地缘政治的量子搜索语义重构
人工智能·python·重构
發糞塗牆39 分钟前
【Azure 架构师学习笔记 】- Azure AI(14)-Azure OpenAI(5)-OpenAI 智能文本处理小工具
人工智能·ai·azure
东离与糖宝1 小时前
Spring Boot 3 + Qwen 3.5 最佳实践:从接口调用到 RAG 向量检索一站式开发
java·人工智能
kisshuan123961 小时前
[特殊字符] MangaLens:AI精准识别漫画气泡,对话内容一目了然
人工智能
电子科技圈1 小时前
从工具到平台:如何化解跨架构时代的工程开发和管理难题
人工智能·设计模式·架构·编辑器·软件工程·软件构建·设计规范
zhangshuang-peta1 小时前
加密MCP保险库:人工智能系统中安全凭证管理的关键
人工智能·安全·chatgpt·ai agent·mcp·peta
yuhaiqiang1 小时前
太牛了🐂,再也没有被AI 骗过,自从用了这个外挂 !必须装上
javascript·人工智能·后端
GISer_Jing1 小时前
Agent技术深度解析:LLM增强智能体架构与优化
前端·人工智能·架构·aigc