【问题标题】:Python OpenCV: Detecting a general direction of movement?Python OpenCV:检测一般的运动方向?
【发布时间】:2011-05-28 14:52:09
【问题描述】:

我仍在编写一个图书扫描脚本,现在,我所需要的只是能够自动检测翻页。这本书占据了 90% 的屏幕(我正在使用一个粗糙的网络摄像头进行运动检测),所以当我翻页时,运动方向基本上是同一个方向。

我已经修改了一个运动跟踪脚本,但衍生产品无济于事:

#!/usr/bin/env python

import cv, numpy

class Target:
    def __init__(self):
        self.capture = cv.CaptureFromCAM(0)
        cv.NamedWindow("Target", 1)

    def run(self):
        # Capture first frame to get size
        frame = cv.QueryFrame(self.capture)
        frame_size = cv.GetSize(frame)
        grey_image = cv.CreateImage(cv.GetSize(frame), cv.IPL_DEPTH_8U, 1)
        moving_average = cv.CreateImage(cv.GetSize(frame), cv.IPL_DEPTH_32F, 3)
        difference = None
        movement = []

        while True:
            # Capture frame from webcam
            color_image = cv.QueryFrame(self.capture)

            # Smooth to get rid of false positives
            cv.Smooth(color_image, color_image, cv.CV_GAUSSIAN, 3, 0)

            if not difference:
                # Initialize
                difference = cv.CloneImage(color_image)
                temp = cv.CloneImage(color_image)
                cv.ConvertScale(color_image, moving_average, 1.0, 0.0)
            else:
                cv.RunningAvg(color_image, moving_average, 0.020, None)

            # Convert the scale of the moving average.
            cv.ConvertScale(moving_average, temp, 1.0, 0.0)

            # Minus the current frame from the moving average.
            cv.AbsDiff(color_image, temp, difference)

            # Convert the image to grayscale.
            cv.CvtColor(difference, grey_image, cv.CV_RGB2GRAY)

            # Convert the image to black and white.
            cv.Threshold(grey_image, grey_image, 70, 255, cv.CV_THRESH_BINARY)

            # Dilate and erode to get object blobs
            cv.Dilate(grey_image, grey_image, None, 18)
            cv.Erode(grey_image, grey_image, None, 10)

            # Calculate movements
            storage = cv.CreateMemStorage(0)
            contour = cv.FindContours(grey_image, storage, cv.CV_RETR_CCOMP, cv.CV_CHAIN_APPROX_SIMPLE)
            points = []

            while contour:
                # Draw rectangles
                bound_rect = cv.BoundingRect(list(contour))
                contour = contour.h_next()

                pt1 = (bound_rect[0], bound_rect[1])
                pt2 = (bound_rect[0] + bound_rect[2], bound_rect[1] + bound_rect[3])
                points.append(pt1)
                points.append(pt2)
                cv.Rectangle(color_image, pt1, pt2, cv.CV_RGB(255,0,0), 1)

            num_points = len(points)

            if num_points:
                x = 0
                for point in points:
                    x += point[0]
                x /= num_points

                movement.append(x)

            if len(movement) > 0 and numpy.average(numpy.diff(movement[-30:-1])) > 0:
              print 'Left'
            else:
              print 'Right'

            # Display frame to user
            cv.ShowImage("Target", color_image)

            # Listen for ESC or ENTER key
            c = cv.WaitKey(7) % 0x100
            if c == 27 or c == 10:
                break

if __name__=="__main__":
    t = Target()
    t.run()

它检测所有框的平均中心的平均运动,这是非常低效的。我将如何快速准确地检测此类运动(即在阈值内)?

我正在使用 Python,我打算继续使用它,因为我的整个框架都是基于 Python 的。

感谢您的帮助,所以提前谢谢大家。干杯。

【问题讨论】:

  • 你真的需要运动追踪吗?为什么不只检测超过某个阈值的变化? (即类似于sum(abs(img2 - img1)) > threshold
  • 嗯,我会摆弄那个。但是我怎么知道页面是向前翻还是向后翻,或者更糟糕的是,翻到一半然后又翻了回来。我会玩图表,因为这就是我的工作方式。谢谢!
  • 啊,没错,我只是假设您需要知道页面已被翻过...如果您需要知道方向,我上面的评论显然不是一个好选择!跨度>
  • 你似乎知道你在说什么。你介意我问你是否知道如何使用cv.CalcOpticalFlowLK()?我让它正常工作,但它给了我完全无法使用的结果(这就像你提到的阈值方法的减慢版本)。

标签: python opencv motion-detection


【解决方案1】:

你为什么不使用 cv.GoodFeaturesToTrack ?它可能会解决脚本运行时...并缩短代码...

【讨论】:

    【解决方案2】:

    我之前没有在 Python 中使用过 OpenCV,只是在带有 openframeworks 的 C++ 中使用过。

    为此,我认为 OpticalFlow 的 velx,vely 属性会起作用。

    有关光流如何工作的更多信息,请查看this paper

    HTH

    【讨论】:

    • 噢噢噢!那看起来有光泽。我一定会检查一下,因为这似乎是我正在寻找的。​​span>
    • 我知道了,但我不知道发生了什么。我得到velx 的波动,但它是随机的正向或负向。你有什么我可以看的吗?这似乎是我可以使用的东西,但我就是不知道如何......
    • 有点晚了,但我从 OpenCV 的 Python 绑定中修改了一个演示包以满足我的需要。谢谢!
    • @Blender - 我正在尝试做你想做的事,你介意分享你的代码吗?或者,如果没有,您能否向我指出您使用的演示包的方向?你真的会让我开心:-)
    • @kramer65:不幸的是,我认为我没有保留代码。我刚刚修改了opt_flow.py 演示脚本并为x 和y 方向设置了阈值。它没有像我希望的那样工作。
    猜你喜欢
    • 2012-11-11
    • 2017-03-23
    • 2012-11-15
    • 1970-01-01
    • 1970-01-01
    • 2013-11-23
    • 2022-11-04
    • 2011-10-24
    • 1970-01-01
    相关资源
    最近更新 更多