OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 178|回复: 0

《DNK210使用指南 -CanMV版 V1.0》第三十四章 image图像滤波实验

[复制链接]

1117

主题

1128

帖子

2

精华

超级版主

Rank: 8Rank: 8

积分
4666
金钱
4666
注册时间
2019-5-8
在线时间
1224 小时
发表于 2024-10-28 17:18:59 | 显示全部楼层 |阅读模式
本帖最后由 正点原子运营 于 2024-10-28 17:18 编辑

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

1)实验平台:正点原子DNK210开发板

2)章节摘自【正点原子】DNK210使用指南 - CanMV版 V1.0


4)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/k210/ATK-DNK210.html

5)正点原子官方B站:https://space.bilibili.com/394620890

6)正点原子K210技术交流企鹅群:605557868

155537c2odj87vz1z9vj6l.jpg

155537nfqovl2gg9faaol9.png

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

34.1 image模块图像滤波方法介绍
image模块为Image对象提供了histeq()方法,用于对图像进行直方图均衡处理,histeq()方法如下所示:
  1. image.histeq(adaptive=False, clip_limit=-1)
复制代码
histeq()方法用于对图像进行直方图均衡处理,直方图均衡处理能够使得图像中的对比度和亮度标准化。
adaptive指的是是否使用自适应直方图均衡算法,自适应直方图均衡算法通常比非自适应直方图均衡算法效果更好,但需要更长的运行时间,当为False时,使用非自适应直方图均衡算法,当为True时,使用自适应直方图均衡算法,默认为False。
clip_limit指的是自适应均衡对比度,默认为-1。
histeq()方法会返回经过处理的Image对象。
histeq()方法的使用示例如下所示:
  1. import image
  2. img = image.Image(size=(320, 240))
  3. img.histeq(adaptive=True, clip_limit=3)
复制代码
image模块为Image对象提供了gaussian()方法,用于对图像进行模糊滤波处理,gaussian()方法如下所示:
  1. image.gaussian(size, unsharp=False, mul, add=0, threshold=False, offset=0, invert=False, mask)
复制代码
gaussian()方法用于对图像进行模糊滤波处理,具体的实现方式是使用平滑高斯核对图像进行卷积。
size指的是卷积核的大小,可为1(3*3)、2(5*5)或更高值。
unsharp指的是执行非锐化掩膜操作,从而提高边缘的图像清晰度。
mul指的是用以与卷积结果相乘的数字,若不设置,则使用默认的自动值,该值将放置卷积输出中的缩放,可以进行全局对比度调整。
add指的是用来与每个像素卷积结果相加的数值,可以进行全局亮度调整。
threshold指的是是否开启图像的自适应阈值处理,开启后可以根据环境像素的亮度,将像素设置为1或者0。
offset指的是开启图像的自适应阈值处理后,如何将像素设置为1,若为负数,则会将更多的像素设置为1,若为正数,则仅将最强对比度的像素设置为1。
invert指的是是否反转二进制图像的输出结果。
mask指的是另一个用作绘图操作的像素级掩码的图像,掩码应该是一个只有黑色和白色像素的图像,并且因该与所处理的Image对象具有相同的大小,仅有掩码中设置的像素会被修改。
gaussian()方法会返回经过处理的Image对象。
gaussian()方法的使用示例如下所示:
  1. import image
  2. img = image.Image(size=(320, 240))
  3. img.gaussian(2)
复制代码
image模块为Image对象提供了cartoon()方法,用于对图像进行卡通滤波处理,cartoon()方法如下所示:
  1. image.cartoon(seed_threshold=0.05, floating_threshold=0.05, mask)
复制代码
cartoon()方法用于对图像进行卡通滤波处理,对图像进行卡通滤波后,还会使用flood-fills算法填充图像中的所有像素区域,通过使图像的所有区域颜色变平来有效地从图像中去除纹理,为了获得最佳效果,图像应具有大量对比度,以使区域不会太容易相互渗透。
seed_threshold指的是填充区域中的像素与原始起始像素的差异。
floating_threshold指的是填充区域中的像素与任何相邻像素的差异。
mask指的是另一个用作绘图操作的像素级掩码的图像,掩码应该是一个只有黑色和白色像素的图像,并且因该与所处理的Image对象具有相同的大小,仅有掩码中设置的像素会被修改。
cartoon()方法会返回经过处理的Image对象。
cartoon()方法的使用示例如下所示:
  1. import image
  2. img = image.Image(size=(320, 240))
  3. img.cartoon(seed_threshold=0.2, floating_threshold=0.05)
复制代码
image模块为Image对象提供了binary()方法,用于对图像进行二值滤波处理,binary()方法如下所示:
  1. image.binary(thresholds, invert=False, zero=False, mask)
复制代码
binary()方法用于对图像进行二值滤波处理,二值滤波处理后的图像中的所有像素会被设置为黑色或白色。
thresholds指的是阈值列表,方法会根据像素值是否在阈值列表中的阈值内,来决定将像素这是为黑色或者白色。
invert指的是是否对阈值进行反转操作。
zero指的是将阈值像素清零,并使不在阈值列表中的像素保持不变。
mask指的是另一个用作绘图操作的像素级掩码的图像,掩码应该是一个只有黑色和白色像素的图像,并且因该与所处理的Image对象具有相同的大小,仅有掩码中设置的像素会被修改。
binary()方法会返回经过处理的Image对象。
binary()方法的使用示例如下所示:
  1. import image
  2. img = image.Image(size=(320, 240))
  3. img.binary([(25, 94, -12, 32, -71, -12)], invert=True, zero=True)
复制代码
image模块为Image对象提供了laplacian()方法,用于对图像进行边缘滤波处理,laplacian()方法如下所示:
  1. image.laplacian(size, sharpen=False, mul, add=0, threshold=False, offset=0, invert=False, mask)
复制代码
laplacian()方法用于对图像进行边缘滤波处理,具体的实现方式是使用拉普拉斯核对图像进行卷积。
size指的是卷积核的大小,可为1(3*3)、2(5*5)或更高值。
sharpen指的是是否改为锐化想,而不是仅输出未经过阈值处理的边缘检测图像,增加卷积核大小然后增加图像清晰度。
mul指的是用以与卷积结果相乘的数字,若不设置,则使用默认的自动值,该值将放置卷积输出中的缩放,可以进行全局对比度调整。
add指的是用来与每个像素卷积结果相加的数值,可以进行全局亮度调整。
threshold指的是是否开启图像的自适应阈值处理,开启后可以根据环境像素的亮度,将像素设置为1或者0。
offset指的是开启图像的自适应阈值处理后,如何将像素设置为1,若为负数,则会将更多的像素设置为1,若为正数,则仅将最强对比度的像素设置为1。
invert指的是是否反转二进制图像的输出结果。
mask指的是另一个用作绘图操作的像素级掩码的图像,掩码应该是一个只有黑色和白色像素的图像,并且因该与所处理的Image对象具有相同的大小,仅有掩码中设置的像素会被修改。
laplacian()方法会返回经过处理的Image对象。
laplacian()方法的使用示例如下所示:
  1. import image
  2. img = image.Image(size=(320, 240))
  3. img.laplacian(1)
复制代码
image模块为Image对象提供了morph()方法,用于对图像进行卷积处理,morph()方法如下所示:
  1. image.morph(size, kernel, mul, add=1, threshold=False, offset=0, invert=False, mask)
复制代码
morph()方法用于对图像进行卷积处理,需要提供卷积操作使用的卷积核。
size指的是卷积核的大小,可为1(3*3)、2(5*5)或更高值。
mul指的是用以与卷积结果相乘的数字,若不设置,则使用默认的自动值,该值将放置卷积输出中的缩放,可以进行全局对比度调整。
add指的是用来与每个像素卷积结果相加的数值,可以进行全局亮度调整。
threshold指的是是否开启图像的自适应阈值处理,开启后可以根据环境像素的亮度,将像素设置为1或者0。
offset指的是开启图像的自适应阈值处理后,如何将像素设置为1,若为负数,则会将更多的像素设置为1,若为正数,则仅将最强对比度的像素设置为1。
invert指的是是否反转二进制图像的输出结果。
mask指的是另一个用作绘图操作的像素级掩码的图像,掩码应该是一个只有黑色和白色像素的图像,并且因该与所处理的Image对象具有相同的大小,仅有掩码中设置的像素会被修改。
morph()方法会返回经过处理的Image对象。
morph()方法的使用示例如下所示:
  1. import image
  2. kernrl = [
  3.     -1,  0,  1,
  4.     -2,  0,  2,
  5.     -1,  0,  1
  6. ]
  7. img = image.Image(size=(320, 240))
  8. img.morph(1, kernrl)
复制代码
image模块为Image对象提供了negate()方法,用于对图像进行像素翻转处理,negate()方法如下所示:
  1. image.negate()
复制代码
negate()方法用于对图像进行像素翻转处理,处理的速度非常快速,且能够对每个颜色通道的像素值进行数值转换。
negate()方法会返回经过处理的Image对象。
negate()方法的使用示例如下所示:
  1. import image
  2. img = image.Image(size=(320, 240))
  3. img.negate()
复制代码
image模块为Image对象提供了rotation_corr()方法,用于对图像进行透视矫正处理,rotation_corr()方法如下所示:
  1. 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()方法的使用示例如下所示:
  1. import image
  2. img = image.Image(size=(320, 240))
  3. target_point = [
  4.     (-50, -50),
  5.     (img.width()-1, 0),
  6.     (img.width()-1+50, img.height()-1+50),
  7.     (0, img.height()-1)
  8. ]
  9. img.rotation_corr(corners=target_point)
复制代码
image模块为Image对象提供了replace()方法,用于对图像进行镜像和翻转处理,replace()方法如下所示:
  1. image.replace(hmirror=False, vflip=False, mask)
复制代码
replace()方法用于对图像进行镜像和翻转处理。
hmirror指的是是否对图像进行水平镜像处理。
vflip指的是是否对图像进行垂直翻转处理。
mask指的是另一个用作绘图操作的像素级掩码的图像,掩码应该是一个只有黑色和白色像素的图像,并且因该与所处理的Image对象具有相同的大小,仅有掩码中设置的像素会被修改。
replace()方法会返回经过处理的Image对象。
replace()方法的使用示例如下所示:
  1. import image
  2. img = image.Image(size=(320, 240))
  3. 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 程序流程图                              
image002.png
图34.3.2.1image图像滤波实验流程图
34.3.3 main.py代码
main.py中的脚本代码如下所示:
  1. from board import board_info
  2. from fpioa_manager import fm
  3. from maix import GPIO
  4. import time
  5. import lcd
  6. import sensor
  7. import gc
  8. lcd.init()
  9. sensor.reset()
  10. sensor.set_framesize(sensor.QVGA)
  11. sensor.set_pixformat(sensor.RGB565)
  12. sensor.set_hmirror(False)
  13. type = 0
  14. type_dict = {
  15.     0: "Normal",
  16.     1: "AdaptiveHistogram Equalization",
  17.     2: "Blur",
  18.     3: "Cartoon",
  19.     4: "Binary",
  20.     5: "Edge",
  21.     6: "Kernel",
  22.     7: "Negative",
  23.     8: "PerspectiveCorrection",
  24.     9: "Mirror &Flip"
  25. }
  26. fm.register(board_info.KEY0, fm.fpioa.GPIOHS0)
  27. key0 = GPIO(GPIO.GPIOHS0, GPIO.IN, GPIO.PULL_UP)
  28. def key_irq_handler(key):
  29.     global key0
  30.     global type
  31.    time.sleep_ms(20)
  32.     if key is key0 and key.value() == 0:
  33.        type = type + 1
  34.        if type == len(type_dict):
  35.            type = 0
  36. key0.irq(key_irq_handler, GPIO.IRQ_FALLING, GPIO.WAKEUP_NOT_SUPPORT, 7)
  37. while True:
  38.     img= sensor.snapshot()
  39.     if type == 0:
  40.        # 原图
  41.        pass
  42.     elif type == 1:
  43.        # 直方图均衡
  44.        img.histeq(adaptive=True, clip_limit=3)
  45.     elif type == 2:
  46.        # 模糊滤波
  47.        img.gaussian(2)
  48.     elif type == 3:
  49.        # 卡通滤波
  50.        img.cartoon(seed_threshold=0.2,floating_thresholds=0.05)
  51.     elif type == 4:
  52.        # 二值滤波
  53.        img.binary([(25, 94, -12, 32, -71, -12)], invert=True, zero=True)
  54.     elif type == 5:
  55.        # 边缘滤波
  56.        img.laplacian(1)
  57.     elif type == 6:
  58.        kernrl = [
  59.            -1,  0,  1,
  60.            -2,  0,  2,
  61.            -1,  0,  1
  62.        ]
  63.        # 图像卷积
  64.        img.morph(1, kernrl)
  65.     elif type == 7:
  66.        # 像素翻转
  67.        img.negate()
  68.     elif type == 8:
  69.        target_point = [
  70.            (-50, -50),
  71.            (img.width()-1, 0),
  72.            (img.width()-1+50, img.height()-1+50),
  73.            (0, img.height()-1)
  74.        ]
  75.        # 透视矫正
  76.        img.rotation_corr(corners=target_point)
  77.     elif type == 9:
  78.        # 镜像和翻转
  79.        img.replace(hmirror=True, vflip=True)
  80.     else:
  81.        type = 0
  82.     img.draw_string(10, 10, type_dict[type], color=(255, 0, 0), scale=1.6)
  83.     lcd.display(img)
  84.     gc.collect()
复制代码
可以看到一开始是先初始化了LCD、摄像头和中断按键,并且按下中断按键可以切换图像处理的方式。
接着在一个循环中不断地获取摄像头输出的图像,因为获取到的图像就是Image对象,因此可以直接调用image模块为Image对象提供的各种方法,然后就是对图像进行处理,最后在LCD显示处理好后的图像。

34.4 运行验证
将DNK210开发板连接CanMV IDE,点击CanMV IDE上的“开始(运行脚本)”按钮后,便能看到LCD上显示了处理后的摄像头图像,按下KEY0按键还能够切换处理方式,如下图所示:     
image003.png
图34.4.1 摄像头原图图像     

image005.png
图34.4.2 直方图均衡处理后图像     

image007.png
图34.4.3 模糊滤波处理后图像     

image009.png
图34.4.4 卡通滤波处理后图像     

image011.png
图34.4.5 二值滤波处理后图像     

image013.png
图34.4.6 边缘滤波处理后图像     

image015.png
图34.4.7 图像卷积处理后图像     

image017.png
图34.4.8 像素翻转处理后图像     

image019.png
图34.4.9 透视矫正处理后图像     


image021.png

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

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 06:05

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表