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

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱: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。只要能满足需求,降低成本,就是好的方案、优秀的方案。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/351334.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

远程git开发

两种本地与远程仓库同步 """ 1&#xff09;你作为项目仓库初始化人员&#xff1a;线上要创建空仓库 > 本地初始化好仓库 > 建立remote链接(remote add) > 提交本地仓库到远程(push)2&#xff09;你作为项目后期开发人员&#xff1a;远程项目仓库已经创…

快速恢复区域 - 空间管理警告和警报(文档 ID 305812.1)

快速恢复区域 - 空间管理警告和警报&#xff08;文档 ID 305812.1&#xff09;

Stable Diffusion插件Recolor实现黑白照片上色

今天跟大家分享一个使用Recolor插件通过SD实现老旧照片轻松变彩色&#xff0c;Recolor翻译过来的含义就是重上色&#xff0c;该模型可以保持图片的构图&#xff0c;它只会负责上色&#xff0c;图片不会发生任何变化。 一&#xff1a;插件下载地址 https://github.com/pkuliyi…

pinctrl子系统与gpio子系统实验-测试Led驱动框架代码

一. 简介 上一篇文章学习编写了 led驱动框架代码&#xff0c;并正常编译通过。文章地址如下&#xff1a; pinctrl子系统与gpio子系统实验-Led驱动框架代码实现-CSDN博客 本文对上一篇文章编写的驱动框架代码进行测试。测试方法与之前的驱动模块的测试方法一样。 二. 测试Le…

快速上手!使用Docker和Nginx部署Web服务的完美指南

前言 Docker是一种容器化技术&#xff0c;它可以将应用程序及其依赖项打包到一个独立的、可移植的容器中。这意味着开发人员可以在任何环境中轻松部署和运行他们的应用程序&#xff0c;而无需担心环境差异和依赖问题。而Nginx则是一款高性能的Web服务器和反向代理服务器&#x…

Chapter 8 - 1. Congestion Management in TCP Storage Networks

This chapter covers the following topics. 本章包括以下主题。 Understanding congestion in TCP storage networks. Detecting congestion in TCP storage networks. Traffic patterns with iSCSI and NVMe/TCP and correlation with network congestion. Preventing co…

Javaweb之SpringBootWeb案例之阿里云OSS服务集成的详细解析

2.3.3 集成 阿里云oss对象存储服务的准备工作以及入门程序我们都已经完成了&#xff0c;接下来我们就需要在案例当中集成oss对象存储服务&#xff0c;来存储和管理案例中上传的图片。 在新增员工的时候&#xff0c;上传员工的图像&#xff0c;而之所以需要上传员工的图像&…

C++版QT:分割窗口

目录 mainwindow.h mainwindow.cpp main.cpp Qt的分割窗口功能允许用户将一个窗口分割成多个区域&#xff0c;每个区域可以独立地显示不同的内容。这种功能在许多应用程序中非常有用&#xff0c;例如编辑器、浏览器和IDE等。 理解Qt的分割窗口&#xff0c;需要从以下几个方面…

SQL注入流程与常用语句

FLAG&#xff1a;别来我梦里了&#xff0c;我已负担不起醒来的失落 专研方向: Mysql&#xff0c;sql注入 每日emo&#xff1a;好久不见&#xff0c;寒暄几句&#xff0c;缺耗尽了半生的勇气 欢迎各位与我这个菜鸟交流学习 SQL注入流程与常用语句 1、判断注入类型&#xff0c;数…

华为三层交换机之基本操作

Telnet简介 Telnet是一个应用层协议,可以在Internet上或局域网上使用。它提供了基于文本的远程终端接口&#xff0c;允许用户在本地计算机上登录到远程计算机&#xff0c;然后像在本地计算机上一样使用远程计算机的资源。Telnet客户端和服务器之间的通信是通过Telnet协议进行的…

element-UI上传文件后valid提示不消失

问题描述&#xff1a;上传文件完成后&#xff0c;必填信息提示不消失 解决方法&#xff1a;在<el-form-item>标签添加show-message属性&#xff0c;字段为空时才显示提示信息 <el-form-item :prop"fileList" :show-message"!form.fileList || !form.f…

web服务和前端交互相关的上中游业务技术知识点梳理

文章目录 前言一、业务API网关鉴权Cookie Session 实现 API 鉴权API Key API Secrettoken 机制实现 API 鉴权 二、Tomcat、Servlet、SpringMVC总结 前言 可能之前在学校里面做的很多东西是纯后端的&#xff0c;不会涉及到太多和前端交互的细节&#xff0c;很多新手对前后端交…

MR image smoothing or filtering 既 FWHM与sigma之间的换算关系 fslmaths -s参数

这里写目录标题 FWHM核高斯核中的sigma是有一个换算公式&#xff1a;结果 大量的文献中都使用FWHM 作为单位&#xff0c;描述对MR等数据的平滑&#xff08;smoothing&#xff09;或者滤波&#xff08;filtering&#xff09;过程。FWHM 通常是指full width at half maximum的缩写…

你是在思考,还是找认同?

这两天&#xff0c;有一篇批判腾讯的文章&#xff0c;开始在互联网圈子里流传开来。 我身边也有人在传播。好奇瞅了下&#xff0c;观察到一个很有意思的地方&#xff1a; 赞同这篇文章的&#xff0c;往往也都是平时那些认为&#xff0c;腾讯面对阿里和字节的冲击岌岌可危的&…

配置dns主从服务器,实现正反向解析

一、安装bind服务 yum install bind -y二、修改主配置文件/etc/named.conf 三、配置数据配置文件/var/named/baidu 四、重启服务&#xff0c;进行测试 systemctl restart named

南昌市青山湖、滕王阁、洛阳路隧道FM调频广播集群通信调度系统应用案例

一、用户需求 青山湖隧道&#xff0c;是南昌市一条东西走向的城市主干道&#xff0c;隧道为双向6车道&#xff0c;长1070米&#xff0c;其中湖底暗埋段为550米&#xff0c;净高5.45米&#xff0c;两孔每孔净宽12.4米。 滕王阁隧道是南昌市沿江北大道与沿江中大道连通工程&#…

【代码随想录-数组】移除元素

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老导航 檀越剑指大厂系列:全面总结 jav…

案例分享 | 助力数字化转型:嘉为科技项目管理平台上线

嘉为科技项目管理平台&#xff08;一期&#xff09;基于易趋&#xff08;EasyTrack&#xff09;进行实施&#xff0c;通过近一年的开发及试运行&#xff0c;现已成功交付上线、推广使用&#xff0c;取得了良好的应用效果。 1.关于广州嘉为科技有限公司&#xff08;以下简称嘉为…

JRT执行SQL脚本

我们可能会从其他库导入表到JRT要支持的库里。或者用其他语言生成导表SQL来让JRT执行SQL创建表和导入数据&#xff0c;为此需要一个能运行SQL脚本文件的脚步。 脚本示例&#xff0c;这个是用JRT的M生成迁移表SQL生成的&#xff1a; 导入SQL的脚本&#xff1a; import JRTBL…

Docker深入解析:从基础到实践

Docker基础知识 Docker是什么&#xff1a;定义和核心概念解释 Docker是一个开源项目&#xff0c;它诞生于2013年&#xff0c;旨在自动化应用程序的部署过程&#xff0c; 让应用程序能够在轻量级的、可移植的、自给自足的容器中运行。这些容器可以在几乎任何机器上运行&#xf…
最新文章