1、直线检测
#####################################################################################################
# @file main.py
# @author 正点原子团队(ALIENTEK)
# @version V1.0
# @date 2024-01-17
# @brief image图像特征检测实验
# @license Copyright (c) 2020-2032, 广州市星翼电子科技有限公司
#####################################################################################################
# @attention
#
# 实验平台:正点原子 K210开发板
# 在线视频:www.yuanzige.com
# 技术论坛:www.openedv.com
# 公司网址:www.alientek.com
# 购买地址:openedv.taobao.com
#
#####################################################################################################from board import board_info
from fpioa_manager import fm
from maix import GPIO
import time
import lcd
import sensor
import image
import gclcd.init()
sensor.reset()
sensor.set_framesize(sensor.QVGA)
sensor.set_pixformat(sensor.RGB565)
sensor.set_vflip(True)type = 0
type_dict = {0: "Normal",1: "Edge",2: "Circle",3: "Line",4: "HoG"
}fm.register(board_info.KEY0, fm.fpioa.GPIOHS0)
key0 = GPIO(GPIO.GPIOHS0, GPIO.IN, GPIO.PULL_UP)def key_irq_handler(key):global key0global typetime.sleep_ms(20)if key is key0 and key.value() == 0:type = type + 1if 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:# 原图passelif type == 1:# 边缘检测gray = img.to_grayscale(copy=True)gray.find_edges(image.EDGE_SIMPLE, threshold=(100, 255))img.draw_image(gray, 0, 0, mask=gray)del grayelif type == 2:# 圆形检测circles = img.find_circles((0, 0, img.width(), img.height()), x_stride=2, y_stride=2, threshold=3800, x_margin=50, y_margin=50, r_margin=50, r_min=60, r_max=80, r_step=5)for c in circles:img.draw_circle(c.x(), c.y(), c.r(), color=(255, 0, 0), thickness=2)elif type == 3:# 直线检测lines = img.find_lines((0, 0, img.width(), img.height()), x_stride=2, y_stride=1, threshold=1000, theta_margin=25, rho_margin=25)for l in lines:img.draw_line(l.line(), color=(255, 0, 0), thickness=2)elif type == 4:img.to_grayscale()# HoG检测img.find_hog((0, 0, img.width(), img.height()), size=8)else:type = 0img.draw_string(10, 10, type_dict[type], color=(255, 0, 0), scale=1.6)lcd.display(img)gc.collect()
-
(0, 0, img.width(), img.height())
- 这是一个元组,定义了要在图像中搜索直线的矩形区域。
- (0, 0) 是矩形左上角的坐标。
- (img.width(), img.height()) 是矩形右下角的坐标。
- 这里设置为整个图像范围,意味着在整张图片中搜索直线。
-
x_stride=2
- 水平方向上的采样步长。
- 值为2表示每隔一个像素进行一次采样,即跳过一个像素。
- 用于减少处理的数据量,提高速度,但可能略微降低精度。
-
y_stride=1
- 垂直方向上的采样步长。
- 值为1表示每个垂直像素都会被采样。
- 比x_stride小,意味着垂直方向的采样更密集。
-
threshold=1000
- 霍夫变换中的投票阈值。
- 只有在参数空间中获得至少1000票的直线才会被检测并返回。
- 较高的阈值会检测到更少但更显著的直线。
-
theta_margin=25
- 角度容差,单位为度。
- 用于合并相似角度的直线。
- 如果两条直线的角度差小于25度,它们可能被视为同一条线。
-
rho_margin=25
- 距离容差,单位为像素。
- 用于合并距离相近的平行线。
- 如果两条平行线的距离小于25像素,它们可能被合并为一条。
这些参数共同控制了直线检测的精度、灵敏度和效率。通过调整这些参数,可以在不同的应用场景中找到最佳的直线检测效果。例如,增加threshold可以减少检测到的直线数量,但会更关注主要的线条;减小stride可以提高检测精度,但会增加计算时间。
2、边缘检测
gray = img.to_grayscale(copy=True)
gray.find_edges(image.EDGE_SIMPLE, threshold=(50, 100))
img.draw_image(gray, 0, 0, mask=gray)
-
gray = img.to_grayscale(copy=True)
- 将原始图像
img
转换为灰度图像。 copy=True
参数表示创建一个新的图像副本,而不是直接修改原图。- 灰度图像只包含亮度信息,简化了后续的边缘检测过程。
- 将原始图像
-
gray.find_edges(image.EDGE_SIMPLE, threshold=(50, 100))
- 在灰度图像上执行边缘检测。
image.EDGE_SIMPLE
指定使用简单的边缘检测算法。threshold=(50, 100)
设置双阈值:- 低阈值50:像素值低于此值不被视为边缘。
- 高阈值100:像素值高于此值一定被视为边缘。
- 介于两者之间的像素,如果与高于高阈值的像素相连,也被视为边缘。
-
img.draw_image(gray, 0, 0, mask=gray)
- 将检测到的边缘绘制回原始图像
img
上。 (0, 0)
指定绘制的起始位置(左上角)。mask=gray
使用灰度图像作为掩码,确保只有边缘部分被绘制。
- 将检测到的边缘绘制回原始图像
这种边缘检测技术常用于:
- 物体轮廓提取
- 图像分割
- 特征识别
- 计算机视觉任务的预处理
通过调整阈值,可以控制边缘检测的敏感度。较低的阈值会检测到更多的边缘,但可能包含更多噪声;较高的阈值则会检测到更少但更显著的边缘。
3、色块追踪
#####################################################################################################
# @file main.py
# @author 正点原子团队(ALIENTEK)
# @version V1.0
# @date 2024-01-17
# @brief image图像色块追踪实验
# @license Copyright (c) 2020-2032, 广州市星翼电子科技有限公司
#####################################################################################################
# @attention
#
# 实验平台:正点原子 K210开发板
# 在线视频:www.yuanzige.com
# 技术论坛:www.openedv.com
# 公司网址:www.alientek.com
# 购买地址:openedv.taobao.com
#
#####################################################################################################import lcd
import sensor
import gclcd.init()
sensor.reset()
sensor.set_framesize(sensor.QVGA)
sensor.set_pixformat(sensor.RGB565)
sensor.set_vflip(True)
sensor.set_auto_gain(False, gain_db=6.0)
sensor.set_auto_whitebal(False)while True:img = sensor.snapshot()# 色块追踪threshold = (7, 63, -21, 46, -71, -23)blobs = img.find_blobs([threshold], False, (0, 0, img.width(), img.height()), x_stride=2, y_stride=1, area_threshold=10, pixels_threshold=10, merge=True, margin=10)for b in blobs:img.draw_rectangle(b.rect(), color=(255, 0, 0))lcd.display(img)gc.collect()
-
[threshold]
- 一个颜色阈值列表,用于定义要查找的色块的颜色范围。
- 例如,可能是
[(0, 100, 0, 120, 0, 100)]
表示在LAB颜色空间中的特定范围。
-
False
- 这个参数通常用于指定是否进行像素级别的颜色匹配。
False
表示不进行像素级别的匹配,可能会更快但精度略低。
-
(0, 0, img.width(), img.height())
- 定义搜索色块的区域,这里是整个图像。
-
x_stride=2, y_stride=1
- 水平和垂直方向的扫描步长。
x_stride=2
表示每隔一个像素在水平方向扫描。y_stride=1
表示垂直方向每个像素都扫描。
-
area_threshold=10
- 色块的最小面积阈值。
- 小于此面积的色块将被忽略。
-
pixels_threshold=10
- 色块的最小像素数阈值。
- 像素数少于此值的色块将被忽略。
-
merge=True
- 是否合并相邻的色块。
True
表示会合并靠近的色块。
-
margin=10
- 合并色块时的边距。
- 如果两个色块的距离小于这个值,它们可能会被合并。
这个函数的作用是:
- 在指定的颜色范围内搜索色块。
- 使用给定的步长进行扫描,以平衡速度和精度。
- 过滤掉太小的色块(基于面积和像素数)。
- 可能合并相近的色块。
这种色块检测通常用于:
- 目标检测和跟踪
- 颜色分割
- 物体计数
- 图像分析和处理
通过调整这些参数,你可以根据具体需求优化色块检测的效果和效率。