亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Manufacturing Technology >> 制造工艺

自动视觉对象跟踪

一种帮助使用视觉自动跟踪彩色物体的摄像头。

故事

简介

在我的上一个教程中,我们探讨了如何控制平移/倾斜伺服设备以定位 PiCam。现在我们将使用我们的设备来帮助相机自动跟踪颜色对象

这是我第一次使用 OpenCV,我必须承认,我爱上了这个奇妙的“开源计算机视觉库”。

OpenCV 可免费用于学术和商业用途。它具有 C++、C、Python 和 Java 接口,并支持 Windows、Linux、Mac OS、iOS 和 Android。在我的 OpenCV 教程系列中,我们将重点关注 Raspberry Pi(因此,Raspbian 作为 OS)和 Python。 OpenCV 旨在提高计算效率,并非常注重实时应用程序。因此,它非常适合物理计算项目!

第 1 步:BOM - 物料清单

主要部分:

(*) 您可以购买带有伺服系统的完整平移/倾斜平台或构建自己的平台。

第 2 步:安装 OpenCV 3 包

我使用的是更新到 Raspbian (Stretch) 最新版本的 Raspberry Pi V3,因此安装 OpenCV 的最佳方法是遵循 Adrian Rosebrock 开发的优秀教程:Raspbian Stretch:安装Raspberry Pi 上的 OpenCV 3 + Python。

我尝试了几种不同的指南来在我的 Pi 上安装 OpenCV。 Adrian 的教程是最好的。我建议你也这样做,按照他的指导一步一步来。

完成 Adrian 的教程后,您应该有一个 OpenCV 虚拟环境准备好在您的 Pi 上运行我们的实验。

让我们进入我们的虚拟环境并确认 OpenCV 3 已正确安装。

Adrian 建议您每次打开新终端时都运行命令“source”,以确保您的系统变量设置正确。

源码 ~/.profile

接下来,让我们进入我们的虚拟环境:

工作简历

如果您看到提示前的文本 (cv),则您处于 cv 虚拟 环境:

(cv) pi@raspberry:~$

Adrian 提请注意cv Python 虚拟环境 完全独立并与 Raspbian Stretch 下载中包含的默认 Python 版本隔离。因此,全局 site-packages 目录中的任何 Python 包都将无法用于 cv 虚拟环境。同样,安装在 cv 的 site-packages 中的任何 Python 包将无法用于 Python 的全局安装。

现在,输入您的 Python 解释器:

python

并确认您运行的是3.5(或以上)版本

在解释器内(会出现“>>>”),导入 OpenCV 库:

导入 cv2

如果没有出现错误消息,则 OpenCV 已正确安装在您的 PYTHON 虚拟环境中。

也可以查看安装的OpenCV版本:

cv2.__version__

应该会出现3.3.0(或者以后可以发布的高级版本)。上面的终端打印屏幕显示了前面的步骤。

第 3 步:测试您的相机

在您的 RPi 中安装 OpenCV 后,让我们测试您的相机是否正常工作。

我假设您的 Raspberry Pi 上已经安装了 PiCam。

在您的 IDE 中输入以下 Python 代码:

import numpy as npimport cv2cap =cv2.VideoCapture(0)while(True):ret, frame =cap.read() frame =cv2.flip(frame, -1) # 垂直翻转相机gray =cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) cv2.imshow('frame', frame) cv2.imshow('gray', gray) if cv2.waitKey(1) &0xFF ==ord('q'):breakcap.release()cv2.destroyAllWindows()

以上代码将捕获由您的 PiCam 生成的视频流,并以 BGR 颜色和灰色模式显示。

请注意,由于相机的组装方式,我垂直旋转了相机。如果不是您的情况,请注释或删除“翻转”命令行。

您也可以从我的 GitHub 下载代码:simpleCamTest.py

执行,输入命令:

python simpleCamTest.py

要完成程序,您必须按键盘上的 [q] 或 [Ctrl] + [C] 键

如图所示。

要了解有关 OpenCV 的更多信息,您可以按照教程进行操作:loading -video-python-opencv-tutorial

第 4 步:使用 OpenCV 在 Python 中进行颜色检测

我们将尝试完成的一件事是检测和跟踪某个颜色对象。为此,我们必须多了解一点 OpenCV 如何解释颜色。

Henri Dang 写了一篇关于使用 OpenCV 在 Python 中进行颜色检测的精彩教程。

通常,我们的相机会使用RGB颜色模式,可以理解为可以将其理解为可以由红、绿、蓝三种颜色的光组成的所有可能的颜色。我们将在这里使用 BGR(蓝色、绿色、红色)代替。

如上所述,对于 BGR,一个像素由 3 个参数表示,蓝色、绿色和红色。每个参数的值通常为 0 – 255(或十六进制的 O 到 FF)。例如,计算机屏幕上的纯蓝色像素的 B 值为 255,G 值为 0,R 值为 0。

OpenCV 与 HSV(色相、饱和度、值)颜色模型一起使用,它是 RGB 颜色模型的替代表示,由计算机图形研究人员在 1970 年代设计,以更接近人类的方式视觉感知造色属性:

很棒。因此,如果您想使用 OpenCV 跟踪某种颜色,则必须使用 HSV 模型对其进行定义。

示例

假设我必须跟踪一个黄色物体,如上图所示的塑料盒。容易的部分是找到它的 BGR 元素。您可以使用任何设计程序来查找它(我使用的是 PowerPoint)。

就我而言,我发现:

  • 蓝色:71
  • 绿色:234
  • 红色:213

接下来,我们必须将 BGR (71, 234, 213) 模型转换为 HSV 模型,该模型将定义为上下范围边界。为此,让我们运行以下代码:

import sysimport numpy as npimport cv2blue =sys.argv[1]green =sys.argv[2]red =sys.argv[3] color =np.uint8([[[blue, green] , red]]])hsv_color =cv2.cvtColor(color, cv2.COLOR_BGR2HSV)hue =hsv_color[0][0][0]print("下限是:"),print("[" + str(hue- 10) + ", 100, 100]\n")print("上限是:"),print("[" + str(hue + 10) + ", 255, 255]")

您也可以从我的 GitHub 下载代码:bgr_hsv_converter.py

要执行,请输入以下命令,将之前找到的 BGR 值作为参数:

python bgr_hsv_converter.py 71 234 213

程序将打印我们对象颜色的上下边界。

在这种情况下:

下限:[24, 100, 100]

上限:[44, 255, 255]

终端打印屏幕显示结果。

最后,但同样重要的是,让我们看看一旦我们确定了对象的颜色,OpenCV 如何“屏蔽”它:

import cv2import numpy as np# 阅读图片 - 1 表示我们想要 BGRimg =cv2.imread('yellow_object.JPG', 1) # 将每个轴的图像大小调整为 20%img =cv2.resize(img, (0,0), fx=0.2, fy=0.2)# 将 BGR 图像转换为 HSV imagehsv =cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # NumPy 创建数组来保存下和上range # “dtype =np.uint8”表示数据类型为 8 位整数lower_range =np.array([24, 100, 100], dtype=np.uint8) upper_range =np.array([44, 255, 255 ], dtype=np.uint8)# create a mask for imagemask =cv2.inRange(hsv, lower_range, upper_range)# 将mask和图像并排显示cv2.imshow('mask',mask)cv2.imshow ('image', img)# 等待用户按下 [ ESC ] while(1):k =cv2.waitKey(0) if(k ==27):breakcv2.destroyAllWindows()

您也可以从我的 GitHub 下载代码:colorDetection.py

要执行,请在您的目录中输入以下命令,其中包含目标对象的照片(在我的情况下:yellow_object.JPG):

python colorDetection.py

上图将显示原始图像(“图像”)以及应用蒙版后对象的外观(“蒙版”)。

第 5 步:对象移动跟踪

现在我们知道如何使用遮罩“选择”我们的对象,让我们使用相机实时跟踪它的运动。为此,我的代码基于 Adrian Rosebrock 的 Ball Tracking with OpenCV 教程。

我强烈建议你详细阅读 Adrian 的教程。

首先,确认您是否有 imutils 库 安装。这是 Adrian 的 OpenCV 便利函数集合,可以使一些基本任务(如调整大小或翻转屏幕)更容易。如果没有,请输入以下命令在您的虚拟 Python 环境中安装该库:

pip install imutils

接下来,从我的 GitHub 下载代码 ball_tracking.py,并使用以下命令执行:

python ball_traking.py

基本上,它与 Adrian 的代码相同,除非我使用该行获得的“视频垂直翻转”:

frame =imutils.rotate(frame, angle=180)

另外,请注意使用的掩码边界是我们在上一步中得到的边界。

第 6 步:测试 GPIO

现在我们已经了解了 OpenCV 的基础知识,让我们为我们的 RPi 安装一个 LED 并开始与我们的 GPIO 交互。

按照上面的电路图:LED 的阴极将连接到 GPIO 21,其阳极通过一个 220 欧姆的电阻连接到 GND。

让我们在虚拟 Python 环境中测试 LED。

请记住,您的 Python 虚拟环境中可能没有安装 RPi.GPIO!要解决这个问题,一旦你在那里(记得确认(cv)在你的终端中),你需要使用 pip 将它安装到你的虚拟环境中:

pip 安装 RPi.GPIO

让我们使用python脚本来执行一个简单的测试:

import sysimport timeimport RPi.GPIO as GPIO# 初始化GPIO和变量redLed =int(sys.argv[1])freq =int(sys.argv[2])GPIO.setmode(GPIO.BCM) )GPIO.setup(redLed, GPIO.OUT)GPIO.setwarnings(False)print("\n [INFO] 每 {1} 秒在 GPIO {0} 处闪烁 LED(5 次)".format( redLed, freq)) for i in range(5):GPIO.output(redLed, GPIO.LOW) time.sleep(freq) GPIO.output(redLed, GPIO.HIGH) time.sleep(freq)# cleanupprint("\n [INFO] 退出程序并清理东西\n")GPIO.cleanup()

此代码将接收 GPIO 编号和 LED 应闪烁的频率(以秒为单位)作为参数。 LED 将闪烁 5 次,程序将终止。请注意,在终止之前,我们将释放 GPIO。

因此,要执行脚本,您必须输入作为参数,LED GPIO , 和频率 .

例如:

python LED_simple_test.py 21 1

上面的命令会每“1”秒让连接到“GPIO 21”的红色LED闪烁5次。

GPIO_LED_test.py 文件可以从我的 GitHub 下载

上面的终端打印屏幕显示了结果(当然你应该确认 LED 正在闪烁。

现在,让我们使用 OpenCV 和一些基本的 GPIO 东西。

第 7 步:识别颜色和 GPIO 交互

让我们开始将我们的 OpenCV 代码与 GPIO 交互集成起来。我们将从最后一个 OpenCV 代码开始,我们将在其上集成 GPIO-RPI 库,因此我们将在相机发现我们的彩色对象时打开红色 LED。此步骤中使用的代码基于 Adrian 的优秀教程 OpenCV、RPi.GPIO 和 Raspberry Pi 上的 GPIO 零:

首先要做的是“创建”我们的 LED,将其连接到特定的 GPIO:

将 RPi.GPIO 导入为 GPIOredLed =21GPIO.setmode(GPIO.BCM)GPIO.setwarnings(False)GPIO.setup(redLed, GPIO.OUT)

其次,我们必须初始化我们的 LED(关闭):

GPIO.output(redLed, GPIO.LOW)ledOn =False

现在,在循环内部,当找到对象时创建“圆圈”,我们将打开 LED:

GPIO.output(redLed, GPIO.HIGH)ledOn =True

让我们从我的 GitHub 下载完整代码:object_detection_LED.py

使用以下命令运行代码:

python object_detection_LED.py

尝试使用不同的对象(颜色和格式)。您会看到,一旦颜色在蒙版边界内匹配,LED 就会打开。

下面的视频展示了一些经验。请注意,只有留在颜色范围内的黄色物体才会被检测到,从而打开 LED。忽略不同颜色的对象。

我们在这里只使用 LED,如上一步所述。我在做视频时已经组装好了 Pan Tilt,所以忽略它。我们将在下一步处理 PAN/TILT 机制。

第 8 步:Pan Tilt 机制

现在我们已经了解了 OpenCV 和 GPIO 的基础知识,让我们安装我们的平移/倾斜机制。

有关详细信息,请访问我的教程:Pan-Tilt-Multi-Servo-Control

舵机应该连接到外部 5V 电源,将它们的数据引脚(在我的例子中,它们的黄色接线)连接到 Raspberry Pi GPIO,如下所示:

  • GPIO 17 ==> 倾斜伺服
  • GPIO 27 ==> 平移伺服

不要忘记将 GND 连接在一起 ==> Raspberry Pi – 伺服 – 外部电源)

您可以选择在 Raspberry Pi GPIO 和服务器数据输入引脚之间串联一个 1K 欧姆的电阻器。如果出现伺服问题,这将保护您的 RPi。

让我们也利用这个机会在我们的虚拟 Python 环境中测试我们的伺服系统。

让我们使用 Python 脚本对我们的驱动程序执行一些测试:

 from time import sleepimport RPi.GPIO as GPIO GPIO.setmode(GPIO.BCM)GPIO.setwarnings(False)def setServoAngle(servo, angle):pwm =GPIO.PWM(servo, 50) pwm .start(8) dutyCycle =角度 / 18. + 3. pwm.ChangeDutyCycle(dutyCycle) sleep(0.3) pwm.stop()if __name__ =='__main__':import sysservo =int(sys.argv[1]) GPIO.setup(servo, GPIO.OUT) setServoAngle(servo, int(sys.argv[2])) GPIO.cleanup()

以上代码的核心是函数setServoAngle(servo,angle)。此函数接收作为参数、伺服 GPIO 编号和伺服必须定位的角度值。一旦这个函数的输入是“角度”,我们必须将其转换为等效的占空比。

要执行脚本,您必须输入作为参数,servo GPIO , 和角度 .

例如:

pythonangleServoCtrl.py 17 45

以上命令会将连接在GPIO 17(“倾斜”)上的伺服定位为“仰角”45度。

文件angleServoCtrl.py可以从我的GitHub下载

第 9 步:找到对象实时位置

这里的想法是使用平移/倾斜机制将对象定位在屏幕中间。坏消息是,开始时我们必须实时知道对象的位置。但好消息是这很容易,一旦我们已经有了对象中心的坐标。

首先,我们将之前使用的“object_detect_LED”代码修改为打印创建对象的x,y坐标。

从我的 GitHub 下载代码:objectDetectCoord.py

代码的“核心”部分是我们找到对象并在其上画一个圆圈,中心有一个红点。

# 只有在半径满足最小尺寸时才继续如果半径> 10:# 在框架上绘制圆和质心,# 然后更新跟踪点列表 cv2.circle(frame, (int( x), int(y)), int(radius), (0, 255, 255), 2) cv2.circle(frame, center, 5, (0, 0, 255), -1) # 打印圆心坐标 mapObjectPosition(int(x), int(y)) # 如果 LED 还没有亮,则打开 LED 如果没有 ledOn:GPIO.output(redLed, GPIO.HIGH) ledOn =True

让我们将中心坐标“导出”到mapObjectPosition(int(x), int(y)) 函数以打印其坐标。功能下方:

def mapObjectPosition (x, y):print ("[INFO] 对象中心坐标在 X0 ={0} 和 Y0 ={1}".format(x, y))

运行程序,我们会在终端看到(x, y)位置坐标,如上图。移动物体并观察坐标。我们将意识到 x 从 0 到 500(从左到右),y 从 o 到 350(从上到下)。见上图。

太棒了!现在我们必须使用这些坐标作为我们的平移/倾斜跟踪系统的起点

第 10 步:物体位置跟踪系统

我们希望我们的对象始终位于屏幕中央。因此,让我们定义例如,如果满足以下条件,我们将认为我们的对象“居中”:

  • 220
  • 160

在这些边界之外,我们必须移动我们的平移/倾斜机制来补偿偏差。基于此,我们可以构建函数 mapServoPosition(x, y) 如下。注意这个函数中用作参数的“x”和“y”与我们之前用于打印中心位置的相同:

#定位舵机以在framedef的中心呈现对象 mapServoPosition (x, y):global panAngle globaltiltAngle if (x <220):panAngle +=10 if panAngle> 140:panAngle =140 positionServo (panServo, panAngle) if (x> 280):panAngle -=10 if panAngle <40:panAngle =40 positionServo (panServo, panAngle) if (y <160):tiltAngle +=10 iftiltAngle> 140:tiltAngle =140 positionServo(tiltServo,tiltAngle)如果(y> 210):tiltAngle -=10 如果tiltAngle <40:tiltAngle =40 positionServo(tiltServo,tiltAngle)

基于 (x, y) 坐标,使用函数 positionServo(servo, angle) 生成伺服位置命令。 例如,假设 y 位置为“50”,这意味着我们的物体几乎在屏幕顶部,这可以翻译为“相机视线”为“低”(假设倾斜角度为 120 度)所以我们必须“减小”倾斜角(比方说到 100 度),这样相机视线就会“向上”,物体在屏幕上会“向下”(y 会增加到 190 度)。

上图显示了几何方面的示例。

想想平移相机将如何操作。请注意,屏幕不是镜像的,这意味着如果您将对象移动到“您的左侧”,一旦您与相机相对,它就会在屏幕上移动“您的右侧”。

函数positionServo(servo,angle)可以写成:

def positionServo (servo, angle):os.system("pythonangleServoCtrl.py" + str(servo) + " " + str(angle)) print("[INFO] 定位伺服在GPIO {0} 到 {1} 度\n".format(servo, angle))

我们将调用之前显示的脚本进行伺服定位。

注意angleServoCtrl.py必须和objectDetectTrac.py在同一个目录下

完整代码可以从我的 GitHub 下载:objectDetectTrack.py

第 11 步:结论

一如既往,我希望这个项目可以帮助其他人找到进入激动人心的电子世界的道路!

有关详细信息和最终代码,请访问我的 GitHub 存储库:OpenCV-Object-Face-Tracking

更多项目,请访问我的博客:MJRoBot.org

来自世界南部的Saludos!

下个教程见!

谢谢

来源: 自动视觉对象跟踪


制造工艺

  1. Python 运算符
  2. Python 面向对象编程
  3. Raspberry Pi Ball 跟踪
  4. Speathe
  5. 实时人脸识别:端到端项目
  6. Python - 面向对象
  7. 确定动态对象跟踪精度
  8. 过滤器在 6D 姿势估计中增强机器人视觉
  9. 什么是自动冲压机?
  10. 什么是自动动力压力机?
  11. 什么是自动弯管机?
  12. 什么是自动转台?