Search code examples
opencvemgucv

Order Motion components by velocity (Motion detection using Emgu)


I am trying to create an ordered list of Motion Components , ordered by motion. For example in a street view camera I would like the vehicles first, followed by bicycles, followed by pedestrians. Is this possible using MotionDetector sample in Emgu?

    if (motionPixelCount < comp.area * 0.05) continue;

This seems to be some kind of thresholding, but what does motionPixelCount really mean? Could this be a proxy for the speed/velocity of the motion component? or something else entirely? It is being compared to the component area.

tl;dr: how do I determine the velocity/speed of the motion components relative to the rest of the objects?


Solution

  • Well the summary of the function that produces motionPixelCount is as follows:

        public void MotionInfo(Rectangle motionRectangle, out double angle, out double motionPixelCount);
        //
        // Summary:
        //     Given a rectagle area of the motion, output the angle of the motion and the
        //     number of pixels that are considered to be motion pixel
        //
        // Parameters:
        //   motionRectangle:
        //     The rectangle area of the motion
        //
        //   angle:
        //     The orientation of the motion
        //
        //   motionPixelCount:
        //     Number of motion pixels within silhoute ROI
    

    It is thresholding by inspecting the amount of pixels within the set of ROI of motionRectangle that have moved. This prevents billions of results where 1 or two pixels appear to have moved. However by setting a more accurate ROI to where the vehicle is you could remove this threshold as you know there is unlikely to be random small movements that you don't care about.

    We could use this data to calculate the speed and velocity of the inspected component however we need some specific data. We need to know the pixel to real world measurement for the object at the particular distance. I discussed in detail this particular problem in the answer to this question. It's easy if we know the size of the object being tracked and the distance is from the camera however this is not usually the case.

    If we have an object at a fixed distance then we can roughly take the area of the object in real world terms and divide it by the area of pixels the object takes. This is easier than performing FOV calculations as it doesn't require an accurate distance measurement but the more accurate the area of the object can be calculated the more accurate the tracking results will be. If we get this pixel_per_mm measurement then:

    This function gives you the overall motion distance:

    double overallAngle, overallMotionPixelCount;
    _motionHistory.MotionInfo(motionMask.ROI, out overallAngle, out overallMotionPixelCount);
    

    Therefore:

    Speed = (overallMotionPixelCount*mm_per_pixel_mesurment) / Time_Between_Frames

    If my Physics is still up to scratch velocity isn't the same as speed and would require you to track the object over time, I figure you're just after speed but roughly:

    Velocity = (overall_distance_movedmm_per_pixel_mesurment) / (Sum_of_frames_TrackedFrame_Rate)

    or:

    Velocity = (overall_distance_moved*mm_per_pixel_mesurment) / (Time_object_was_tracked_for)

    In conclusion this can be done however it is hard and is why different technology such as Sonar or Infra-red is used to track speed accurately.

    An interesting example at least in the UK is the use of painted lines and speed cameras. The distance between these lines has to be within 5mm of a specific measurement the speed of the vehicle is then calculated (via two pictures of the same car) by how far it's moved according to these references. This is a cheat way of providing depth data of an image. These are being replaced for sonar types as if these lines are not within a 5mm distance of a set amount the speed can not be accurately be measured and can not stand up in court.

    Ok I wondered off a bit there but unless your tracking an object at a know distance and a known size you can't get the speed or velocity without some for of Depth data either from a specific camera such as a kinetic or from two cameras set a know distance apart. (Note this can be done with one camera and two frames if you know the distance travelled by the camera and there's no rotation).

    I hope this helps you,

    Cheers,

    Chris