‘Cause I got something for you. It is shiny, it is clean.

In which we use OpenCV to track a laser.

Building on my article about using HSV thresholding to isolate features in video frames, below is a video showing the use of OpenCV to track a red laser.  The majority of the algorithm is the same as presented in the previous article; the only addition is actually determining the area of interest after thresholding.  In order to preventing spoiling anyone's fun, I am not going to post the code as of now.

Hint: think about how to find the largest area in white after thresholding.

If you would like to compare algorithms or just want to know what I did, drop me a note via the contact form.

In preliminary testing, the algorithm seems robust enough to handle changing lighting conditions as well as differing background colors; however, the angle of reflection of the laser can cause issues.  For best results, the laser should be relatively perpendicular to the image plane.  As the laser approaches being parallel to the image plane, less laser light is reflected back to the camera.  The same applies to irregular objects or surfaces that scatter the laser at angles away from the camera.  This can be seen at the end of the video when the laser is reflected off the lamp shade.

Testing was done using a Logitech C920.  Depending on the laser used and ambient lighting conditions, turning off auto white balance may prevent the intensity of the laser from being interpreted as white.

As far as applications, I leave that to the reader.

Come together, right now...

In which we join files line by line.

Working in IT, there is no shortage of "grunt work" that is amenable to one off scripts or applications.  In an effort to prevent others (and possibly myself) from having to reimplement these, I am publishing these as useLESS tools.

useLESS tools: scripts or programs written to paper over the shortcomings or deficiencies in applications or processes.  You could use less, and they would be made useless, if you could reimplement everything in light of the experience gained by doing it the last time.

Today I give you our first useLESS tool - fjoin

At work I am currently involved in integrating with an external vendor.  As part of the process, I have been provided with pseudo realistic test data to process.  Being pseudo realistic, it doesn't really match with what our system expects and must be "massaged".  That is to say, nothing works.

In particular, I have two text files.  One text file has the IDs used by the vendor, and the other has the IDs our system expects.  I need a way to turn these into SQL update statements, and it needs to be repeatable so I can rerun it as testing progresses.  What to do?

Using notepad++ or you favorite editor, it is fairly easy to record a macro that inserts

UPDATE [TABLE] SET [FIELD] = '

before each line of one file and

' WHERE ID = 

at the beginning of each line in the other so that if you took line x from the first file and line x from the second file and joined them, you would get something like

UPDATE [TABLE] SET [FIELD] = 'OURID_123' WHERE ID = 42

The real trick is merging the two files line by line.  fjoin does just this.  It takes two or more files and joins them line by line stopping at the end of the shortest file.  The result is sent to the terminal so you can pipe this into another program or redirect to a file.

If you would like to create an executable from this code, you can use pyinstaller

pysinstaller -F fjoin.py

This will create a single (rather large) executable for you.

import sys

if len(sys.argv) == 1:
    print 'No files specified'
    sys.exit(0)

files = []
# skip the name of the program
for arg in sys.argv[1:]:
    try:
        files.append(open(arg))
    except IOError:
        print 'ERROR:', arg, 'does not exist'
        sys.exit(1)

reading = True
composite = []

while reading:
    for f in files:
        line = f.readline()
        # stop as soon as a file comes up short
        if not line:
            reading = False
            break
        else:
            # remove newline
            composite.append(line.rstrip('\n'))
    # only output if we joined across all files
    # in other words, no partial lines
    if len(composite) == len(files):
        print ''.join(composite)
    composite = []

for f in files:
    f.close()

fjoin.py (2.36 kb)

I suggest you gentlemen invent a way to put a square peg in a round hole.

In which we optimize OpenCV on the BeagleBone Black.

If you have been paying attention to the BBB group on Google Groups, you may have discovered a lively thread on webcams [1]. As part of this thread, I have been working with Michael Darling to realize the best performance possible when using OpenCV to process an MJPG stream from a webcam on the BBB.  OpenCV relies on libjpeg when loading the MJPG frames to OpenCV Mats, and libjpeg is not the fastest of jpeg libraries.  However, there is another option - libjpeg-turbo [2].

While it is technically possible to compile OpenCV with libjpeg-turbo support on the BBB, you will have fewer issues and spend less time compiling if you use a cross compiler on a more powerful computer.  Michael has written a guide to cross compiling OpenCV.  Below you will find the guide as a webpage for online viewing or a pdf for download as well as the latest code to capture frames from a webcam and convert them to OpenCV Mats.  The guide is currently a draft, and we would appreciate any feedback you can provide.  Many thanks to Michael for taking the time to write this up.

Note: The code in the guide and the latest code are slightly different.

  1. -o is used to indicate which frames to convert to OpenCV Mats and requires an integer argument.
        -o 1 will convert every frame
        -o 2 will convert every 2nd (ever other) frame, and so on.
        The default is 1.
  2. -p is similar to -o in the original framegrabber.  However, it doesn't actually output anything.  It just controls if any frames are to be converted.
  3. Captured count and processed count variables have been renamed and moved to the top.
  4. Formatting has been corrected.
  5. Setting of the Mat size now uses the width and height variables.

 

The guide will be updated to reflect these changes in a future release, but in the meantime, you will need to adjust the command line arguments specified in the guide, namely replace -o with -p.

Guide [DRAFT]
    BBB_30fps.html
    BBB_30fps.pdf (204.32 kb)
Code
    framegrabberCV.c (19.77 kb)

[1] problems with webcams
[2] libjpeg-turbo