【数字图像处理】RGB 转灰度图

常见的数字图像格式有 RGB, RGBA, YCbCr 等,RGB/RGBA 格式适合存储,而 YCbCr 格式适合图像处理。在数字图像处理中,通常需要将 RGB 格式的图像变换为灰度图,再进行后续的处理,例如边缘检测、锐化等。本文主要介绍数字图像 RGB 转灰度图的基本原理,并记录在紫光同创 PGL22G FPGA 平台的布署与实现过程。

目录

1. RGB 转灰度图原理

2. FPGA 布署与实现

2.1 功能与指标定义

2.2 模块设计

2.3 上板调试


1. RGB 转灰度图原理

        在研究生物视觉的过程中,人们发现人眼视网膜中包含三种视锥细胞,这三种视锥细胞的光谱吸收峰值不同,对应光的波长分别处于 450 nm, 530nm 和 570 nm 附近,对应光的颜色分别为蓝、绿、红。

        考虑人眼对不同颜色光的感知程度不同,对红、绿、蓝 3 个颜色分量分别设定一个权重,颜色分量值与对应权重相乘再累加,就得到灰度值。

        目前关于颜色权重的选取,仍存在一些争议,但总的偏差不大。常用的 RGB 转灰度图的公式如下:

Gray = 0.299 \times R + 0.587 \times G + 0.114 \times B

使用 Matlab 进行验证。

clc, clear

% 读取图像
im = imread('./loopy.png');
im = im2double(im);

% RGB转灰度图
im_r = im(:,:,1);
im_g = im(:,:,2);
im_b = im(:,:,3);
im_new = 0.299*im_r +0.587*im_g +0.114*im_b;

% 查看图像
subplot(121)
imshow(im)
title('原图像')
subplot(122)
imshow(im_new)
title('处理后图像')

2. FPGA 布署与实现

2.1 功能与指标定义

        使用紫光同创 FPGA 平台实现 RGB 转灰度图功能,FPGA 需要实现的功能与指标如下:

(1)与电脑的串口通信,用于接收用户下发的图像,波特率为 256000 Bd/s;

(2)RGB 转灰度图处理,使用 FPGA 内部的乘法器,实现颜色分量的加权;

(3)DDR3 读写控制,将处理前后的图像数据分别写入 DDR3 的不同区域,实现图像的拼接;

(4)HDMI 输出,输出一路 HDMI 信号源,用于将拼接后的图像显示在外接显示器上,分辨率为 1024×768。

2.2 模块设计

        主要的设计模块功能划分如下:


top_uart 模块

· uart_rx_slice 模块,UART 串口接收驱动模块

· uart_rx_parse 模块,UART 串口数据解析模块,从上位机接收 RGB 8bit 图像

top_vidin 模块

· vidin_pipeline 模块,缓存两行图像(使用乒乓操作),并将数据提交到 ddr3 用户数据调度模块

· mult_9x9_uaub IP,乘法器 IP,输入为 2 个 9bit 无符号数,输出为 18bit 无符号数

merge_out 模块

· dvi_timing_gen 模块,根据定义的分辨率,产生 HDMI 视频控制时序

· dvi_ddr_rd 模块,根据 HDMI 控制信号,提交读指令到 ddr3 用户数据调度模块

· dvi_encoder 模块,HDMI 输出编码(8b10b 编码)与输出驱动

· dvi_pll IP,PLL IP,将参考时钟倍频,产生需要的像素时钟信号

其中,乘法器的输入为 2 个 9bit 无符号数,RGB 颜色分量为 8bit,颜色分量系数需要扩大 512 倍再取整,由

0.299 \times 512 = 153.088 

0.587 \times 512 = 300.544

0.114 \times 512 = 58.368

得 RGB 乘法器相乘系数分别取:153,301 和 58。

FPGA 工程资源使用率如下:

4925a8030c3d4f7b814f139460e721f2.png

2.3 上板调试

使用 PyQt5 和 OpenCV 库,编写上位机程序,实现以下功能:

(1)使用 OpenCV 库加载图像,并截取左上角 512 × 384 的区域;

(2)通过串口发送给 PGL22G 开发板。

# -*- Coding: UTF-8 -*-
import cv2
import sys
import struct
from PyQt5 import Qt, QtGui, QtCore, QtWidgets, QtSerialPort

class mainWindow(Qt.QWidget):
   def __init__(self, com_port, parent=None):
      super(mainWindow, self).__init__(parent)
      #self.setGeometry(720, 300, 512, 384)
      self.setFixedSize(530, 384)
      self.setWindowTitle("PGL OpenCV Tool")

      # 创建标签与按钮
      self.img_widget = QtWidgets.QLabel()
      self.btn1 = QtWidgets.QPushButton("打开")
      self.btn1.clicked.connect(self.getfile)
      self.btn2 = QtWidgets.QPushButton("关闭")
      self.btn2.clicked.connect(self.close)

      # 创建布局
      centralLayout = QtWidgets.QVBoxLayout()
      centralLayout.addWidget(self.img_widget)
      bottomLayout = QtWidgets.QHBoxLayout()
      bottomLayout.addWidget(self.btn1)
      bottomLayout.addWidget(self.btn2)
      centralLayout.addLayout(bottomLayout)
      self.setLayout(centralLayout)

      # 串口对象
      self.COM = QtSerialPort.QSerialPort()
      self.COM.setPortName(com_port)
      self.COM.setBaudRate(256000)
      self.open_status = False
      self.row_cnt = 0
      self.img = None
      self.timer = QtCore.QTimer()
      self.timer.timeout.connect(self.sendImage)
      self.startup()

   def startup(self):
      """Write code here to run once"""
      for com_port in QtSerialPort.QSerialPortInfo.availablePorts():
         print(com_port.portName())

      # Try open serial port
      if not self.COM.open(QtSerialPort.QSerialPort.ReadWrite):
         self.open_status = False
         print("Open Serial Port failed.")
      else:
         self.open_status = True

   def getfile(self):
      """获取图像路径"""
      fname = QtWidgets.QFileDialog.getOpenFileName(self, 'Open file',
         'C:\\Users\\Administrator\\Pictures', "Image files(*.jpg *.png)")
      self.clipImage(fname[0])
      self.updateImage()
      self.sendImage()

   def clipImage(self, fname):
      """读取并裁剪图片至512x384大小"""
      if fname:
         img = cv2.imread(fname, cv2.IMREAD_COLOR)
         img_roi = img[:384,:512,:]
         print(img_roi.shape)
         cv2.imwrite('./img_roi.png', img_roi)

   def updateImage(self):
      """显示裁剪后的图像"""
      self.img_widget.setPixmap(QtGui.QPixmap('./temp/img_roi.png'))
      self.img = cv2.imread('./img_roi.png')
      self.timer.start(100)

   def sendImage(self):
      """通过串口发送图片"""
      pattern = ">4H{:d}B".format(512*3)

      if self.open_status:
         if self.row_cnt == 384:
            self.row_cnt = 0
            self.timer.stop()
         else:
            args1 = [self.row_cnt, self.img.shape[0], 0, 0]
            args2 = [rgb for rgb in self.img[self.row_cnt,:].reshape(-1)]
            send_data = struct.pack(pattern, *(args1+args2))
            self.row_cnt += 1
            self.COM.write(send_data)

def main():
   app = QtWidgets.QApplication(sys.argv)
   window = mainWindow('COM21')
   window.show()
   sys.exit(app.exec_())

if __name__ == "__main__":
   main()

 297055f22e75458a83586a9a3a6e2d98.png

        在电脑端发送图像,就可以看到 FPGA 处理结果了 ~

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

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

相关文章

改进YOLO系列 | YOLOv5/v7 引入反向残差注意力模块 iRMB | 《ICCV 2023 最新论文》

论文地址:https://arxiv.org/abs/2301.01146 代码地址:https://github.com/zhangzjn/EMO 本论文着重于开发现代、高效、轻量级的模型,用于进行密集预测,同时在参数、FLOPs和性能之间进行权衡。倒置残差块(IRB)作为轻量级CNN的基础设施,但在基于注意力的研究中尚未找到对…

计算机毕业设计选题推荐-个人记账理财微信小程序/安卓APP-项目实战

✨作者主页:IT毕设梦工厂✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

Linux——vim简介、配置方案(附带超美观的配置方案)、常用模式的基本操作

vim简介、配置方案、常用模式的基本操作 本章思维导图: 注:本章思维导图对应的xmind和.png文件都已同步导入至资源 1. vim简介 vim是Linux常用的文本编辑器,每个Linux账户都独有一个vim编辑器 本篇我们介绍vim最常用的三种模式:…

6可靠的局域网组建

前面聊的拓扑结构都比较简单,所以能用,但是未必可靠。为了可靠,我们需要做冗余,同时需要做一些其他的配置。 生成树协议STP 假设交换机按照上面的方案连,虽然可以提高网络可靠性,但是因为形成了环路&#…

谈谈越来越无效的拥塞控制

简单看一个图: 它不是互联网本身,但这是典型网络的必要组件,它决定了 flow 如何从从一边流向另一边:一条 flow 经过交换节点通过 NIC 被导入一条链路前在 buffer 中排队。 现如今大多数工程师的工作都在折腾那个单独的盒子&…

Django(复习篇)

项目创建 1. 虚拟环境 python -m venv my_env ​ cd my_env activate/deactivate ​ pip install django ​2. 项目和app创建 cd mypros django-admin startproject Pro1 django-admin startapp app1 ​3. settings配置INSTALLED_APPS【app1"】TEMPLATES【 DIRS: [os.pat…

双11终极官方战报 凯迪仕智能锁全网全渠道第一 持续领跑智能锁行业

一年一度双11狂欢盛典暂时落下帷幕,作为下半年最大的电商购物节,本次双11电商平台借机推出优惠券、补贴、折扣等促销活动,激发消费者购物热情。其中,智能门锁等智能家居产品更是取得了亮眼的成交。 据悉,凯迪仕智能锁双…

【Linux】 mdir命令使用

mdir 为mtools工具指令,模拟MS-DOS的dir指令,可显示MS-DOS文件系统中的目录内容。 语法 mdir [参数][目录] mdir命令 -Linux手册页 命令选项及作用 执行令 mdir--help 执行命令结果 参数 -a  显示隐藏文件。-f  不显示磁盘所剩余的可用空间。-w…

【C语言】函数的系统化精讲(三)

文章目录 一、递归举例二、递归举例2.1求n的阶乘2.2 顺序打印⼀个整数的每⼀位 三、递归与迭代3.1递归的思考3.2求第n个斐波那契数 总结 一、递归举例 .通过上回(【C语言】函数的系统化精讲(二))我们了解到递归的限制条件&#x…

Java终端模式小尝试

Java终端模式小尝试 1、IDE中终端1.1 拉去代码 jediterm1.2 IDE调用系统终端 2、待续~~ 1、IDE中终端 终端_Intellij IDEA、Terminal emulator | pycharm Documentation JetBrains jediterm WindTerm:新一代开源免费的终端工具,GitHub星标6.6k&#xff…

冒泡排序

贵阳这个地方的天气变化好大呀,前两天晒大太阳,今天就冷的脚抖,简直不要太冷,但是不管怎么样,还是要学习的哟! 冬天来了,春天确实还有一点远! 好了,话不多说,…

linux_day03

1、复习 遇到虚拟机异常退出,会生成配置文件,不确定文件以后是不是还要用的情况下,先改文件名,再启动虚拟机; 2、磁盘相关命令: df(disk full):查看磁盘整体状况 -h &…

ztree结合hmap使用经验分享

项目背景 在建德封控拦截系统(Vue3antd2.x)为追求更快的地图初始化体验,在尝试了hmap2.5.0版本以及2.6.3版本后,由于这两个版本在现场电脑的初始化速度不够流畅,最终使用的是hmap2.1.3版本。同时由于布控选设备&#…

2023年【起重机械指挥】考试试卷及起重机械指挥操作证考试

题库来源:安全生产模拟考试一点通公众号小程序 2023年起重机械指挥考试试卷为正在备考起重机械指挥操作证的学员准备的理论考试专题,每个月更新的起重机械指挥操作证考试祝您顺利通过起重机械指挥考试。 1、【多选题】《中华人民共和国特种设备安全法》…

在CMake中打印日志信息

message([STATUS|WARNING|AUTHOR_WARNING|FATAL_ERROR|SEND_ERROR] "message to display" ...) (无) :重要消息 STATUS :非重要消息 WARNING:CMake 警告, 会继续执行 AUTHOR_WARNING:CMake 警告 (dev), 会继续执行 SEN…

【hacker送书第一期】嵌入式虚拟化技术与应用

第一期图书推荐 前言为什么嵌入式系统需要虚拟化技术?专家推荐本书适用群体内容简介目录权威作者团队参与方式 前言 随着物联网设备的爆炸式增长和万物互联应用的快速发展,虚拟化技术在嵌入式系统上受到了业界越来越多的关注、重视和实际应用。嵌入式系…

云端部署ChatGLM-6B

大模型这里更新是挺快的,我参考的视频教程就和我这个稍微有些不一样,这距离教程发布只过去4天而已… 不过基本操作也差不多 AutoDL算力云:https://www.autodl.com/home ChatGLM3:https://github.com/THUDM/ChatGLM3/tree/main Hug…

消息队列之初识Rabbit及安装

文章目录 一、MQ的相关概念1.什么是MQ?2.为什么要用MQ2.1流量消峰2.2应用解耦2.3异步处理 3.MQ 的分类3.1.ActiveMQ3.2.Kafka3.3.RocketMQ3.4.RabbitMQ 4.MQ 的选择4.1.Kafka4.2.RocketMQ4.3.RabbitMQ 二、RabbitMQ的相关概念1.四大核心概念2.RabbitMQ 核心部分3.Ra…

OpenMMlab导出yolov3的onnx模型并推理

手动导出 直接使用脚本 import torch from mmdet.apis import init_detector, inference_detectorconfig_file ./configs/yolo/yolov3_mobilenetv2_8xb24-ms-416-300e_coco.py checkpoint_file yolov3_mobilenetv2_mstrain-416_300e_coco_20210718_010823-f68a07b3.pth mod…

数据结构-堆和二叉树

目录 1.树的概念及结构 1.1 树的相关概念 1.2 树的概念 1.3 树的表示 1.4 树在实际中的应用(表示文件系统的目录树结构) 2.二叉树的概念及结构 2.1 概念 2.2 特殊的二叉树 2.3 二叉树的存储 3.堆的概念及结构 4.堆的实现 初始化堆 堆的插入…