当前位置: 首页 > article >正文

【正点原子K210连载】第三十四章 image图像滤波实验 摘自【正点原子】DNK210使用指南-CanMV版指南

第三十四章 image图像滤波实验

在上一章节中,介绍了image模块中元素绘制方法给的使用,本章将继续介绍image模块中图像滤波方法的使用。通过本章的学习,读者将学习到image模块中图像滤波的使用。
本章分为如下几个小节:
34.1 image模块图像滤波方法介绍
34.2 硬件设计
34.3 程序设计
34.4 运行验证

34.1 image模块图像滤波方法介绍
image模块为Image对象提供了histeq()方法,用于对图像进行直方图均衡处理,histeq()方法如下所示:
image.histeq(adaptive=False, clip_limit=-1)
histeq()方法用于对图像进行直方图均衡处理,直方图均衡处理能够使得图像中的对比度和亮度标准化。
adaptive指的是是否使用自适应直方图均衡算法,自适应直方图均衡算法通常比非自适应直方图均衡算法效果更好,但需要更长的运行时间,当为False时,使用非自适应直方图均衡算法,当为True时,使用自适应直方图均衡算法,默认为False。
clip_limit指的是自适应均衡对比度,默认为-1。
histeq()方法会返回经过处理的Image对象。
histeq()方法的使用示例如下所示:
import image

img = image.Image(size=(320, 240))
img.histeq(adaptive=True, clip_limit=3)
image模块为Image对象提供了gaussian()方法,用于对图像进行模糊滤波处理,gaussian()方法如下所示:
image.gaussian(size, unsharp=False, mul, add=0, threshold=False, offset=0, invert=False, mask)
gaussian()方法用于对图像进行模糊滤波处理,具体的实现方式是使用平滑高斯核对图像进行卷积。
size指的是卷积核的大小,可为1(33)、2(55)或更高值。
unsharp指的是执行非锐化掩膜操作,从而提高边缘的图像清晰度。
mul指的是用以与卷积结果相乘的数字,若不设置,则使用默认的自动值,该值将放置卷积输出中的缩放,可以进行全局对比度调整。
add指的是用来与每个像素卷积结果相加的数值,可以进行全局亮度调整。
threshold指的是是否开启图像的自适应阈值处理,开启后可以根据环境像素的亮度,将像素设置为1或者0。
offset指的是开启图像的自适应阈值处理后,如何将像素设置为1,若为负数,则会将更多的像素设置为1,若为正数,则仅将最强对比度的像素设置为1。
invert指的是是否反转二进制图像的输出结果。
mask指的是另一个用作绘图操作的像素级掩码的图像,掩码应该是一个只有黑色和白色像素的图像,并且因该与所处理的Image对象具有相同的大小,仅有掩码中设置的像素会被修改。
gaussian()方法会返回经过处理的Image对象。
gaussian()方法的使用示例如下所示:

import image

img = image.Image(size=(320, 240))
img.gaussian(2)

image模块为Image对象提供了cartoon()方法,用于对图像进行卡通滤波处理,cartoon()方法如下所示:
image.cartoon(seed_threshold=0.05, floating_threshold=0.05, mask)
cartoon()方法用于对图像进行卡通滤波处理,对图像进行卡通滤波后,还会使用flood-fills算法填充图像中的所有像素区域,通过使图像的所有区域颜色变平来有效地从图像中去除纹理,为了获得最佳效果,图像应具有大量对比度,以使区域不会太容易相互渗透。
seed_threshold指的是填充区域中的像素与原始起始像素的差异。
floating_threshold指的是填充区域中的像素与任何相邻像素的差异。
mask指的是另一个用作绘图操作的像素级掩码的图像,掩码应该是一个只有黑色和白色像素的图像,并且因该与所处理的Image对象具有相同的大小,仅有掩码中设置的像素会被修改。
cartoon()方法会返回经过处理的Image对象。
cartoon()方法的使用示例如下所示:

import image

img = image.Image(size=(320, 240))
img.cartoon(seed_threshold=0.2, floating_threshold=0.05)

image模块为Image对象提供了binary()方法,用于对图像进行二值滤波处理,binary()方法如下所示:
image.binary(thresholds, invert=False, zero=False, mask)
binary()方法用于对图像进行二值滤波处理,二值滤波处理后的图像中的所有像素会被设置为黑色或白色。
thresholds指的是阈值列表,方法会根据像素值是否在阈值列表中的阈值内,来决定将像素这是为黑色或者白色。
invert指的是是否对阈值进行反转操作。
zero指的是将阈值像素清零,并使不在阈值列表中的像素保持不变。
mask指的是另一个用作绘图操作的像素级掩码的图像,掩码应该是一个只有黑色和白色像素的图像,并且因该与所处理的Image对象具有相同的大小,仅有掩码中设置的像素会被修改。
binary()方法会返回经过处理的Image对象。
binary()方法的使用示例如下所示:

import image

img = image.Image(size=(320, 240))
img.binary([(25, 94, -12, 32, -71, -12)], invert=True, zero=True)

image模块为Image对象提供了laplacian()方法,用于对图像进行边缘滤波处理,laplacian()方法如下所示:
image.laplacian(size, sharpen=False, mul, add=0, threshold=False, offset=0, invert=False, mask)
laplacian()方法用于对图像进行边缘滤波处理,具体的实现方式是使用拉普拉斯核对图像进行卷积。
size指的是卷积核的大小,可为1(33)、2(55)或更高值。
sharpen指的是是否改为锐化想,而不是仅输出未经过阈值处理的边缘检测图像,增加卷积核大小然后增加图像清晰度。
mul指的是用以与卷积结果相乘的数字,若不设置,则使用默认的自动值,该值将放置卷积输出中的缩放,可以进行全局对比度调整。
add指的是用来与每个像素卷积结果相加的数值,可以进行全局亮度调整。
threshold指的是是否开启图像的自适应阈值处理,开启后可以根据环境像素的亮度,将像素设置为1或者0。
offset指的是开启图像的自适应阈值处理后,如何将像素设置为1,若为负数,则会将更多的像素设置为1,若为正数,则仅将最强对比度的像素设置为1。
invert指的是是否反转二进制图像的输出结果。
mask指的是另一个用作绘图操作的像素级掩码的图像,掩码应该是一个只有黑色和白色像素的图像,并且因该与所处理的Image对象具有相同的大小,仅有掩码中设置的像素会被修改。
laplacian()方法会返回经过处理的Image对象。
laplacian()方法的使用示例如下所示:

import image

img = image.Image(size=(320, 240))
img.laplacian(1)

image模块为Image对象提供了morph()方法,用于对图像进行卷积处理,morph()方法如下所示:
image.morph(size, kernel, mul, add=1, threshold=False, offset=0, invert=False, mask)
morph()方法用于对图像进行卷积处理,需要提供卷积操作使用的卷积核。
size指的是卷积核的大小,可为1(33)、2(55)或更高值。
mul指的是用以与卷积结果相乘的数字,若不设置,则使用默认的自动值,该值将放置卷积输出中的缩放,可以进行全局对比度调整。
add指的是用来与每个像素卷积结果相加的数值,可以进行全局亮度调整。
threshold指的是是否开启图像的自适应阈值处理,开启后可以根据环境像素的亮度,将像素设置为1或者0。
offset指的是开启图像的自适应阈值处理后,如何将像素设置为1,若为负数,则会将更多的像素设置为1,若为正数,则仅将最强对比度的像素设置为1。
invert指的是是否反转二进制图像的输出结果。
mask指的是另一个用作绘图操作的像素级掩码的图像,掩码应该是一个只有黑色和白色像素的图像,并且因该与所处理的Image对象具有相同的大小,仅有掩码中设置的像素会被修改。
morph()方法会返回经过处理的Image对象。
morph()方法的使用示例如下所示:

import image

kernrl = [
    -1,  0,  1,
    -2,  0,  2,
    -1,  0,  1
]
img = image.Image(size=(320, 240))
img.morph(1, kernrl)

image模块为Image对象提供了negate()方法,用于对图像进行像素翻转处理,negate()方法如下所示:
image.negate()
negate()方法用于对图像进行像素翻转处理,处理的速度非常快速,且能够对每个颜色通道的像素值进行数值转换。
negate()方法会返回经过处理的Image对象。
negate()方法的使用示例如下所示:

import image

img = image.Image(size=(320, 240))
img.negate()

image模块为Image对象提供了rotation_corr()方法,用于对图像进行透视矫正处理,rotation_corr()方法如下所示:
image.rotation_corr(x_rotation=0, y_rotation=0, z_rotation=0, x_translation=0, y_translation=0, zoom=1, fov=60, corners)
roataion_corr()方法用于对图像进行透视矫正处理,通过对图像进行三维旋转来纠正图像中的透视问题。
x_rotation、y_rotation和z_rotation指的是图像绕X、Y和Z轴旋转的角度度数,即分别对应上下旋转、左右旋转和平面旋转。
x_translation和y_translation指的是图像旋转后沿X或Y转平移的单位数,因为转换应用于三维空间,因此单位并不是像素。
zoom指的是图像缩放的倍数,默认为1。
fov指的是在进行二维到三维投影时,在三维空间旋转图像之前内部使用的视场,当这个值接近0时,图像将被放置在距离视口无限远的地方,当这个值接近180时,图像将被放置在视口中,通常,不应该改变这个参数的默认值,但可以通过修改它来改变二维到三维的映射效果。
corners指的是一个拥有四个(x, y)tuples的list,代表四个corner用来创建四点对应单应性,将第一个corner映射到(0, 0),第二个corner(image_width-1, 0),第三个corner(image_width-1, image_height-1)和第四个corner(0, image_height-1),然后在图像被重新映射后应用三维旋转旋转,这个参数允许使用rotation_corr()方法来做一些事情,比如鸟瞰图转换。
rotation_corr()方法会返回经过处理的Image对象。
rotation_corr()方法的使用示例如下所示:

import image

img = image.Image(size=(320, 240))
target_point = [
    (-50, -50),
    (img.width()-1, 0),
    (img.width()-1+50, img.height()-1+50),
    (0, img.height()-1)
]
img.rotation_corr(corners=target_point)

image模块为Image对象提供了replace()方法,用于对图像进行镜像和翻转处理,replace()方法如下所示:
image.replace(hmirror=False, vflip=False, mask)
replace()方法用于对图像进行镜像和翻转处理。
hmirror指的是是否对图像进行水平镜像处理。
vflip指的是是否对图像进行垂直翻转处理。
mask指的是另一个用作绘图操作的像素级掩码的图像,掩码应该是一个只有黑色和白色像素的图像,并且因该与所处理的Image对象具有相同的大小,仅有掩码中设置的像素会被修改。
replace()方法会返回经过处理的Image对象。
replace()方法的使用示例如下所示:

import image

img = image.Image(size=(320, 240))
img.replace(hmirror=True)

34.2 硬件设计
34.2.1 例程功能

  1. 获取摄像头输出的图像,并使用image模块对图像进行一些处理后,将图像显示在LCD上。
  2. 当KEY0按键被按下后,切换image模块对图像的处理方式。
    34.2.2 硬件资源
    本章实验内容,主要讲解image模块的使用,无需关注硬件资源。
    34.2.3 原理图
    本章实验内容,主要讲解image模块的使用,无需关注原理图。
    34.3 程序设计
    34.3.1 image模块图像滤波方法介绍
    有关image模块图像滤波方法的介绍,请见第34.1小节《image模块图像滤波方法介绍》。
    34.3.2 程序流程图
    在这里插入图片描述

图34.3.2.1 image图像滤波实验流程图
34.3.3 main.py代码
main.py中的脚本代码如下所示:

from board import board_info
from fpioa_manager import fm
from maix import GPIO
import time
import lcd
import sensor
import gc

lcd.init()
sensor.reset()
sensor.set_framesize(sensor.QVGA)
sensor.set_pixformat(sensor.RGB565)
sensor.set_hmirror(False)

type = 0
type_dict = {
    0: "Normal",
    1: "Adaptive Histogram Equalization",
    2: "Blur",
    3: "Cartoon",
    4: "Binary",
    5: "Edge",
    6: "Kernel",
    7: "Negative",
    8: "Perspective Correction",
    9: "Mirror & Flip"
}

fm.register(board_info.KEY0, fm.fpioa.GPIOHS0)
key0 = GPIO(GPIO.GPIOHS0, GPIO.IN, GPIO.PULL_UP)

def key_irq_handler(key):
    global key0
    global type
    time.sleep_ms(20)
    if key is key0 and key.value() == 0:
        type = type + 1
        if type == len(type_dict):
            type = 0
key0.irq(key_irq_handler, GPIO.IRQ_FALLING, GPIO.WAKEUP_NOT_SUPPORT, 7)

while True:
    img = sensor.snapshot()
    if type == 0:
        # 原图
        pass
    elif type == 1:
        # 直方图均衡
        img.histeq(adaptive=True, clip_limit=3)
    elif type == 2:
        # 模糊滤波
        img.gaussian(2)
    elif type == 3:
        # 卡通滤波
        img.cartoon(seed_threshold=0.2, floating_thresholds=0.05)
    elif type == 4:
        # 二值滤波
        img.binary([(25, 94, -12, 32, -71, -12)], invert=True, zero=True)
    elif type == 5:
        # 边缘滤波
        img.laplacian(1)
    elif type == 6:
        kernrl = [
            -1,  0,  1,
            -2,  0,  2,
            -1,  0,  1
        ]
        # 图像卷积
        img.morph(1, kernrl)
    elif type == 7:
        # 像素翻转
        img.negate()
    elif type == 8:
        target_point = [
            (-50, -50),
            (img.width()-1, 0),
            (img.width()-1+50, img.height()-1+50),
            (0, img.height()-1)
        ]
        # 透视矫正
        img.rotation_corr(corners=target_point)
    elif type == 9:
        # 镜像和翻转
        img.replace(hmirror=True, vflip=True)
    else:
        type = 0
    img.draw_string(10, 10, type_dict[type], color=(255, 0, 0), scale=1.6)
    lcd.display(img)
    gc.collect()

可以看到一开始是先初始化了LCD、摄像头和中断按键,并且按下中断按键可以切换图像处理的方式。
接着在一个循环中不断地获取摄像头输出的图像,因为获取到的图像就是Image对象,因此可以直接调用image模块为Image对象提供的各种方法,然后就是对图像进行处理,最后在LCD显示处理好后的图像。
34.4 运行验证
将DNK210开发板连接CanMV IDE,点击CanMV IDE上的“开始(运行脚本)”按钮后,便能看到LCD上显示了处理后的摄像头图像,按下KEY0按键还能够切换处理方式,如下图所示:
在这里插入图片描述

图34.4.1 摄像头原图图像
在这里插入图片描述

图34.4.2 直方图均衡处理后图像
在这里插入图片描述

图34.4.3 模糊滤波处理后图像
在这里插入图片描述

图34.4.4 卡通滤波处理后图像
在这里插入图片描述

图34.4.5 二值滤波处理后图像
在这里插入图片描述

图34.4.6 边缘滤波处理后图像
在这里插入图片描述

图34.4.7 图像卷积处理后图像
在这里插入图片描述

图34.4.8 像素翻转处理后图像
在这里插入图片描述

图34.4.9 透视矫正处理后图像
在这里插入图片描述

图34.4.10 镜像和翻转处理后图像


http://www.kler.cn/news/288613.html

相关文章:

  • 什么是抽象公共代码
  • PLC边缘计算网关的选择策略-天拓四方
  • 0826-0901 各种面试笔试题算法题整理
  • CSS 样式化表格——WEB开发系列24
  • 【数据库|第9期】SQL Server、Access和Sqlite 的字段别名详解
  • 在国产芯片上实现YOLOv5/v8图像AI识别-【4.2】RK3588获取USB摄像头图像推流RTSP更多内容见视频
  • 使用 树莓派3B+ 对日本葡萄园进行经济实惠的环境监测
  • Java 入门指南:Java 并发编程 —— 线程隔离技术 ThreadLocal
  • subclass-balancing的实验结果分析
  • 开放式耳机排行榜10强?这五款绝对不能错过!
  • mysql高可用之组复制 (MGR)
  • 基于RK3568平台移植ffmpeg3.4.5及ffmpeg验证
  • 【战略游戏】
  • Docker笔记-启动容器时,时间与宿主机保持一致
  • 如何找到适合的IT外包服务商
  • 【JAVA】两轮充电桩设计模式实践分享
  • mysql5.7 TIMESTAMP NOT NULL DEFAULT ‘0000-00-00 00:00:00‘ 换版8版本 引发的问题
  • 深入Redis:细谈持久化
  • 浅析前端数据埋点监控:用户行为与性能分析的桥梁
  • ES6基础----Generator的使用
  • 【RabbitMQ之一:windows环境下安装RabbitMQ】
  • 数分基础(05)中心极限定理、假设检验与AB测试简介
  • 多线程并发性
  • 二叉树展开为列表(LeetCode)
  • 改进YOLO的群养猪行为识别算法研究及部署(小程序-网站平台-pyqt)
  • 【通俗理解】最优控制之旅——强化学习中的策略优化
  • 物业|基于SprinBoot+vue的物业管理系统(源码+数据库+文档)
  • 深入理解 CSS Flex 布局
  • Golang 字面量的表示
  • 【HarmonyOS 4.0】应用级变量的状态管理