python - Python/OpenCV - 如何保持对象在视频中移动的标签以及如何获取它们之间的距离
问题描述
大家好,我正在做一个 arduino 机器人手臂的大学项目,它使用带有 python/opencv 的网络摄像头捕捉某种颜色的物体。
我的代码的步骤基本上是这些:
- 捕获帧;
- 将帧 BGR 转换为 HSV;
- 阈值 HSV 仅获得我想要的颜色;
- 将腐蚀和膨胀应用于脱粒
- 使用 cv2.findContours 在 thresh 上查找轮廓
- 在 for 循环中获取使用矩检测到的每个轮廓的质心
- 绘制轮廓,质心上的一个点(小圆圈),质心坐标(cx|cy),并在框架上写下对象标签(循环上i的位置)
直到这里一切都很顺利,但是我遇到了一个问题,当我切换对象的位置(尤其是 y 轴)时,它们会在循环中切换 i 位置,我想要的是算法知道“那个对象是nº 1 即使他高于或低于对象 nº2 和 nº3"。我还想知道是否有办法在对象 0(将是机器人手臂)和所有其他对象的位置之间画一条线,这样我就可以得到对象的位置并且我可以移动机器人抓住他们。
你们知道我是怎么做到的吗?对不起,如果有任何英语错误,我还在学习英语。
这里是我到目前为止所做的代码以及正在运行的代码的打印。
# Importing libraries
import cv2
import numpy as np
# Creating callback function and Trackbars
def callback(x):
pass
cv2.namedWindow('Trackbars', cv2.WINDOW_FREERATIO)
cv2.createTrackbar('LH', 'Trackbars', 0, 255, callback)
cv2.createTrackbar('LS', 'Trackbars', 0, 255, callback)
cv2.createTrackbar('LV', 'Trackbars', 0, 255, callback)
cv2.createTrackbar('UH', 'Trackbars', 255, 255, callback)
cv2.createTrackbar('US', 'Trackbars', 255, 255, callback)
cv2.createTrackbar('UV', 'Trackbars', 255, 255, callback)
# Define a capture object and resizes to 640x360
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 360)
while True:
# Capturing the frame
_, frame = cap.read()
# Converting to HSV
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# Getting Trackbars value
l_h = cv2.getTrackbarPos('LH', 'Trackbars')
l_s = cv2.getTrackbarPos('LS', 'Trackbars')
l_v = cv2.getTrackbarPos('LV', 'Trackbars')
u_h = cv2.getTrackbarPos('UH', 'Trackbars')
u_s = cv2.getTrackbarPos('US', 'Trackbars')
u_v = cv2.getTrackbarPos('UV', 'Trackbars')
# Creating Lower and Upper arrays with the data of trackbars
l_c = np.array([l_h, l_s, l_v])
u_c = np.array([u_h, u_s, u_v])
# Creating thresh
thresh = cv2.inRange(hsv, l_c, u_c)
# Applying Morphological transformations: Erosion and dilation on the thresh
erode = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
dilate = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
thresh = cv2.erode(thresh,erode,iterations = 2)
thresh = cv2.dilate(thresh,dilate,iterations = 2)
# Finding and drawing contours, centroid and centroid positions
try:
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for i, c in enumerate(contours):
M = cv2.moments(c)
cx = int(M["m10"] / M["m00"])
cy = int(M["m01"] / M["m00"])
cv2.drawContours(frame, contours, -1, (0, 255, 0), 2)
cv2.putText(frame, "OBJECT "+(str(i)), (cx-35,cy-30),1,1,(0,0,255),1)
cv2.circle(frame,(cx,cy),1,(0,0,255),2)
cv2.putText(frame, str(cx)+","+ str(cy), (cx-35,cy+30),1,1,(0,0,255),1)
except:
pass
# Showing frame and thresh
cv2.imshow('frame',frame)
cv2.imshow('thresh',thresh)
# 'Esc' key break the loop and destroy all windows
key = cv2.waitKey(1)
if key == 27:
cv2.destroyAllWindows()
break
对象 1 在 for 的 i 上的 Y 变化位置上升时,变为 i = 3
谢谢!
解决方案
推荐阅读
- hadoop - cp 命令在 Hadoop 中如何工作?
- javascript - 如何将大数据从原生 Java 发送到 JavaScript?
- postgresql - Postgres 索引需要重新索引
- matlab - matlab从测量信号中去卷积一个方波
- c++ - 我们如何跳过帧,计算帧数并使用视频阅读器获取当前帧
- ios - 动画 Xamarin.Forms ViewCell 会导致 iOS 上的缩放问题和性能下降
- bash - 在bash中附加两个变量的字符
- c++ - CMake 在 Windows 上找不到 g++ 编译器
- javascript - 图像网格轮播无法正常工作
- c# - 使用实体框架将列表对象分成两个对象