当前位置: 首页 > news >正文

树莓派4B_OpenCv学习笔记15:OpenCv定位物体实时坐标

今日继续学习树莓派4B 4G:(Raspberry Pi,简称RPi或RasPi)

 本人所用树莓派4B 装载的系统与版本如下:

 版本可用命令 (lsb_release -a) 查询:

 Opencv 版本是4.5.1:

今日学习 OpenCv定位物体实时位置,代码来源是创乐博,这里作学习解释

文章提供测试代码讲解,整体代码贴出、测试效果图

目录

完整实例代码贴出:

实验过程:

获取小球的准确HSV色域:

将上一步得到的HSV色域替换在程序中:

实验结果截图与视频:

网上查阅资料贴出:


完整实例代码贴出:

这个代码实现了圈出指定HSV色彩范围的圆形物体,并打印出其质心在视频帧上的坐标

并且有LED相关的亮灭操作用于指示是否检测到目标

# -*- coding: utf-8 -*-from __future__ import print_function     # 导入print函数,确保在Python 2和Python 3中都能以兼容的方式使用print。  
from imutils.video import VideoStream # 从imutils库中导入VideoStream,用于从摄像头捕获视频帧。 
import imutils                                             # 导入imutils库,该库提供了图像和视频处理的实用功能。 
import time
import cv2
import os
import RPi.GPIO as GPIO                          # 导入Raspberry Pi的GPIO库,用于控制GPIO引脚。Led = 21                                                      # 定义一个变量Led,表示连LED的GPIO引脚编号。
GPIO.setwarnings(False)                           # 关闭GPIO库的警告信息。
GPIO.setmode(GPIO.BCM)                       # 设置GPIO引脚编号模式为BCM(Broadcom SOC channel mode)。
GPIO.setup(Led, GPIO.OUT)                     # 设置GPIO引脚Led为输出模式。# 定义一个函数,用于打印对象中心的坐标。
def mapObjectPosition (x, y):print ("[INFO] Object Center coordenates at X0 = {0} and Y0 =  {1}".format(x, y))# 打印一条信息,表示正在等待摄像头预热。 
print("[INFO] waiting for camera to warmup...")
vs = VideoStream(0).start()                     # 创建一个VideoStream对象,并启动它。0表示使用默认的摄像头。  
time.sleep(2.0)                                          # 等待2秒,确保摄像头已经预热完成。colorLower = (9,135,231)                         # 定义HSV颜色空间的下限,用于颜色过滤。
colorUpper = (31,255,255)                       # 定义HSV颜色空间的上限,用于颜色过滤。GPIO.output(Led, GPIO.LOW)                # 将Led引脚设置为低电平,关闭LED。 
ledOn = False                                           # 定义一个变量ledOn,表示LED是否已打开。while True:frame = vs.read()                                                        # 从VideoStream中读取一帧图像。  frame = imutils.resize(frame, width=500)               # 调整帧的大小,使其宽度为500像素。frame = imutils.rotate(frame, angle=0)                   # 旋转帧(虽然在这里旋转角度为0,所以实际上没有旋转)。hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)  # 将帧从BGR颜色空间转换为HSV颜色空间。mask = cv2.inRange(hsv, colorLower, colorUpper)# 使用定义的颜色范围创建一个颜色掩码。mask = cv2.erode(mask, None, iterations=2)         # 对掩码进行腐蚀操作,减少噪声。mask = cv2.dilate(mask, None, iterations=2)         # 对掩码进行膨胀操作,确保对象区域被完全覆盖# 在掩码上查找轮廓。 cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)cnts = cnts[0] if imutils.is_cv2() else cnts[1]            # 根据OpenCV的版本(2或3/4),选择正确的轮廓列表。 center = None                                                            # 初始化一个变量center,用于存储对象的中心坐标。 if len(cnts) > 0:       # 如果找到了轮廓...  c = max(cnts, key=cv2.contourArea)               # 找到面积最大的轮廓。((x, y), radius) = cv2.minEnclosingCircle(c)     # 找到该轮廓的最小外接圆,并获取其圆心和半径。M = cv2.moments(c)                                         # 计算轮廓c的矩,矩是一组值,可以从中推导出对象的形状特征,如面积、质心等。 center = (int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"])) # 使用矩来计算轮廓的质心(或称为中心),并将其存储在变量center中。 if radius > 10:  # 如果找到的最小外接圆的半径大于10(一个阈值,可以根据实际情况调整):cv2.circle(frame, (int(x), int(y)), int(radius),(0, 255, 255), 2)  # 在原帧上绘制找到的最小外接圆,颜色为青色(BGR中的(0, 255, 255)),线宽为2。cv2.circle(frame, center, 5, (0, 0, 255), -1)  # 在原帧上绘制轮廓的质心(或中心),颜色为红色(BGR中的(0, 0, 255)),并填充。mapObjectPosition(int(x), int(y))             # 调用之前定义的函数,打印对象中心的坐标。  if not ledOn:                                              # 如果LED灯之前没打开(ledOn为False),则将其打开,并将ledOn设置为True。GPIO.output(Led, GPIO.HIGH)ledOn = Trueelif ledOn:         # 如果没有找到轮廓,但LED灯是打开的(ledOn为True):关闭LED灯,并将ledOn设置为False。GPIO.output(Led, GPIO.LOW)ledOn = Falsecv2.imshow("Frame", frame) # 使用OpenCV的imshow函数显示处理后的帧。key = cv2.waitKey(1) & 0xFF   # 如果按下的键是Esc键(ASCII码为27),则退出循环。  if key == 27:breakprint("\n [INFO] Exiting Program and cleanup stuff \n")  # 打印一条信息,表示程序正在退出并进行清理。  
GPIO.cleanup()                                                                       # 清理GPIO设置,释放资源。
cv2.destroyAllWindows()                                                      # 关闭所有OpenCV打开的窗口。
vs.stop()                                                                                  # 停止VideoStream的捕获。

实验过程:

代码中所用的大部分函数已经在之前的几篇文章提到过了,就不重复解释了:

文章网址如下:

树莓派4B_OpenCv学习笔记9:图片的腐蚀与膨胀-CSDN博客

树莓派4B_OpenCv学习笔记12:OpenCv颜色追踪_画出轨迹_树莓派opencv颜色识别-CSDN博客树莓派4B_OpenCv学习笔记13:OpenCv颜色追踪_程序手动调试HSV色彩空间_检测圆-CSDN博客

获取小球的准确HSV色域:

因为程序中已经存在了寻找最大轮廓圆的处理,因此即使不使用上一节文章的手动调节HSV的处理也没什么大问题,但我这里为了检测更为准确专用,还是加上了上一节代码的HSV微调操作:

文章网址如下:

树莓派4B_OpenCv学习笔记13:OpenCv颜色追踪_程序手动调试HSV色彩空间_检测圆-CSDN博客

拍摄照片获取BGR颜色空间:160    75    13

转换为大致的HSV色彩空间:

再使用之前的颜色小球追踪程序对HSV进行进一步细节调整:

调整前:

[97,100,100]

[117,255,255]

调整后:

[92,189,130]

[117,244,200]

将上一步得到的HSV色域替换在程序中:

实验结果截图与视频:

树莓派4B_OpenCv学习笔记15:OpenCv定位物体

网上查阅资料贴出:

[树莓派基础]11.树莓派OpenCV定位物体的实时位置_哔哩哔哩_bilibili

http://www.lryc.cn/news/386615.html

相关文章:

  • MySQL之如何定位慢查询
  • Open3D 删除点云中重复的点
  • 填报志愿选专业是兴趣重要还是前景重要?
  • python开发基础——day9 函数基础与函数参数
  • STM32——使用TIM输出比较产生PWM波形控制舵机转角
  • 第十五章 集合(set)(Python)
  • 面试-javaIO机制
  • 在.NET Core中,config和ConfigureServices的区别和作用
  • App Inventor 2 如何实现多个定时功能?
  • 技术驱动的音乐变革:AI带来的产业重塑
  • 重生之我要学后端0--HTTP协议和RESTful APIs
  • 深度之眼(二十八)——神经网络基础知识(三)-卷积神经网络
  • AI Infra简单记录
  • 三英战吕布 | 第5集 | 温酒斩华雄 | 竖子不足与谋 | 三国演义 | 逐鹿群雄
  • 【C语言】自定义类型:结构体
  • 算法金 | 决策树、随机森林、bagging、boosting、Adaboost、GBDT、XGBoost 算法大全
  • [每周一更]-(第103期):GIT初始化子模块
  • 单例模式---线程安全实现
  • Agent技术在现代软件开发与应用中的探索
  • c语言中extern定义和引用其他文件的变量,(sublime text)单独一个文件编译不会成功
  • 时序数据中的孤立野点、异常值识别及处理方法
  • JetBrains PyCharm 2024 mac/win版编程艺术,智慧新篇
  • MCU解决800V电动汽车牵引逆变器的常见设计挑战的3种方式
  • 《逆向投资 邓普顿的长赢投资法》
  • C++中main函数的参数、返回值分别什么意思?main函数返回值跟普通函数返回值一样吗?
  • Java程序员学习Go开发Higress的WASM插件
  • Python入门-基本数据类型-数字类型
  • 小程序web-view无法打开该页面的解决方法
  • 海外媒体发稿:媒体宣发套餐的作用分享-华媒舍
  • 【R语言】plot输出窗口大小的控制