简体   繁体   English

opencv python中的运动跟踪

[英]Motion Tracking in opencv python

So I have been trying to make a motion tracker to track a dog moving in a video (recorded Top-down) retrieve a cropped video showing the dog and ignore the rest of the background.所以我一直在尝试制作一个运动跟踪器来跟踪视频中移动的狗(自上而下录制)检索显示狗的裁剪视频并忽略背景的其余部分。

I tried first with object tracking using the available algorithms in opencv 3 (BOOSTING, MIL, KCF, TLD, MEDIANFLOW, GOTURN(returns an error, couldn't solve it yet)) from this link and I even tried a basic algorithm for motion tracking by subtracting the first frame, but none of them gives a good result.我首先试图与对象跟踪使用可用算法中的OpenCV 3从(BOOSTING,MIL,KCF,TLD MEDIANFLOW,GOTURN(返回一个错误,没能解决它尚未)) 这个链接和我甚至试图对运动的基本算法通过减去第一帧进行跟踪,但没有一个给出好的结果。 Link 链接

I would prefer a code with a preset rectangle box that surrounds the area of motion once it is detected.我更喜欢带有预设矩形框的代码,一旦检测到该矩形框,它就会围绕运动区域。 Something like in this video像这个视频中的东西

I'm not very familiar with OPENCV, but I believe single motion tracking is not supposed to be an issue since a lot of work has been done already.我对 OPENCV 不是很熟悉,但我相信单运动跟踪不应该是一个问题,因为已经做了很多工作。 Should I consider other libraries/APIs or is there a better code/tutorial I can follow to get this done?我应该考虑其他库/API 还是可以遵循更好的代码/教程来完成这项工作? my point is to use this later with neural network (which is why I'm trying to solve it using python/opencv)我的观点是稍后将其与神经网络一起使用(这就是我尝试使用 python/opencv 解决它的原因)

Thanks for any help/advice感谢您的任何帮助/建议

Edit:编辑:

I removed the previous code to make the post cleaner.我删除了以前的代码以使帖子更干净。

Also, based on the feedback I got and further research, I was able to modify some code to make it close to my wanted result.此外,根据我得到的反馈和进一步的研究,我能够修改一些代码以使其接近我想要的结果。 However, I still have an annoying problem with the tracking.但是,我仍然有一个恼人的跟踪问题。 It seems like the first frame affects the rest of the tracking since even after the dog moves, it keeps detecting its first location.似乎第一帧会影响其余的跟踪,因为即使在狗移动之后,它也会继续检测它的第一个位置。 I tried to limit the tracking to only 1 action using a flag, but the detection gets messed up.我试图使用标志将跟踪限制为仅 1 个操作,但检测变得一团糟。 This is the code and pictures showing results:这是显示结果的代码和图片:

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()

This picture shows how the very first frame is still affecting the frame difference results, which forces the box to cover area with no motion.这张图片显示了第一帧如何仍然影响帧差异结果,这迫使框在没有运动的情况下覆盖区域。

结果显示帧差和视频显示

This one shows a case when motion is ignored an no-longer existing motion (frame difference from the second and first frames of the video) being falsely detected.这显示了当运动被忽略时错误检测到不再存在的运动(与视频的第二帧和第一帧的帧差异)的情况。 When I allow multiple tracking it tracks both, which is still wrong since it detects an empty area.当我允许多个跟踪时,它同时跟踪两个,这仍然是错误的,因为它检测到一个空白区域。

在此处输入图片说明

Does anyone have an idea where the code is wrong or lacking ?有没有人知道代码错误或缺少的地方? I keep trying but cannot get it to work properly.我一直在尝试,但无法使其正常工作。

Thank you in advance !!提前谢谢你!!

To include motion detection I have created generic components on NPM Registry and docker hub This detects the motion on client web cam( React app) and uses server in Python based on open CV so Client just captures web cam images and server analyses these images using OPENCV to determine if there is a motion or not client can specify a call back function which server calls each time there is a motion Server is just a docker image which you can pull and run and specify its URL to client为了包括运动检测,我在 NPM Registry 和 docker hub 上创建了通用组件这会检测客户端网络摄像头(React app)上的运动,并在基于开放 CV 的 Python 中使用服务器,因此客户端只捕获网络摄像头图像,服务器使用 OPENCV 分析这些图像确定是否有动作 客户端可以指定一个回调函数,每次有动作时服务器都会调用该函数 服务器只是一个 docker 映像,您可以将其拉取并运行并指定其 URL 到客户端

NPM Registry(Client) NPM 注册表(客户端)

Registry Link:注册表链接:

https://www.npmjs.com/settings/kunalpimparkhede/packages

Command命令

npm install motion-detector-client

Docker Image (Server) Docker 镜像(服务器)

Link链接

https://hub.docker.com/r/kunalpimparkhede/motiondetectorwebcam

Command命令

docker pull kunalpimparkhede/motiondetectorwebcam

You just need to write following code to have motion detection您只需要编写以下代码即可进行运动检测

Usage:用法:

import MotionDetectingClient from './MotionDetectingClient';

<MotionDetectingClient server="http://0.0.0.0:8080" callback={handleMovement}/>

function handleMovement(pixels) 
{
console.log("Movement By Pixel="+pixels)
}

On server side : just start the docker server on port 8080:在服务器端:只需在端口 8080 上启动 docker 服务器:

docker run --name motion-detector-server-app -P 8080:5000 motion-detector-server-app

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM