Python 基于视频的目标位置检测
所以,我用openCV做了基于颜色的目标检测,我在raspberry pi 3上运行它。它正在工作,因为它实时跟踪网球(尽管它有一些延迟,因为我使用的是kinect v1(freenect库))。现在我想确定找到的对象所在的位置。我想知道它是在中间,还是左边还是右边。我想把相机的框架分成三部分。我会有3个布尔值,一个用于中间,一个用于左边,一个用于右边,然后所有3个变量都将通过usb通信发送。然而,我已经试了一个星期来确定这个物体在哪里,但是我不能这样做。我在这里请求帮助 使用openCV进行对象检测的当前工作代码(I通过颜色检测对象)Python 基于视频的目标位置检测,python,opencv,raspberry-pi,raspbian,object-detection,Python,Opencv,Raspberry Pi,Raspbian,Object Detection,所以,我用openCV做了基于颜色的目标检测,我在raspberry pi 3上运行它。它正在工作,因为它实时跟踪网球(尽管它有一些延迟,因为我使用的是kinect v1(freenect库))。现在我想确定找到的对象所在的位置。我想知道它是在中间,还是左边还是右边。我想把相机的框架分成三部分。我会有3个布尔值,一个用于中间,一个用于左边,一个用于右边,然后所有3个变量都将通过usb通信发送。然而,我已经试了一个星期来确定这个物体在哪里,但是我不能这样做。我在这里请求帮助 使用openCV进行对
#用法
#python ball_tracking.py--视频ball_tracking_example.mp4
#python ball_tracking.py
#导入必要的包
从集合导入deque
将numpy作为np导入
导入argparse
导入imutils
进口cv2
#构造参数并解析参数
ap=argparse.ArgumentParser()
添加参数(“-v”,“视频”,
help=“指向(可选)视频文件的路径”)
ap.add_参数(“-b”,“--buffer”,type=int,default=64,
help=“最大缓冲区大小”)
args=vars(ap.parse_args())
#定义“绿色”的上下边界
#球在HSV颜色空间中,然后初始化
#跟踪点列表
格林洛=(29,86,6)
绿色上限=(64255255)
pts=deque(maxlen=args[“缓冲区”])
#如果未提供视频路径,请获取参考
#到网络摄像机
如果不是args.get(“视频”,False):
摄像机=cv2。视频捕获(0)
#否则,获取对视频文件的引用
其他:
摄像头=cv2.视频捕获(args[“视频”])
#继续循环
尽管如此:
#抓取当前帧
(抓取,帧)=照相机。读取()
#如果我们正在观看视频,但没有抓取帧,
#现在我们已经到了视频的结尾
如果args.get(“视频”)未被抓取:
打破
#调整帧大小、模糊帧并将其转换为HSV
#色彩空间
frame=imutils.resize(frame,width=600)
#模糊=cv2.高斯模糊(帧,(11,11),0)
hsv=cv2.CVT颜色(帧,cv2.COLOR_BGR2HSV)
#为颜色“绿色”构建遮罩,然后执行
#一系列的扩张和侵蚀,以去除任何小的
#面具上留下的斑点
遮罩=cv2.inRange(hsv、绿下、绿上)
掩模=cv2。腐蚀(掩模,无,迭代次数=2)
掩码=cv2。放大(掩码,无,迭代次数=2)
#在遮罩中找到轮廓并初始化当前轮廓
#(x,y)球的中心
cnts=cv2.findContentours(mask.copy(),cv2.RETR_EXTERNAL,
cv2.链(近似简单)[-2]
中心=无
#仅当至少找到一个轮廓时才继续
如果len(cnts)>0:
#在遮罩中找到最大的轮廓,然后使用
#计算最小包围圈和
#质心
c=最大值(CNT,键=cv2.轮廓面积)
((x,y),半径)=cv2.闭合圆(c)
M=cv2.力矩(c)
中心=(整数(M[“m10”]/M[“m00”]),整数(M[“m01”]/M[“m00”]))
#仅当半径满足最小尺寸时才能继续
如果半径>10:
#在框架上绘制圆和质心,
#然后更新跟踪点列表
cv2.圆(帧,(int(x),int(y)),int(半径),
(0, 255, 255), 2)
cv2.圆(框架,中心,5,(0,0,255),-1)
#编辑:
如果int(x)>int(200)&int(x)int(1)&int(x)int(400)&int(x)
代码已正确注释。使用usb端口发送信息不是问题,我只是不知道如何检测球在哪里
我在用我的树莓皮做树莓皮
编辑:
我忘了提一下,我只对物体根据X轴的位置感兴趣。我想,当我将当前帧设置为600时,我会编写3个if,比如if x>200&&x<400:bool middle=true
。这不管用
编辑2:
我想我总算成功了,但“中间”永远不会是真的。对于左和右,我得到了正确的结果,但对于中间,我没有得到正确的结果。如果要检测其位置的对象,那么使用cv2.findContours()比使用cv2.houghcirles()要好。因为cv2.HoughCircles()直接返回圆的中心位置(x,y) 您可以找到使用HoughCircles()的示例 如果你得到了圆的中心,那么确定它的位置就很容易了 祝你好运。
如果int(x)>int(200)和int(x) if int(x) > int(200) AND int(x) < int(400):
middle = True
left = False
notleft = False
if int(x) > int(1) AND int(x) < int(200):
left = True
middle = False
notleft = False
if int(x) > int(400) AND int(x) < int(600):
notleft = True
left = False
middle = False
中间=正确
左=假
notleft=False
如果int(x)>int(1)和int(x) if int(x) > int(200) AND int(x) < int(400):
middle = True
left = False
notleft = False
if int(x) > int(1) AND int(x) < int(200):
left = True
middle = False
notleft = False
if int(x) > int(400) AND int(x) < int(600):
notleft = True
left = False
middle = False
# import the necessary packages
from collections import deque
import numpy as np
import argparse
import imutils
import cv2
# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-v", "--video",
help="path to the (optional) video file")
ap.add_argument("-b", "--buffer", type=int, default=32,
help="max buffer size")
args = vars(ap.parse_args())
# define the lower and upper boundaries of the "green"
# ball in the HSV color space
greenLower = (29, 86, 6)
greenUpper = (64, 255, 255)
# initialize the list of tracked points, the frame counter,
# and the coordinate deltas
pts = deque(maxlen=args["buffer"])
counter = 0
(dX, dY) = (0, 0)
direction = ""
# if a video path was not supplied, grab the reference
# to the webcam
if not args.get("video", False):
camera = cv2.VideoCapture(0)
# otherwise, grab a reference to the video file
else:
camera = cv2.VideoCapture(args["video"])
# keep looping
while True:
# grab the current frame
(grabbed, frame) = camera.read()
# if we are viewing a video and we did not grab a frame,
# then we have reached the end of the video
if args.get("video") and not grabbed:
break
# resize the frame, blur it, and convert it to the HSV
# color space
frame = imutils.resize(frame, width=600)
# blurred = cv2.GaussianBlur(frame, (11, 11), 0)
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# construct a mask for the color "green", then perform
# a series of dilations and erosions to remove any small
# blobs left in the mask
mask = cv2.inRange(hsv, greenLower, greenUpper)
mask = cv2.erode(mask, None, iterations=2)
mask = cv2.dilate(mask, None, iterations=2)
# find contours in the mask and initialize the current
# (x, y) center of the ball
cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)[-2]
center = None
# only proceed if at least one contour was found
if len(cnts) > 0:
# find the largest contour in the mask, then use
# it to compute the minimum enclosing circle and
# centroid
c = max(cnts, key=cv2.contourArea)
((x, y), radius) = cv2.minEnclosingCircle(c)
M = cv2.moments(c)
center = (int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"]))
# only proceed if the radius meets a minimum size
if radius > 10:
# draw the circle and centroid on the frame,
# then update the list of tracked points
cv2.circle(frame, (int(x), int(y)), int(radius),
(0, 255, 255), 2)
cv2.circle(frame, center, 5, (0, 0, 255), -1)
pts.appendleft(center)
# loop over the set of tracked points
for i in np.arange(1, len(pts)):
# if either of the tracked points are None, ignore
# them
if pts[i - 1] is None or pts[i] is None:
continue
# check to see if enough points have been accumulated in
# the buffer
if counter >= 10 and i == 1 and pts[-10] is not None:
# compute the difference between the x and y
# coordinates and re-initialize the direction
# text variables
dX = pts[-10][0] - pts[i][0]
dY = pts[-10][1] - pts[i][1]
(dirX, dirY) = ("", "")
# ensure there is significant movement in the
# x-direction
if np.abs(dX) > 20:
dirX = "East" if np.sign(dX) == 1 else "West"
# ensure there is significant movement in the
# y-direction
if np.abs(dY) > 20:
dirY = "North" if np.sign(dY) == 1 else "South"
# handle when both directions are non-empty
if dirX != "" and dirY != "":
direction = "{}-{}".format(dirY, dirX)
# otherwise, only one direction is non-empty
else:
direction = dirX if dirX != "" else dirY
# otherwise, compute the thickness of the line and
# draw the connecting lines
thickness = int(np.sqrt(args["buffer"] / float(i + 1)) * 2.5)
cv2.line(frame, pts[i - 1], pts[i], (0, 0, 255), thickness)
# show the movement deltas and the direction of movement on
# the frame
cv2.putText(frame, direction, (10, 30), cv2.FONT_HERSHEY_SIMPLEX,
0.65, (0, 0, 255), 3)
cv2.putText(frame, "dx: {}, dy: {}".format(dX, dY),
(10, frame.shape[0] - 10), cv2.FONT_HERSHEY_SIMPLEX,
0.35, (0, 0, 255), 1)
# show the frame to our screen and increment the frame counter
cv2.imshow("Frame", frame)
key = cv2.waitKey(1) & 0xFF
counter += 1
# if the 'q' key is pressed, stop the loop
if key == ord("q"):
break
# cleanup the camera and close any open windows
camera.release()
cv2.destroyAllWindows()