首页 > 解决方案 > Python/OpenCV - 如何保持对象在视频中移动的标签以及如何获取它们之间的距离

问题描述

大家好,我正在做一个 arduino 机器人手臂的大学项目,它使用带有 python/opencv 的网络摄像头捕捉某种颜色的物体。

我的代码的步骤基本上是这些:

  1. 捕获帧;
  2. 将帧 BGR 转换为 HSV;
  3. 阈值 HSV 仅获得我想要的颜色;
  4. 将腐蚀和膨胀应用于脱粒
  5. 使用 cv2.findContours 在 thresh 上查找轮廓
  6. 在 for 循环中获取使用矩检测到的每个轮廓的质心
  7. 绘制轮廓,质心上的一个点(小圆圈),质心坐标(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

对象 0、1、2、3

对象 1 在 for 的 i 上的 Y 变化位置上升时,变为 i = 3

谢谢!

标签: pythonopencv

解决方案


推荐阅读