opencv python中的运动跟踪
Posted
技术标签:
【中文标题】opencv python中的运动跟踪【英文标题】:Motion Tracking in opencv python 【发布时间】:2018-06-13 18:52:11 【问题描述】:所以我一直在尝试制作一个运动跟踪器来跟踪在视频中移动的狗(自上而下录制)检索显示狗的裁剪视频并忽略背景的其余部分。
我首先尝试使用来自this link 的 opencv 3 中的可用算法(BOOSTING、MIL、KCF、TLD、MEDIANFLOW、GOTURN(返回错误,无法解决))进行对象跟踪,我什至尝试了通过减去第一帧来进行运动跟踪的基本算法,但它们都没有给出好的结果。 Link
我更喜欢带有预设矩形框的代码,一旦检测到运动区域,该矩形框就会包围它。类似video
我对 OPENCV 不是很熟悉,但我相信单次运动跟踪不应该成为问题,因为已经完成了很多工作。我应该考虑其他库/API,还是可以遵循更好的代码/教程来完成这项工作?我的意思是稍后将它与神经网络一起使用(这就是我尝试使用 python/opencv 解决它的原因)
感谢任何帮助/建议
编辑:
我删除了以前的代码以使帖子更干净。
此外,根据我得到的反馈和进一步的研究,我能够修改一些代码以使其接近我想要的结果。但是,我仍然有一个令人讨厌的跟踪问题。第一帧似乎影响了其余的跟踪,因为即使在狗移动之后,它也会继续检测它的第一个位置。我尝试使用标志将跟踪限制为仅 1 个动作,但检测变得混乱。这是显示结果的代码和图片:
jimport imutils
import time
import cv2
previousFrame = None
def searchForMovement(cnts, frame, min_area):
text = "Undetected"
flag = 0
for c in cnts:
# if the contour is too small, ignore it
if cv2.contourArea(c) < min_area:
continue
#Use the flag to prevent the detection of other motions in the video
if flag == 0:
(x, y, w, h) = cv2.boundingRect(c)
#print("x y w h")
#print(x,y,w,h)
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
text = "Detected"
flag = 1
return frame, text
def trackMotion(ret,frame, gaussian_kernel, sensitivity_value, min_area):
if ret:
# Convert to grayscale and blur it for better frame difference
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (gaussian_kernel, gaussian_kernel), 0)
global previousFrame
if previousFrame is None:
previousFrame = gray
return frame, "Uninitialized", frame, frame
frameDiff = cv2.absdiff(previousFrame, gray)
thresh = cv2.threshold(frameDiff, sensitivity_value, 255, cv2.THRESH_BINARY)[1]
thresh = cv2.dilate(thresh, None, iterations=2)
_, cnts, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
frame, text = searchForMovement(cnts, frame, min_area)
#previousFrame = gray
return frame, text, thresh, frameDiff
if __name__ == '__main__':
video = "Track.avi"
video0 = "Track.mp4"
video1= "Ntest1.avi"
video2= "Ntest2.avi"
camera = cv2.VideoCapture(video1)
time.sleep(0.25)
min_area = 5000 #int(sys.argv[1])
cv2.namedWindow("Security Camera Feed")
while camera.isOpened():
gaussian_kernel = 27
sensitivity_value = 5
min_area = 2500
ret, frame = camera.read()
#Check if the next camera read is not null
if ret:
frame, text, thresh, frameDiff = trackMotion(ret,frame, gaussian_kernel, sensitivity_value, min_area)
else:
print("Video Finished")
break
cv2.namedWindow('Thresh',cv2.WINDOW_NORMAL)
cv2.namedWindow('Frame Difference',cv2.WINDOW_NORMAL)
cv2.namedWindow('Security Camera Feed',cv2.WINDOW_NORMAL)
cv2.resizeWindow('Thresh', 800,600)
cv2.resizeWindow('Frame Difference', 800,600)
cv2.resizeWindow('Security Camera Feed', 800,600)
# uncomment to see the tresh and framedifference displays
cv2.imshow("Thresh", thresh)
cv2.imshow("Frame Difference", frameDiff)
cv2.putText(frame, text, (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
cv2.imshow("Security Camera Feed", frame)
key = cv2.waitKey(3) & 0xFF
if key == 27 or key == ord('q'):
print("Bye")
break
camera.release()
cv2.destroyAllWindows()
这张图显示了第一帧仍然如何影响帧差结果,这会迫使盒子覆盖没有运动的区域。
此示例显示了一种情况,即忽略运动而错误地检测到不再存在的运动(与视频的第二帧和第一帧的帧差)。当我允许多次跟踪时,它同时跟踪两者,这仍然是错误的,因为它检测到一个空白区域。
有没有人知道代码错误或缺失的地方?我一直在尝试,但无法使其正常工作。
提前谢谢你!!
【问题讨论】:
不要只放链接,你试过的代码在哪里? @Silencer 我在编辑中添加了它。感谢您的评论 我认为你应该先正确识别问题,然后尝试解决方案。您想先检测运动……也许还想跟踪这个物体?或者也许只检测每一步的运动?您提到的第一个算法仅用于跟踪,而不是用于检测,这就是您需要 ROI 的原因(这是您要跟踪的“对象”)。此外,如果您移动超过 1 个物体会怎样?我建议首先尝试正确检测运动,您可以尝试类似this @api55 感谢您的评论。我正在尝试遵循您的建议,一旦我得到一些结果,我将编辑并提及它。关于您的问题,正如您所说,检测运动并跟踪该对象。在我的场景中,房间里有一只狗,我想跟踪它(使用边界框)。所以基本上,狗移动 -> 检测到运动 -> 创建一个边界框并继续跟踪它(忽略视频中的任何其他运动)。 @Lewis 我用这种方法并没有真正得到令人满意的结果,如果你的背景不是静态的,它会更加复杂。我最终使用 YOLO 进行对象检测来执行跟踪。 【参考方案1】:为了包含运动检测,我在 NPM Registry 和 docker hub 上创建了通用组件 这会检测客户端网络摄像头(React 应用程序)上的运动,并基于 Open CV 使用 Python 中的服务器 所以客户端只是捕获网络摄像头图像,服务器使用 OPENCV 分析这些图像以确定是否有运动 客户端可以指定每次有动作时服务器调用的回调函数 服务器只是一个 docker 镜像,你可以拉取并运行它并指定它的 URL 给客户端
NPM 注册表(客户端)
注册链接:
https://www.npmjs.com/settings/kunalpimparkhede/packages
命令
npm install motion-detector-client
Docker 映像(服务器)
链接
https://hub.docker.com/r/kunalpimparkhede/motiondetectorwebcam
命令
docker pull kunalpimparkhede/motiondetectorwebcam
您只需要编写以下代码即可进行运动检测
用法:
import MotionDetectingClient from './MotionDetectingClient';
<MotionDetectingClient server="http://0.0.0.0:8080" callback=handleMovement/>
function handleMovement(pixels)
console.log("Movement By Pixel="+pixels)
在服务器端:只需在端口 8080 上启动 docker 服务器:
docker run --name motion-detector-server-app -P 8080:5000 motion-detector-server-app
【讨论】:
以上是关于opencv python中的运动跟踪的主要内容,如果未能解决你的问题,请参考以下文章