pageauc / speed-camera

A Unix, Windows, Raspberry Pi Object Speed Camera using python, opencv, video streaming, motion tracking. Includes a Standalone Web Server Interface, Image Search using opencv template match and a whiptail Admin Menu Interface Includes picam and webcam Plugins for motion track security camera configuration including rclone sync script. watch-app allows remotely controller camera configuration from a remote storage service name. Uses sqlite3 and gnuplot for reporting. Recently added openalpr license plate reader support.
Apache License 2.0
960 stars 169 forks source link

Idea for more accurate speed calculation #129

Closed sebsoft closed 9 months ago

sebsoft commented 1 year ago

Hi Claude,

I've changed the logging a bit to log the cur_ave_speed instead of ave_speed to show the speed of the individual measurements instead of the running average. Before calculating the average that will be stored with the picture the z score for each measurement can be computed which can be used to remove outliers from the list. In the example below z score limit is set to 2 which removes the outlier at 1/10 .

2023-02-27 10:38:35 INFO speed_camera New - 0/10 xy(66,211) Start New Track 2023-02-27 10:38:36 INFO speed_camera Add - 1/10 xy(73,209) 2.88 kph D=7/50 C=11 269x91=9135 sqpx L2R 2023-02-27 10:38:36 INFO speed_camera Add - 2/10 xy(100,209) 67.24 kph D=27/50 C=12 269x91=8837 sqpx L2R 2023-02-27 10:38:36 INFO speed_camera Add - 3/10 xy(127,208) 52.72 kph D=27/50 C=10 269x86=8538 sqpx L2R 2023-02-27 10:38:36 INFO speed_camera Add - 4/10 xy(154,208) 50.91 kph D=27/50 C=7 268x83=8188 sqpx L2R 2023-02-27 10:38:36 INFO speed_camera Add - 5/10 xy(182,208) 75.26 kph D=28/50 C=6 257x78=6650 sqpx L2R 2023-02-27 10:38:36 INFO speed_camera Add - 6/10 xy(203,207) 48.32 kph D=21/50 C=9 255x75=6623 sqpx L2R 2023-02-27 10:38:36 INFO speed_camera Add - 7/10 xy(223,208) 82.81 kph D=20/50 C=9 256x72=7431 sqpx L2R 2023-02-27 10:38:36 INFO speed_camera Add - 8/10 xy(193,211) 95.00 kph D=30/50 C=8 62x77=1377 sqpx R2L 2023-02-27 10:38:36 INFO speed_camera Add - 9/10 xy(207,218) 39.72 kph D=14/50 C=8 49x74=1766 sqpx L2R 2023-02-27 10:38:36 INFO speed_camera Add - 10/10 xy(228,212) 37.54 kph D=21/50 C=6 57x77=1316 sqpx L2R 2023-02-27 10:38:36 INFO speed_camera z score -2.09 removed 2.88 2023-02-27 10:38:36 INFO speed_camera z score -0.10 2023-02-27 10:38:36 INFO speed_camera z score -0.17 2023-02-27 10:38:36 INFO speed_camera z score 0.80 2023-02-27 10:38:36 INFO speed_camera z score -0.28 2023-02-27 10:38:36 INFO speed_camera z score 1.10 2023-02-27 10:38:36 INFO speed_camera z score 1.59 2023-02-27 10:38:36 INFO speed_camera z score -0.62 2023-02-27 10:38:36 INFO speed_camera z score -0.71

                               #iterate through list and remove the outliers -- z score > 2
                                for x in speed_list:
                                    z = ( x - ave_speed) / std_speed
                                    if abs(z) > 2.0:
                                        speed_list.remove(x)
                                        logging.info("z score %3.2f  removed %3.2f",
                                             z,
                                             x,        
                                             )
                                    else:
                                        logging.info("z score %3.2f",
                                             z,
                                             )
                                #recalulate the average speed without the outliers
                                ave_speed = np.mean(speed_list)
pageauc commented 1 year ago

Is your code on Github? Do you plan on doing a github push? Claude

On Mon, Feb 27, 2023 at 5:00 AM sebsoft @.***> wrote:

Hi Claude,

I've changed the logging a bit to log the cur_ave_speed instead of ave_speed to show the speed of the individual measurements instead of the running average. Before calculating the average that will be stored with the picture the z score for each measurement can be computed which can be used to remove outliers from the list. In the example below z score limit is set to 2 which removes the outlier at 1/10 .

2023-02-27 10:38:35 INFO speed_camera New - 0/10 xy(66,211) Start New Track 2023-02-27 10:38:36 INFO speed_camera Add - 1/10 xy(73,209) 2.88 kph D=7/50 C=11 269x91=9135 sqpx L2R 2023-02-27 10:38:36 INFO speed_camera Add - 2/10 xy(100,209) 67.24 kph D=27/50 C=12 269x91=8837 sqpx L2R 2023-02-27 10:38:36 INFO speed_camera Add - 3/10 xy(127,208) 52.72 kph D=27/50 C=10 269x86=8538 sqpx L2R 2023-02-27 10:38:36 INFO speed_camera Add - 4/10 xy(154,208) 50.91 kph D=27/50 C=7 268x83=8188 sqpx L2R 2023-02-27 10:38:36 INFO speed_camera Add - 5/10 xy(182,208) 75.26 kph D=28/50 C=6 257x78=6650 sqpx L2R 2023-02-27 10:38:36 INFO speed_camera Add - 6/10 xy(203,207) 48.32 kph D=21/50 C=9 255x75=6623 sqpx L2R 2023-02-27 10:38:36 INFO speed_camera Add - 7/10 xy(223,208) 82.81 kph D=20/50 C=9 256x72=7431 sqpx L2R 2023-02-27 10:38:36 INFO speed_camera Add - 8/10 xy(193,211) 95.00 kph D=30/50 C=8 62x77=1377 sqpx R2L 2023-02-27 10:38:36 INFO speed_camera Add - 9/10 xy(207,218) 39.72 kph D=14/50 C=8 49x74=1766 sqpx L2R 2023-02-27 10:38:36 INFO speed_camera Add - 10/10 xy(228,212) 37.54 kph D=21/50 C=6 57x77=1316 sqpx L2R 2023-02-27 10:38:36 INFO speed_camera z score -2.09 removed 2.88 2023-02-27 10:38:36 INFO speed_camera z score -0.10 2023-02-27 10:38:36 INFO speed_camera z score -0.17 2023-02-27 10:38:36 INFO speed_camera z score 0.80 2023-02-27 10:38:36 INFO speed_camera z score -0.28 2023-02-27 10:38:36 INFO speed_camera z score 1.10 2023-02-27 10:38:36 INFO speed_camera z score 1.59 2023-02-27 10:38:36 INFO speed_camera z score -0.62 2023-02-27 10:38:36 INFO speed_camera z score -0.71

                           #iterate through list and remove the outliers -- z score > 2
                            for x in speed_list:
                                z = ( x - ave_speed) / std_speed
                                if abs(z) > 2.0:
                                    speed_list.remove(x)
                                    logging.info("z score %3.2f  removed %3.2f",
                                         z,
                                         x,
                                         )
                                else:
                                    logging.info("z score %3.2f",
                                         z,
                                         )
                            #recalulate the average speed without the outliers
                            ave_speed = np.mean(speed_list)

— Reply to this email directly, view it on GitHub https://github.com/pageauc/speed-camera/issues/129, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABNPKZG2KUZCESWKACHTZMTWZSCMHANCNFSM6AAAAAAVJH2EVU . You are receiving this because you are subscribed to this thread.Message ID: @.***>

-- YouTube Channel at https://www.youtube.com/user/pageaucp http://www.youtube.com/user/pageaucp GitHub Repository at https://github.com/pageauc

sebsoft commented 1 year ago

Sure, do you want me to push it here ? I'am a starter with github (and python) so then you would have to add me as a contributor ? Sebastiaan

pageauc commented 1 year ago

I don't see your speed camera code on sebsoft. Normally you would clone speed camera repo to sebsoft make changes and create a push of changes to me for review and then I would do a merge. I am not a Github expert but this has worked in the past. I have my motrack demo https://github.com/pageauc/MoTrack-Picam2-Demo working the way I want and will incorporate new and revised functions into speed camera code. I am recovering from a severe left hand injury and typing with one hand sucks.

If you want you can zip your new speed-cam.py script and post as attachment on this issue. I can then do a diff an add your changes with mine. If that is OK. Claude .,..

sebsoft commented 1 year ago

Hi Claude,

I just gave it a try pushing the changes.

As said these are my first ventures in python so see what you can use.

Sebastiaan

carterw commented 1 year ago

Where does std_speed come from?

sebsoft commented 1 year ago

Its the standard deviation of the calculated speeds, i've added these lines

speed_list.append(cur_ave_speed) ave_speed = np.mean(speed_list) std_speed = np.std(speed_list)

carterw commented 1 year ago

Thanks! Yesterday I came across this "How to Find Outliers in NumPy" article, your code resembles Method #3.

https://blog.finxter.com/how-to-find-outliers-in-python-easily/

sebsoft commented 1 year ago

Thats nice. In the meantime i found that you get best results using object detection.  Do object detection on the first and last image and use the displacement of the boundingbox to calculate the speed.Verstuurd vanaf mijn iPhoneOp 3 aug. 2023 om 16:00 heeft Bill Carter @.***> het volgende geschreven: Thanks! Yesterday I came across this "How to Find Outliers in NumPy" article, your code resembles Method #3. https://blog.finxter.com/how-to-find-outliers-in-python-easily/

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you authored the thread.Message ID: @.***>

carterw commented 1 year ago

That does make sense. This project works on the principle of "get the difference between 2 images, find the largest contour, if it moves assume it is a car. and that same largest contour will be the one detected in multiple subsequent images". Would be nice to know for sure it is a car and just work with 2 relevant car objects.

pageauc commented 1 year ago

I have revised logic to eliminate double image read and changed average speed calculation from np.mean to np.std See revised speed-cam.py ver 12.01. You can do a menubox.sh UPGRADE menu pick to download changes.

Also the program is an object tracker and not specific to vehicles. I may add an option to do vehicle tracking using vehicle recognition that should improve accuracy due to less chance of moving largest contours relative to moving object.

Let me know results of your testing.

carterw commented 1 year ago

I have revised logic to eliminate double image read and changed average speed calculation from np.mean to np.std

I don't think that is going to give correct results. np.std() is the variation of the data which is helpful to identify outliers, but it won't represent a car speed.

From wikipedia; "the standard deviation is a measure of the amount of variation or dispersion of a set of values.[1] A low standard deviation indicates that the values tend to be close to the mean (also called the expected value) of the set, while a high standard deviation indicates that the values are spread out over a wider range."

import numpy as np ar = [21,23,25,27,29,31] # some typical car speeds np.mean(ar) 26.0 np.std(ar) 3.415650255319866 # not any of the speeds

You might consider using np.median(). https://www.diffen.com/difference/Mean_vs_Median

pageauc commented 1 year ago

I have change ave speed to np.median. May improve results

On Sat, Aug 5, 2023 at 11:28 AM Bill Carter @.***> wrote:

I have revised logic to eliminate double image read and changed average speed calculation from np.mean to np.std

I don't think that is going to give correct results. np.std() is the variation of the data which is helpful to identify outliers, but it won't represent a car speed.

From wikipedia; "the standard deviation is a measure of the amount of variation or dispersion of a set of values.[1] A low standard deviation indicates that the values tend to be close to the mean (also called the expected value) of the set, while a high standard deviation indicates that the values are spread out over a wider range."

import numpy as np ar = [21,23,25,27,29,31] # some typical track speeds np.mean(ar) 26.0 np.std(ar) 3.415650255319866 # not any of the speeds

— Reply to this email directly, view it on GitHub https://github.com/pageauc/speed-camera/issues/129#issuecomment-1666534287, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABNPKZCPFV5LRCHKO6NJAELXTZRA3ANCNFSM6AAAAAAVJH2EVU . You are receiving this because you commented.Message ID: @.***>

-- YouTube Channel at https://www.youtube.com/user/pageaucp http://www.youtube.com/user/pageaucp GitHub Repository at https://github.com/pageauc

johncblacker commented 9 months ago

So, I propose using google coral tpu accelerator for performance improvement and implement the concept of object detection once every X number of frames and object tracking using dlib on the other frames. Also, implement the use of centroid tracking. As I see it inaccuracy comes from triggering as soon as motion is detected (which may be a car, maybe not) and then following that across the FOV. That results in inaccuracy and false object detection. Again, Adrian Rosebrock's example using centroid tracking is most accurate and performance enhancement via google coral edgetpu.

carterw commented 9 months ago

That device looks interesting, but the Pi 4 is capable of running tensorflow lite object recognition at a pretty reasonable speed. I've got one on my desk that can run the examples in the picamera2 repository. https://github.com/raspberrypi/picamera2/tree/main/examples/tensorflow

I don't have any experience with dlib, is there any advantage to it over the 'motion detection with bounding box' method being used in this project?