使用Atan图像过滤器进行图像处理的编程应用

384 篇文章 ¥29.90 ¥99.00
本文探讨了Atan图像过滤器在数字图像处理中的应用,主要用于边缘检测和图像增强。通过提供的C++代码示例,展示了如何计算像素梯度,应用Atan滤波器并映射角度,从而突出图像边缘和高频细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用Atan图像过滤器进行图像处理的编程应用

图像过滤器是数字图像处理中常用的工具,它们能够改变图像的外观和特征。在本文中,我们将讨论如何使用Atan图像过滤器进行图像处理,并提供相应的源代码示例。

Atan图像过滤器是一种基于反正切函数的滤波器,它可以用于边缘检测和图像增强等应用。该滤波器的原理是对图像中的像素进行梯度计算,并将梯度值映射到0到π范围内。这使得图像中的边缘和高频细节能够更加突出地显示出来。

下面是一个使用C++语言编写的示例代码,演示了如何在图像上应用Atan滤波器:

#include <iostream>
#include <cmath>

// 定义图像的宽度和高度
const 
https://wiki.lckfb.com/zh-hans/lushan-pi-k230/这个网页是嘉立创关于庐山派K230的,请你学习一下,然后有一个博主写了一篇关于基于canmv的k230的寻迹串级pid小车的文章,他第一步先配置了摄像头,import time, os, sys, math from machine import UART from machine import FPIOA from media.sensor import * #导入sensor模块,使用摄像头相关接口 from media.display import * #导入display模块,使用display相关接口 from media.media import * #导入media模块,使用meida相关接口 #串口设置 fpioa = FPIOA() fpioa.set_function(11,FPIOA.UART2_TXD) fpioa.set_function(12,FPIOA.UART2_RXD) uart=UART(UART.UART2,115200) #设置串口号2和波特率 #固定代码 lcd_width=640 lcd_height=480 sensor=Sensor(width=1280,height=960) sensor.reset() #framesize数字越大,越显示的近,帧率越低 sensor.set_framesize(sensor.VGA) sensor.set_pixformat(Sensor.GRAYSCALE) #在mipi上显示那么frmesize需要匹配display显示 Display.init(Display.ST7701, width=lcd_width, height=lcd_height, to_ide=True) MediaManager.init() #初始化media资源管理器 sensor.run() clock=time.clock() 然后第二步,“首先需要划分ROI区域,最后一个小数为权重值,前者是告诉采集的当前区域最大面积,后者是是四个区域的中心点连成一条线后经权重比换算过来的线中心,该线中心是后面换算距离的重要之处。”,代码如下#黑线阈值 GRAYSCALE_THRESHOLD = [(0, 64)] #采样图像为VGA 640*480,列表把roi把图像分成4个矩形,越靠近的摄像头视野(通常为图像下方)的矩形权重越大。 ROIS = [ # [ROI, weight] (0,420,640,60,0.7), (0,280,640,60,0.5), # 可以根据不同机器人情况进行调整。 (0,140,640,60,0.3), (0, 0,640,60,0.1), ] weight_sum = 0 for r in ROIS: weight_sum += r[4] # r[4] 为矩形权重值. 然后第三步,利用img.find_blobs函数寻找黑色色块,阈值为:GRAYSCALE_THRESHOLD = [(0, 64)] 然后因为设置好的roi元组,那么k230会自动划分4块区域,接着计算出中心点,经权重值换算后得到线中心。权重值可以不总和为1,注意越靠近屏幕下方的权重值越大,这样换算过来的角度越大那么单片机给电机的反应越大,假设摄像头当前画面的像素是分辨率:160(宽)X120(高),左上角坐标为(0,0),然后当前出现直线坐标为(80,120)至(160,0)偏右的直线。上中下三个部分的权重分别为0.1、0.3、0.7(底部图像靠近机器人,权重大,权重总和可以不是1),我们来计算一下其中心值,得到(98,60),即X’=(800.7+1200.3+160*0.1)/(0.7+0.3+0.1)=98 于是进行偏离角度换算: 那么直线偏离坐标可以认为是(98,60),图中绿色“+”位置。那么利用反正切函数可以求出偏离角度:a = atan((98-80)/60)=16.7°,机器人相当于实线的位置往左偏了,所以加一个负号,即 -16.7°;偏离角度就是这么计算出来的。得到偏离角度后就可以自己编程去调整小车或者机器人的运动状态,直到0°为没有偏离。 代码如下 while True: clock.tick() img=sensor.snapshot() #权重值之和 centroid_sum = 0 for r in ROIS: #找到具体色块,找到当前roi矩形范围内的具体符合黑线的色块,其中合并相邻且重叠的色块 blobs=img.find_blobs(GRAYSCALE_THRESHOLD,roi=r[0:4],merge=True) if blobs: #检测到符合条件的色块时,比较色块最多的地方,定义为主路径,作用为过滤阴影 largest_blobs=max(blobs,key=lambda b: b.pixels())#lambda 参数:返回值 #开始绘画矩形,和中心点十字箭头 img.draw_rectangle(largest_blobs.rect()) img.draw_cross(largest_blobs.cx(), largest_blobs.cy()) centroid_sum+=largest_blobs.cx()*r[4] center_pos = (centroid_sum / weight_sum) # 确定直线的中心. #角度转换 angle=0 angle = -math.atan((center_pos-320)/240) #采用图像为VGA时候使用 angle = math.degrees(angle)#最终为具体角度 #lcd显示角度值,左半屏为正值 img.draw_string_advanced(2,2,20, str('%.1f' % angle), color=(255,255,255)) #串口传递角度给单片机 angle_int = int(angle * 100) # 放大100倍转为整数 uart.write(angle_int.to_bytes(2, 'little', True)) # 小端2字节 print("Turn Angle: %f" % angle) Display.show_image(img) #显示图片 print(clock.fps()) #打印FPS 小端二字节就是将原来例如42.33度的角度先转换为整数(x100),再将int转byte,然后将得到的偏离角度用串口传到stm32单片机,我们开始单片机的处理。以上就是K230的处理,你帮我总结一下最终的K230的代码
07-08
<think>我们首先需要总结用户提供的代码,并将其整合成一个完整的K230寻迹程序。代码主要分为以下几个部分: 1. 导入必要的库和模块 2. 设置串口(用于与单片机通信) 3. 初始化摄像头和显示 4. 定义黑线阈值和ROI区域(包括权重) 5. 主循环:捕获图像,处理图像(划分ROI区域,寻找黑线,计算中心点,计算角度),通过串口发送角度 注意:用户提供的代码中,ROI的定义和权重计算部分已经给出,主循环中处理每个ROI区域,找到最大的色块,计算加权中心,然后计算角度。 我们将按照用户提供的代码片段进行整合,并注意以下几点: - 摄像头初始化设置为VGA(640x480),但实际使用中,ROI区域的定义是基于这个分辨率的。 - 角度计算公式:angle = -math.atan((center_pos-320)/240) 然后转换为角度。 - 串口发送:将角度乘以100转换为整数,然后使用小端序、有符号的2字节发送。 但是,在用户提供的代码中,ROI的定义有四个区域,每个区域是一个元组,包括x, y, width, height, weight。注意ROI的y坐标是从图像底部开始(因为权重大的在下方),所以ROI定义中y坐标是从420开始往下(即图像底部)到0(顶部)。 我们整合代码,并添加必要的注释。 注意:由于用户提供的代码片段中,有些部分可能不完整(比如导入的模块可能有缺失),我们根据上下文补充完整。 最终代码:</think>以下是基于博主描述的K230寻迹串级PID小车代码总结,整合了摄像头配置、ROI处理、黑线识别和角度计算逻辑: ```python import time, math from machine import UART, FPIOA from media.sensor import * from media.display import * from media.media import * # 串口初始化 fpioa = FPIOA() fpioa.set_function(11, FPIOA.UART2_TXD) fpioa.set_function(12, FPIOA.UART2_RXD) uart = UART(UART.UART2, 115200) # 摄像头配置 lcd_width, lcd_height = 640, 480 sensor = Sensor(width=1280, height=960) sensor.reset() sensor.set_framesize(sensor.VGA) sensor.set_pixformat(Sensor.GRAYSCALE) # 显示初始化 Display.init(Display.ST7701, width=lcd_width, height=lcd_height, to_ide=True) MediaManager.init() sensor.run() clock = time.clock() # 寻迹参数配置 GRAYSCALE_THRESHOLD = [(0, 64)] # 黑线阈值 ROIS = [ # [x, y, width, height, weight] (0, 420, 640, 60, 0.7), # 底部区域(权重最大) (0, 280, 640, 60, 0.5), (0, 140, 640, 60, 0.3), (0, 0, 640, 60, 0.1), # 顶部区域 ] weight_sum = sum(r[4] for r in ROIS) # 权重总和 while True: clock.tick() img = sensor.snapshot() centroid_sum = 0 # 处理每个ROI区域 for r in ROIS: blobs = img.find_blobs(GRAYSCALE_THRESHOLD, roi=r[0:4], merge=True) if blobs: # 找出最大色块(主路径) largest_blob = max(blobs, key=lambda b: b.pixels()) img.draw_rectangle(largest_blob.rect()) img.draw_cross(largest_blob.cx(), largest_blob.cy()) # 加权累加中心点 centroid_sum += largest_blob.cx() * r[4] # 计算加权中心点 center_pos = centroid_sum / weight_sum # 计算偏离角度(基于VGA分辨率) angle = -math.atan((center_pos - 320) / 240) # 320=水平中心点 angle_deg = math.degrees(angle) # 显示角度值 img.draw_string_advanced(2, 2, 20, f"{angle_deg:.1f}°", color=(255,255,255)) # 串口传输角度给单片机(小端序2字节) angle_int = int(angle_deg * 100) # 放大100倍处理小数 uart.write(angle_int.to_bytes(2, 'little', signed=True)) # 显示图像和帧率 Display.show_image(img) print(f"Turn Angle: {angle_deg:.2f}°, FPS: {clock.fps():.1f}") ``` ### 核心逻辑总结: 1. **摄像头配置**:使用VGA分辨率(640x480)的灰度图像 2. **ROI分区**:垂直划分为4个矩形区域,权重从底部(0.7)到顶部(0.1)递减 3. **黑线识别**:通过`find_blobs`在每块ROI中寻找最大连续黑色区域 4. **角度计算**: - 加权中心点公式:`X' = Σ(区域中心X × 权重) / 总权重` - 角度公式:`angle = -arctan((X' - 320)/240)` 5. **数据传输**:角度值×100转为整数,通过UART以小端序2字节发送 ### 关键参数说明: | 参数 | 值 | 说明 | |------|----|------| | 水平基准 | 320 | 图像水平中心点(X轴) | | 垂直基准 | 240 | 角度计算参考点(Y轴) | | 权重分配 | 0.7→0.1 | 底部权重>顶部权重 | | 传输格式 | int16小端序 | 支持负角度传输 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值