PDA

View Full Version : Comparing Frames ...how? (Motion Detecion)


Alen
13th April 2004, 11:47
Hello

I have following problem:
I have to compare frames, I think for this I should use the function 'compare', right?

I have to compare the frames from a Video stream. So managed to open a videofile (avi) and to save the frames as BMP images using the 'WriteFile' function. Now I look for a way to compare the frames and log the differences in a log file.

I have to do something like 'motion detection' on already existing video-file. I think its enough when I compare every second a frame x with the frame x-1 (the previous frame)and log the differences.

But can I do this?

1) Shall I frist save all frames as BMP pictures and then compare the frames, with the compare function (how?

2) Shall I compare the frames 'on-the-fly' while playing the videofile?

Does anybody have any advice?

Greets
Alen

esby
13th April 2004, 12:41
have a look there

http://forum.doom9.org/showthread.php?threadid=67239

esby

PS: avoid using a bmp step,
unless you want just to compare a few frames...

Alen
13th April 2004, 15:47
eerr, ufff this seems to be really complicated.

how can I do this stuff without the "bmp step" ?

Look at this code:


a="1.bmp"
b="2.bmp"
Compare(a,b,"","log.txt")



I just wanted to compare to bitmaps? But this doesn't work.
I think 'compare' expects clips as first and second argumen,but are BMP Files clips? I do not think so.
So who can I compare bitmaps??

And how to do the whole thing without the bmp step?

Greets
Alen

SoonUDie
13th April 2004, 17:04
If you really want to use compare(), you can do it "on the fly". Just use this:

ConvertToYuY2(last)
Compare(last, last.trim(1,0),"","log.txt")

This will run compare() on the current frame and the next frame (n and n+1). If your clip has a specific name (i.e. "video"), replace last with the name of your clip.

However, that won't really tell you anything about motion within the frame. If you're looking for a mask of the motion, search for MaskTools in this forum and download the latest version. The function you'd want to use is MotionMask().

If you just want to see all the differences between two frames, you could use
Subtract(last, last.trim(1,0)).levels(127,1,255,0,255)
If you want to see even more of what's going on, raise the gamma.

Alen
13th April 2004, 19:54
ConvertToYuY2(last)
Compare(last, last.trim(1,0),"","log.txt")


However, that won't really tell you anything about motion within the frame.




Ok, tried this, I got following ouput in my log file:
Comparing channel(s) YUV

Mean Max Max
Absolute Mean Pos. Neg.
Frame Dev. Dev. Dev. Dev. PSNR (dB)
-----------------------------------------------------
0 0.5493 -0.0257 22 -17 45.9309
1 0.0000 +0.0000 0 0 99.9947
2 0.4586 +0.0204 19 -12 46.9108
3 0.3976 -0.0119 20 -23 47.5409
4 0.6690 +0.0101 19 -22 45.6350
5 0.3128 -0.0137 14 -13 49.1569
6 0.2869 +0.0125 15 -15 49.0463
7 0.3065 -0.0074 20 -22 48.7449
8 0.0000 +0.0000 0 0 99.9947
9 0.2980 +0.0136 10 -11 49.0838
10 0.5496 -0.0121 12 -20 46.5653
11 0.4885 +0.0129 17 -16 47.2792
12 0.2425 -0.0120 17 -16 50.3706
13 0.4603 +0.0134 16 -13 47.6432
14 0.4121 -0.0117 12 -12 48.3780
15 0.0000 +0.0000 0 0 99.9947
16 0.2130 +0.0073 10 -10 51.1371
17 0.4321 -0.0070 12 -12 47.9978
18 0.0000 +0.0000 0 0 99.9947

er, what does this mean?? What do this values stand for? Sorry for my newbie questions.


If you're looking for a mask of the motion, search for MaskTools in this forum and download the latest version. The function you'd want to use is MotionMask().


Ok, I'll try this out. The thing I need for my problem is something like the ouput of compare. I need values showing me how much of a frame changed.Like how simular are the frames?

Simular ==> no motion
Not Simular ==> there was something like a motion


If you just want to see all the differences between two frames, you could use
Subtract(last, last.trim(1,0)).levels(127,1,255,0,255)
If you want to see even more of what's going on, raise the gamma. [/B]

Ok, 'subtract' produces a new video clip, right?

SoonUDie
13th April 2004, 20:59
The problem with comparing just the frames to each other is that there can be motion, but it won't be detected. For example, think of a black frame with a white ball moving around on it. The average value of the frame is the same, no matter how much the ball moves.

Doing a Subtract() or a MotionMask() shows you exactly which things are changing on the pixel level. Both of them produce what you might call "new" clips, representing that information.

What exactly do you want to do with this information?

Alen
28th April 2004, 12:21
SoonUDie, sorry for my late response


You,re right.


The thing is need is this: I tried this java tool (see below the link) and it works, but it is very slow. So I am asking wheater is possibel to have such a 'process' in avisynth.

I want to process a given avi-file.
The output should be a textfile like this:


Area1 Area2 Area3 Area 4 .....Area n
Frame 1 4 5 4 4 ...
Frame 5 9 3 4 5
Frame 10 6 3 3 17
Frame 15 14 44 33 44
Frame n


You see, that output file should be a something like a matrix

The values should be the average for each area. And a frame should be splitted up in n areas of the same size.

What you thing, is there way to do such thing simular to the java project in AVISYNTH ?

-------------------------------



http://bart.sm.luth.se/~mathed-8/mDec/index.html

Group nearby pixels, and calculate their average intensity (black-and-white value), and use this new value for comparison with previous average values.


.......
This is accomplished by dividing the video stream into squares (pseudo-pixels), and calculate one value for each square, which is the average of all the pixels in the square. To give an example: With a square side of 5, an incoming video stream with resolution 320*240 will result in an internal representation 320*240/(5*5) squares. Since each square (pseudo-pixel) contains an average of 25 nearby pixels, the noise sensitivity is dramatically reduced compared to the case where each pixel is analysed by itself. Noise is present in image #1.

The actual comparison consists of comparing each square value with the corresponding one in the previous frame. If the difference exceeds a specified threshold, the area covered by the square is said to have considerable motion. As in image #2 it is mostly around the edges of an object that considerable movement occurs. As a final step, it is possible to decide how many such squares that must have moved before the whole video frame is thought to have considerable movement.


This technique with several types of motion thresholds (square size, difference threshold, and the number of squares containing considerable motion) allows us to detect and display subtle motion differences, while not activating the motion alarm, as well as fine-tune the motion detection algorithm.

SoonUDie
28th April 2004, 13:36
I don't think there are any functions to allow you to write a text file like that. I don't think it would be too hard to write a plugin though (If I knew C, I'd help you out :o ).

About the blocks thing, all you need to do is resize the image to small size using something like BilinearResize(). Each pixel will be a "block".

Alen
28th April 2004, 17:32
You mean wall the thing avisynth can't do, can be done by a 'own' avisynth plugin? Sure, someone has to write such a pluging. A friend of mine is C guru. Perhaps I should ask him :)

Thank your for your help!