Search code examples
screenshotvideo-processingmotion-detectionvideo-codecs

Motion detection on screenshots


I'd like to know if there is a fast algorithm that can detect parts that moved between two sequential screenshots. The algorithm should take two images and output a set of (rectangular) regions in one image and a vector that describes where the matching region is located in the other image.

I'd like to use that for a losless video compression algorithm that is streamlined for screen capturing. I think this makes the use case a little bit different from the usual applications of motion detection:

  • The images are screenshots. It's unlikely that there are any artifacts or image noise
  • If a part of the image moves, it moves pixel-wise. Moved parts usually differ in less than 2% of their pixels
  • Regions that move are often big and have a rectangular shape

Since the video compression pipeline also has other steps and should happen in real-time, the motion detection should be fast.

Is there anything helpful?


Solution

  • What I did

    I implemented a simple technique that compensates for most movements and is simple to implement.

    Each frame is divided into tiles of a constant size, say, 8×8 pixels. The codec manages a ringbuffer of a customizable number of tiles, for instance 220. Now, for each tile the codec encounters in the input stream, it checks whether it is already to be found in the ringbuffer. If it is, it just saves the tiles index, if not it stores the tile in the ringbuffer.

    Whenever a part of the image is moved by a multiple of the blocksize from any image in the past, it is very likely that one finds the tiles in the cache. This way, one can compensate most motion. Since finding a tile in the ringbuffer is very fast, this is fast enough to run in real time.