pageauc
Posts: 229
Joined: Fri Jan 04, 2013 10:52 pm

Object (vehicle Speed Camera using openCV, python & picamera

Sat Aug 29, 2015 10:58 pm

speed_track.py
A Raspberry Pi Vehicle (object) Speed Camera Demo
using a Raspberry Pi computer, picamera module, python and openCV
written by Claude Pageau pageauc@gmail.com
6-Feb-2016 upgraded to release .99 see release notes here viewtopic.php?p=813535#p813535

NEW I have a newer Faster version of my Object Speed Tracking python script that uses threading for streaming
https://github.com/pageauc/motion-track ... ed-track-2

Let me know what you think. Note this is still just a demo

YouTube Demo and code walk through here https://youtu.be/eRi50BbJUro
GitHub Repo here https://github.com/pageauc/motion-track ... peed-track

Here is a previous YouTube video demonstrating a motion tracking test program using a Raspberry Pi B2.
this was the rough starting point for speed_track.py https://youtu.be/09JS7twPBsQ

Program Description
This is a raspberry pi computer openCV vehicle speed camera demo program. It is written in python and uses openCV2 to detect and track object motion. The results are recorded on speed photos and in a CSV log file that can be imported to another program for additional processing.
The program will detect and track motion in the field of view and use openCV to calculate the largest contour and return its x,y coordinate. Motion detection is restricted between y_upper and y_lower variables (road area). If a track is longer than track_len_trig variable then average speed will be calculated (based on IMAGE_VIEW_FT variable) and a speed photo will be taken and saved in an images folder. If log_data_to_file=True then a speed_track.log file will be created/updated with event data stored in CSV (Comma Separated Values) format.

Some of this code is based on a YouTube tutorial by Kyle Hounslow using C here https://www.youtube.com/watch?v=X6rPdRZzgjg

Quick Setup
Requires a Raspberry Pi computer with a RPI camera module installed, configured and tested to verify it is working. I used a RPI model B2 but a B+ or earlier should work OK.

Login via SSH or use a desktop terminal session and perform the following code block commands to install the required dependencies and program files.

Code: Select all

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install -y python-opencv python-picamera python-image python-pyexiv2
cd ~
mkdir speed-track
cd speed-track
wget https://raw.github.com/pageauc/motion-track/master/speed-track/speed_track.py
wget https://raw.github.com/pageauc/motion-track/master/speed-track/speed_settings.py
wget https://raw.github.com/pageauc/motion-track/master/speed-track/speed_track.md
chmod +x speed_track.py
python ./speed_track.py
You can also use git clone to copy the files to your RPI.

Code: Select all

cd ~
git clone https://github.com/pageauc/motion-track.git
mv motion-track/speed-track ./
This will clone all of my motion-track project and the speed-track will be in a subfolder in motion-track folder. You can move
this folder if you wish per the mv command otherwise exclude the last command.

Note an images folder will be created to store jpg speed photos. There is an image_path variable in the speed-settings.py file. Use nano editor to change variables in this file as desired. It will default to create a subfolder in the current folder that speed_track.py is launched from.

Use the calibrate option and follow instructions below to calculate an accurate value for IMAGE_VIEW_FT variable in the speed_settings.py

Calibrate IMG_VIEW_FT variable
speed_track.py needs to be calibrated in order to display a correct speed (mph or kph). Once calibrated the size of the vehicle does not matter since this calibration only sets the pixel per feet conversion factor.

Calibrate Procedure
  • - Setup the RPI camera to point to the view to be monitored.
  • - Login to RPI using SSH or desktop terminal session and cd to speed-track folder
  • - Use nano to edit speed_settings.py. Edit variable calibrate=True ctl-x y to save
  • - Start speed_track.py eg python ./speed_track.py
  • - Calibration images will be generated automatically when a motion track is complete. Files will be placed in images folder with a calib- prefix.
  • - Follow the on screen instructions for calibrating an accurate value for the IMAGE_VIEW_FT. You will need to measure appropriate vehicle lengths in feet.
  • - Adjust the y_upper and y_lower variables to cover the road area. Note image 0,0 is the top left hand corner and values are in pixels. Do not exceed the CAMERA_HEIGHT default 240 value
  • - Use an image viewer program to view the calib- files and use hash mark to record pixels for vehicle length Note each division is 10 pixels. I use filezilla to transfer files to/from my PC and the RPI using sftp protocol and the RPI IP address.
  • - Use formula below to calculate a value for IMG_VIEW_FT variable
  • - You should take several photos to confirm and average results.
  • - Use nano to edit the speed_settings.py and change IMG_VIEW_FT variable value to new calculated value. Also change variable calibrate = False
  • - Restart speed_track.py and monitor console messages. Perform a test using a vehicle at a known speed to verify calibration.
  • - Make sure y_upper and y_lower variables are correctly set for the area to monitored. This will restrict motion detection to area between these variable values. Make sure top of vehicles is included.
Please note that if road is too close and/or vehicles are moving too quickly then the camera may not capture motion and/or record vehicle in speed photo. Try adjusting the track_trig_len setting. If the roadway is farther away the camera will have more time to take a speed photo, but you may have to adjust event_timeout or x_diff_max variable settings

Calibration formula

Use this formula to calculate a value for IMG_VIEW_FT

IMG_VIEW_FT = (CAMERA_WIDTH * Ref_Obj_ft) / num_px_for_Ref_Object

eg (320 * 18) / 80 = 72

Settings
Variable values are stored in the speed_settings.py file and are imported when speed_track.py is run. Use the nano editor to modify these settings per the comments. Most settings should be OK and need not need to be changed. Others may need to be fine tuned depending on the distance from the camera to the road to be monitored. The openCV settings most likely won't need to be changed unless you are familiar with them.

Have Fun
Claude Pageau ....
YouTube Channel https://www.youtube.com/user/pageaucp
GitHub Repo https://github.com/pageauc
Last edited by pageauc on Mon May 16, 2016 5:35 pm, edited 9 times in total.
GitHub - https://github.com/pageauc
YouTube - https://www.youtube.com/user/pageaucp

pageauc
Posts: 229
Joined: Fri Jan 04, 2013 10:52 pm

Re: Vehicle Speed Camera using openCV, python & picamera

Mon Sep 07, 2015 1:25 pm

Proposed Vehicle Speed Camera Program Improvements.

Well I have been using my speed camera for a while and decided to improve the programming per the following. Will work on this when I get some free time.

1 - Set a speed limit variable to trigger recording of log and image(s) of potentially speeding vehicles when any event is over the speed limit. Might also have this for final speed only rather than any event.
2 - Record stream images to alternate stream variables. If any event is above the speed limit, then after the track is complete, save the opencv stream alternate images to disk and update a high speed log. This will avoid missing vehicle and won't require taking a larger image at the end of the track that might miss the vehicle if it is moving too fast. These images will be smaller 320x240 but I can resize larger after the track end and put text on those. The RPI should have enough memory for the sequence of small stream high speed images.
3 - Change csv log to put date, hour and minutes in separate columns. This will allow easier grouping for graphing traffic time of day statistics. Was thinking of looking at gnuplot python interface to do some graphing.
4 - Create a speed report in html format with the fastest sorted at the top by specified time period.
5 - It might be possible to post process saved speed images using opencv to group vehicles by colour.

Let me know if anyone has other ideas.
Claude .....
Last edited by pageauc on Tue Sep 08, 2015 7:57 pm, edited 1 time in total.
GitHub - https://github.com/pageauc
YouTube - https://www.youtube.com/user/pageaucp

pageauc
Posts: 229
Joined: Fri Jan 04, 2013 10:52 pm

Re: Vehicle Speed Camera using openCV, python & picamera

Wed Sep 09, 2015 7:33 pm

speed_motion.py Vehicle Speed Camera
9-Sep-2015 - Released version .99 to github

Updated image stream capture to use video port. This increases loop speed substantially.
The most significant improvement is using an existing event motion image
and re sizing it rather than take a new image. This improves speed photos
by removing delay for full size image. Captures motion closer to the center.

The following is a summary of the changes in version .97 changes.

* Changed Calibration to detect motion and take photos automatically
Photos are now saved in images folder with prefix calib-
* Changed speed photo to use resized existing motion image instead of
a New large image
* Added aver_speed number to speed photo filenames. Allows sorting files by speed.
* Final image is from previous event rather than current event to
have motion more in view.
* Improved verbose logging display.
* Improved CSV log to put hour and minutes in separate columns.
This allows for using as pivot table in spreadsheet
* Added a variable to restrict logging to speeds above a set point All=0.

See previous instructions for downloading and installing. viewtopic.php?p=808897#p808897
GitHub Repo here https://github.com/pageauc/motion-track ... peed-track
Please let me know what you think.
Last edited by pageauc on Sat Feb 06, 2016 6:39 am, edited 1 time in total.
GitHub - https://github.com/pageauc
YouTube - https://www.youtube.com/user/pageaucp

User avatar
jbeale
Posts: 3908
Joined: Tue Nov 22, 2011 11:51 pm

Re: Vehicle Speed Camera using openCV, python & picamera

Thu Sep 10, 2015 7:58 pm

Thanks for writing up all that and making the demo video. Do you have a sense for how consistent the program's results are?
For example, if several cars pass by each one driving at exactly 25.0 mph, what would you expect the program's output to look like? Would it detect each car, and how much spread would there be in the measured speed?

pageauc
Posts: 229
Joined: Fri Jan 04, 2013 10:52 pm

Re: Vehicle Speed Camera using openCV, python & picamera

Fri Sep 11, 2015 9:37 pm

Thanks Supra for the code fix. It is posted on github.

I have found the most recent update to be pretty accurate as far as my testing goes and I have my camera on a bit of an angle to the road so I have had to fine tune the settings for the median. It would be nice to have a sensor confirm the accuracy but this gets difficult with a road. I have just drove back and forth with my vehicle at certain speeds that I can compare on the related images. Make sure to log the data on a sheet of pager and mark the time of the test run so you can compare with the actual camera photos and log. If the track length trigger is long enough then accuracy is improved but puts vehicles closer to the edge.

It is possible for a vehicle to be going very fast and not give the camera a chance to trigger fast enough. Some times you will get movement detected that takes up processing. This does not have to be within the y upper, lower area to cause a slight slowdown. Remember all contours for the motion are returned, I just filter for specific contours that I am interested in. I have some trees in the view and if the wind is blowing this can trigger a contour. If you increase the min area then this can improve things. I have added display for number of contours in the most recent github update to show number of contours for Added Tracks. If you have a lot of contours then this could indicate a noisy background. I normally get less than 5 and usually fewer it the wind is not blowing too hard.

If the camera is very close to the roadway you will need to shorten the track length trigger a bit. This will put the vehicle closer to the center of the image but might reduce accuracy.

Please update to the most recent version on github since it now uses the actual motion image that is resized for the saved image. This works better and should not miss vehicles very much.

This was meant to be a fun challenge for me. I do not claim accuracy in every case. This is not like a sensor but I believe even a sensor would have issues when there are multiple vehicles. There are some additional checks that can be made like the w to h ratio for contours to make sure it is looking at a vehicle. eg if h is greater than w then it is a tall narrow object and probably not what you are looking for. Checking colours is another possibility. I decided to keep it fairly simple since a photo is taken and can confirm what the movement is. I have seen a lot of opencv videos and most have no sound, voice over commentary, show or link to code or repo, Etc. I consider the PI a learning tool with some practical uses. The code is meant to give others a chance to learn and adapt the code to their own uses or projects. I do not claim to be the best programmer in the world but you can learn a lot by googling. The hardest part of developing a program is to find an efficient algorithm that can be translated into code. The pi can be a challenge for opencv. Some demo's I have seen just process existing image or video files and do not deal with real time issues that can be more challenging. That is why I did not choose to just process rpi-cam-web-interface motion video files with a 3 second pre movement buffer setting.

Anyway I appreciate comments and suggestions

Thanks
Claude ...
GitHub - https://github.com/pageauc
YouTube - https://www.youtube.com/user/pageaucp

pageauc
Posts: 229
Joined: Fri Jan 04, 2013 10:52 pm

Re: Vehicle Speed Camera using openCV, python & picamera

Tue Nov 17, 2015 10:18 pm

A question was asked about pointing the camera at the ground. Here is my response FYI.

Yes you can point camera at the ground from a height above the objects you are trying to track speed. Objects don't have to be cars but can be anything moving. I just used vehicles for the example. You can always calibrate using a tape measure or object of known x coord length. You just need to calibrated the camera view for a distance (px per foot) where the expected moving objects will be (distance from camera). The program currently will recognize the single largest moving object in the frame and record speed of that object. Once calibrated to a distance the moving object can be any size that has an area above the MIN_AREA setting and is between the y_upper and y_lower settings. These variables are set in the speed_settings.py file.

Just remember in order to get an accurate speed the moving objects have to be a known distance away from the camera since the speed is based on the px/ft at that distance. The farther away an object is from the camera the moving object will cover a longer distance based on px/ft than if the same object was closer to the camera. eg if the camera width is 320 px then a very close object might cover 320px in a few feet but if it was far away then it might be hundreds of feet to travel the full 320px view of the camera. Also the speed is calculated over a track length distance to improve accuracy. This might need to be adjusted. Very close objects might go past the camera so quickly that the camera would not have a chance to capture a track length so ideally the moving object should be in frame for a few seconds at least. You might therefore need to position the camera farther away if the objects are moving fast. This would keep the objects within the view of the camera for a longer time period so a track can be calculated.
GitHub - https://github.com/pageauc
YouTube - https://www.youtube.com/user/pageaucp

pageauc
Posts: 229
Joined: Fri Jan 04, 2013 10:52 pm

Re: Vehicle Speed Camera using openCV, python & picamera

Sat Feb 06, 2016 2:14 pm

Now Much Faster FPS with Speed Track Camera Ver 0.99 Released 6-Feb-2016

Updated to version 0.99 that now uses video port streaming to dramatically increase the frame rate. The github repository at https://github.com/pageauc/motion-track ... peed-track has been updated. YouTube Demo and older code walk through here https://youtu.be/eRi50BbJUro I think this is still a demo but the code can be used for other purposes or just for fun. Thanks to Luc Bastiaens for the video code streaming logic that was based on work at http://www.pyimagesearch.com/2015/03/30 ... nd-python/
I have tested this on a RPI P2 overclocked per the following settings.

Code: Select all

arm_freq=950
sdram_freq=450
core_freq=250
over_voltage=6
gpu_mem=128
Using the 320x240 image size I achieved between 12.1 and 13.5 Frames per second for the opencv2 processing loop.
640x480 image size slows processing to between 9 and 11 FPS. I ran the same code with a recent updated Jessie on a B+ and achieved a slightly slower FPS approx 11.5 - 12.5. Your mileage may vary. If images are being saved this will slow the FPS a bit as well. These results were with ssh console. If you have Opencv windows displayed on an attached display then FPS of loop will be somewhat slower
If you have variable

Code: Select all

gui_window_on = True
and get error message
GdkGLExt-WARNING **: Window system doesn't support OpenGL
The error may occur with Rasbian Jessie but did not occur for me with Wheezy for some reason.
To Resolve this problem execute the following commands in a terminal session (ssh or desktop)

Code: Select all

sudo apt-get update
sudo apt-get install libgl1-mesa-dri
Reboot for change to take effect then retest your problem app
Regards Claude ...
Last edited by pageauc on Thu Mar 10, 2016 12:04 am, edited 6 times in total.
GitHub - https://github.com/pageauc
YouTube - https://www.youtube.com/user/pageaucp

Schuppenzot
Posts: 19
Joined: Mon May 12, 2014 8:21 pm

Re: Vehicle Speed Camera using openCV, python & picamera

Tue Apr 05, 2016 7:59 pm

What to do with this error?

Code: Select all

+++++++++++++++++++++++++++++++++++
speed_track.py - Exiting Program
+++++++++++++++++++++++++++++++++++

Traceback (most recent call last):
  File "./speed_track.py", line 388, in <module>
    speed_camera()
  File "./speed_track.py", line 340, in speed_camera
    image_write( filename, image_text )
  File "./speed_track.py", line 192, in image_write
    font = ImageFont.truetype( font_path, font_size, encoding='unic' )
  File "/usr/lib/python2.7/dist-packages/PIL/ImageFont.py", line 240, in truetype
    return FreeTypeFont(font, size, index, encoding)
  File "/usr/lib/python2.7/dist-packages/PIL/ImageFont.py", line 137, in __init_                                                     _
    self.font = core.getfont(font, size, index, encoding)
IOError: cannot open resource
EDIT: nevermind: since I'm headless I don't have many fonts installed. copied one to my home dir and changed the link in the code. All is working.

I do only reach 11fps on a Pi3 though...

bismosa
Posts: 43
Joined: Sun Dec 23, 2012 11:43 am

Re: Vehicle Speed Camera using openCV, python & picamera

Tue May 10, 2016 7:07 pm

Hello!

Thanks for sharing this code! Im at testing.

The first thing i found is the speed conversion to KPH. I think you must change the code in line 69 to:

Code: Select all

speed_conv = px_to_mph / 1.609344
With the Cars on the street it seems to be working good. But i tried to capture also the speed of the trains (yes...Im living near to a railroad). But here are no reasonable results. I think the problem ist the length of the object? What settings can i modify to get better results?
The speed of the Train is about 100kph...
44-speed-20160510-205738.jpg
44-speed-20160510-205738.jpg (57.7 KiB) Viewed 19433 times
74-speed-20160510-205739.jpg
74-speed-20160510-205739.jpg (52.25 KiB) Viewed 19433 times
38-speed-20160510-205740.jpg
38-speed-20160510-205740.jpg (52.26 KiB) Viewed 19433 times
I think one problem is the speed of the Raspberry. I using the B+ (not the 2)...with a average 8fps.

Very interesting funny project!

Regards
Bismosa

User avatar
jbeale
Posts: 3908
Joined: Tue Nov 22, 2011 11:51 pm

Re: Vehicle Speed Camera using openCV, python & picamera

Wed May 11, 2016 10:57 pm

I haven't used this specific program but in some of my OpenCV experiments, an object was not detected as such until it was completely separate from the four edges of the frame. That algorithm would not detect a train, because it is never contained entirely within the image frame.

Return to “Automation, sensing and robotics”