一、实践目标
本项目在行空板上外接USB摄像头,通过摄像头来检测目标物,并框出目标物的边缘部分。
二、知识目标
学习使用opencv库实现Canny边缘检测的的方法。
三、实践准备
四、实践过程
1、硬件搭建
1、将摄像头接入行空板的USB接口。
2、通过USB连接线将行空板连接到计算机。
2、软件编写第一步:打开Mind+,远程连接行空板
第二步:在“行空板的文件”中新建一个名为AI的文件夹,在其中再新建一个名为“基于行空板的opencv边缘检测”的文件夹,导入本节课的依赖文件。
第三步:编写程序 在上述文件的同级目录下新建一个项目文件,并命名为“main.py”。 示例程序:
- #!/usr/bin/env python
-
- '''
- This sample demonstrates Canny edge detection.
- ..
- '''
-
- # Python 2/3 compatibility
- from __future__ import print_function
-
- import cv2 as cv
- import numpy as np
-
- # relative module
- import video
-
- # built-in module
- import sys
-
- def main():
- try:
- fn = sys.argv[1] # 尝试获取命令行参数作为视频源
- except:
- fn = 0 # 如果没有提供命令行参数,则使用默认摄像头作为视频源
-
- def nothing(*arg):
- pass
-
- # 创建一个名为 "edge" 的窗口,以全屏模式显示
- cv.namedWindow('edge',cv.WND_PROP_FULLSCREEN) #Set the windows to be full screen.
- cv.setWindowProperty('edge', cv.WND_PROP_FULLSCREEN, cv.WINDOW_FULLSCREEN) #Set the windows to be full screen.
-
- # 创建两个滑动条来调整Canny算法的阈值
- cv.createTrackbar('thrs1', 'edge', 2000, 5000, nothing)
- cv.createTrackbar('thrs2', 'edge', 4000, 5000, nothing)
-
- # 创建一个视频捕获对象
- cap = video.create_capture(fn)
- while True:
- # 从视频捕获对象中读取一帧
- _flag, img = cap.read()
- # 将图像转换为灰度图
- gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
- # 获取滑动条的当前位置作为Canny算法的阈值
- thrs1 = cv.getTrackbarPos('thrs1', 'edge')
- thrs2 = cv.getTrackbarPos('thrs2', 'edge')
- # 使用Canny算法找到图像中的边缘
- edge = cv.Canny(gray, thrs1, thrs2, apertureSize=5)
- # 创建一个用于显示的图像,将边缘显示为绿色
- vis = img.copy()
- vis = np.uint8(vis/2.)
- vis[edge != 0] = (0, 255, 0)
- # 显示图像
- cv.imshow('edge', vis)
- # 检查是否按下了ESC键,如果按下则退出循环
- ch = cv.waitKey(5)
- if ch == 27:
- break
-
- print('Done')
-
-
- if __name__ == '__main__':
- print(__doc__)
- main()
- cv.destroyAllWindows()
复制代码
3、运行调试第一步:运行主程序 运行“main.py”程序,将Mind+放入画面中,Mind+的边缘随即被检测出并以绿色光点框出,同时,画面中桌角的边缘亦被检测出。
4、程序解析
在上述的“main.py”文件中,我们主要通过opencv库来调用摄像头,获取实时视频流,然后使用Canny边缘检测算法找到边缘,最后将边缘显示为绿色并在窗口中显示出来。用户可以通过滑动条来实时调整Canny算法的阈值。整体流程如下,
- ①初始化:程序启动时,会读取命令行参数作为视频源,如果没有提供命令行参数,则使用默认的摄像头。然后,程序会创建一个名为 "edge" 的全屏窗口,并在这个窗口中创建两个滑动条用于调整Canny算法的阈值。
- ②主循环:程序进入一个无限循环,每次循环都会从视频源中读取一帧,然后进行以下处理:
A:将读取到的帧转换为灰度图。
B:获取滑动条的当前位置,作为Canny算法的阈值。
C:使用Canny算法对灰度图进行边缘检测,得到一个边缘图。
D:创建一个用于显示的图像,将边缘图中的边缘像素在显示图像中对应的像素设置为绿色。
E:在窗口中显示这个图像。
- ③用户交互:程序会检查用户的键盘输入,如果按下'ESC'键,那么程序会退出主循环。
- ④结束:当主循环结束时,程序会销毁所有的窗口,然后退出。
这个程序的主要目标是实时地从视频中检测边缘,并将边缘显示在窗口中。用户可以通过滑动条实时调整边缘检测的阈值,以观察不同阈值下的边缘检测效果。
五、知识园地
1. 了解Canny算法
Canny算法是一种非常流行的边缘检测算法,由John F. Canny在1986年提出。它是一种多阶段的算法,主要包括以下几个步骤:
- 噪声去除:由于边缘检测对噪声非常敏感,所以第一步是使用高斯滤波器对图像进行平滑处理,以减少噪声。
- 计算梯度强度和方向:然后,算法使用Sobel算子分别计算图像在水平方向和垂直方向的梯度,从而得到每个像素点的梯度强度和方向。
- 非极大值抑制:梯度强度图中的每一个像素点都需要与其在梯度方向上的邻居进行比较,如果当前像素点的梯度强度不比两个邻居中的任何一个大,那么就将当前像素点的梯度强度设置为零。这一步可以帮助抑制那些不是边缘的像素点。
- 双阈值处理:确定两个阈值:高阈值和低阈值,用于进一步抑制弱边缘。强度高于高阈值的被认为是“强边缘”。强度低于低阈值的被立即抑制,强度在两个阈值之间的被标记为“弱边缘”。
- 滞后阈值:最后一步是决定哪些边缘才是真正的边缘。这里会保留所有的“强边缘”,同时,如果“弱边缘”的邻居中有“强边缘”,那么也会保留这个“弱边缘”。
Canny算法的主要优点是具有良好的检测性能,能够准确地检测出图像中的边缘,并且边缘通常只有一个像素的宽度,这对于许多应用来说是非常重要的。但是,Canny算法的计算量较大,对于实时应用可能会有一些挑战。
|