Generating Win32 Crash Dumps

Every Software Engineer knows that most software ends up crashing eventually, when it does it is very useful to have a full crash log to help you determine the cause of the problem, to that end here is a good article that I found on working on what Microsoft calls ‘Minidumps’ on windows.

http://crashrpt.sourceforge.net/docs/html/using_minidump.html

This is some code for catching unhanded exceptions (typically like null pointer references or heap corruption etc.) and writing a crash dump that can later be opened up with visual studio:

#include "DbgHelp.h"
LONG WINAPI UnhandledExceptionHandler(PEXCEPTION_POINTERS pExceptionPtrs)
{
   // This writes a dump file to the current dir.
   // To view this file open it up in Visual Studio
   // If source and symbols are available you should
   // along with the crash point.
   HANDLE hFile = CreateFileA("crash_dump.dmp",
		GENERIC_WRITE,
		0,
		NULL,
		CREATE_ALWAYS,
		FILE_ATTRIBUTE_NORMAL,
		NULL);
    MINIDUMP_EXCEPTION_INFORMATION aMiniDumpInfo;
    aMiniDumpInfo.ThreadId = GetCurrentThreadId();
    aMiniDumpInfo.ExceptionPointers = pExceptionPtrs;
    aMiniDumpInfo.ClientPointers = TRUE;
    MiniDumpWriteDump(GetCurrentProcess(),
            GetCurrentProcessId(),
            hFile,
            (MINIDUMP_TYPE) (MiniDumpWithFullMemory|MiniDumpWithHandleData),
            &aMiniDumpInfo,
            NULL,
            NULL);
    CloseHandle(hFile);
    return EXCEPTION_EXECUTE_HANDLER; 
} 
int main(int argc, char* argv[]) {
	SetUnhandledExceptionFilter(UnhandledExceptionHandler);
	// Do yer normal stuff here...
	// Crash-tastic!
	int* p = 0;
	*p = 0;
}

You will need to link to DbgHelp.lib.

If you run your program from within visual studio’s debugger (e.g. F5) then the debugger won’t let execution run on to the handler, so to test the handler you will have to run your program without the debugger (e.g. ctrl-F5), bit of an annoyance but there you have it…

Image Storage and Indexing for Machine Vision Images

Every Software Engineer needs a hobby – to this end I have been toying with an idea for the last while.

There are many machine vision and computer vision applications that capture images from cameras and store them on disk. These applications can generate so many images that working with them can be quite difficult. For example consider an application that acquires from two cameras each acquiring at 30 frames per second – this application will save 216K images per hour, a 5 hour run would generate 1 million images!

Very often the images will be stored on a file system (local or networked) in some sort of hierarchical directory structure. Using a file system is a very efficient way of storing images, database systems (Relational or NoSQL) don’t offer many advantages and indeed can have associated disadvantages.

But how can we effectively work with so many images, we have possibly millions of images sitting in a set of directories, how can we interact with them and efficiently and query them based on attributes that are interest to us so the we can perform more analysis?

For example consider this set of (contrived) image queries:

Give me all of the images:

+ from camera 1
+ from camera 1 acquired on Sunday between 13:00 and 13:10
+ whose file size > 1MB
+ acquired within 100 meters of this GPS location
+ that have an average brightness > 63 Grey levels

Some people have attacked this image query problem by using a relational database to store image meta-data, if designed well this can allow for efficient image retrieval, however it seems to me that a schema-less approach is a better fit for images with dynamic attributes and I like the idea of not being tied down to any particular database technology and all of the baggage that comes with it.

So my idea is to start out on the road of implementing (for fun) a simple image indexing system for rather large sets of images, it will have an associated tool set, API and maybe even a query language in the future.

The system will:

Allow indexing of large numbers of images in arbitrary hierarchical directory structures

Index images based on standard attributes such as:

+ Acquisition Date/Time
+ Name
+ Source (e.g. camera)
+ Type
+ Size
+ Bit Depth
+ Exif Data, e.g.:
–> Location
–> Author
–> Acquisition parameters (aperture, exposure time etc.)
+ Etc.

Index images optionally based on Computer Vision metrics, e.g.
+ Brightness
+ Sharpness
+ Etc.

Allow users to define their own attributes for indexing, e.g.:
+ Define image attributes based on an OpenCV algorithm
+ Define attributes based on the contents of the image fie name.

The system will:

+ Have no dependencies on technologies such as Database systems etc.
+ Be cross platform

To get the ball rolling and so that we can say the first sod has been turned, here is some (naive) python which scans a directory tree of images and creates a flat CSV file of the image name, path and size:

#!/usr/bin/python
import argparse
import fnmatch
import os
import time
parser = argparse.ArgumentParser()
parser.add_argument("-p", "--path", help="The root path to the images directory tree")
args = parser.parse_args()
path = args.path
print 'looking in ' + path
ii = 0
start = time.time()
with open('%s/.flat' % path, 'w') as out:
    for root, _, filenames in os.walk(path):
        for name in fnmatch.filter(filenames, '*.jpg'):
            p = os.path.relpath(root, path)
            (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime) = os.stat(os.path.join(root, name))
            f = {'name': name, 'path': p, 'size': size}
            out.write("i,%s,%s,%d\n" % (name, p, size))
            ii += 1
            if ii % 1000 == 0:
                print "Reading %d" % ii

duration = time.time() - start
print '%d images indexed in %d seconds, %d images/s' % (ii, duration, ii / duration)

Run it like this:

scanner.py --path "images\Run1\ccm17"

Once the directory tree has been walked and the CSV file generated we can use the following script to query images:

#!/usr/bin/python
import argparse
import os
import csv
parser = argparse.ArgumentParser()
parser.add_argument("-p", "--path", help="The root path to the images directory tree")
parser.add_argument("-w", "--where", help="The where value")
args = parser.parse_args()
path = args.path
print 'looking in ' + path
code = compile(args.where, '', 'eval')
images = []
index = (os.path.join(path, '.flat'))
jindex = (os.path.join(path, '.flat.json'))
print('opening index' + index)
class Image:
    def __init__(self, name, size, path):
        self.name = name
        self.size = size
        self.path = path
with open(index) as csvfile:
     spamreader = csv.reader(csvfile, delimiter=',', quotechar='|')
     for row in spamreader:
         images.append(Image(row[1], row[3], row[2]))
print 'index loaded'
for image in images:
    if eval(code):
        print('%s %s' % (image.name, image.size))

This allows us to run queries like this:

select.py --path "images\Run1\ccm17" --where "'_43' in image.name and image.size > 76000"

This will quickly list the images whose file size > 76000 bytes and whose name contains ‘_43’

This is a really simple first step but it does demonstrate how even a flat ‘index’ of attributes can be of great use.

Next Step:

+ Add more image attributes to the CSV file

Software Algorithm Complexity Cheat-Sheet

Software Algorithm Complexities – Having trouble remembering your O(n)’s from your O(log N)’s, not to worry I just found this very handy complexity cheat-sheet –

http://bigocheatsheet.com/

I am currently doing some research into possible indexing mechanisms for very large sets of images in Computer Vision applications, so this sheet is very handy, thanks Eric!

Quantum QBits in Silicon?

Quantum Computers (and hence Quantum Software Engineering) may have taken a rather large step forward if (as The Register reports) The University of New South Wales has managed to render a qbit in plain old silicon!

Looks like I will have to start swatting up on my Quantum Algorithms… (I tried this before and it really hurt my head!)

Can’t sync to NTP server when upstream clock is not available

We were doing some software and systems testing this week, this involved setting up a completely isolated network of cameras with their own NTP server for time synchronization across them. The NTP server was configured to broadcast time updates via UDP. Everything worked OK except the NTP server stopped broadcasting once it lost time synchronization with its up-stream clock (which it lost because all connections to external networks were removed).

To resolve this problem and get the NTP server broadcasting again we had to allow it to synchronize with its own internal clock and pretend that it was a stratum 2 time source (accurate timing wasn’t required during this phase of testing).

To do this the following was added to /etc/ntpd.conf (with thanks to this post)

#
# Undisciplined Local Clock. This is a fake driver intended for backup
# and when no outside source of synchronized time is available.
server  127.127.1.0     # local clock
fudge   127.127.1.0 stratum 2
#

Once the change is made, restart the NTP daemon:

sudo /etc/init.d/ntp restart

The first line allows us to sync with the local clock while the second line ‘elevates’ it to stratum 2

This isn’t a brilliant time-base but it allowed us to test basic time synchronization scenarios.

WPF Validation Error Disappearing when Switch between visual items

Typical daily trials of a Software Engineer – getting WPF error validation working can be a bit of a pain, it’s a bit buggy.

I hit a problem today whereby errors marked for text boxes on a tab would disappear if you moved away from the tab and then back again, it turned out to be a common WPF problem and this post provided a fix, you just need to wrap your tab content inside an:

<AdornerDecorator>...</AdornerDecorator>

element. Bit of a pain but at least it seemed to work once I put these elements in!

DevOps Ireland

DevOps in Ireland? I have been very interested in DevOps ever since I watched Adam Jacob give his ChefConf 2015 keynote speech. I wondered if there are any Irish DevOps groups and a little digging revealed:

Twitter Account: @DevOpsIreland
Website (Empty!): devops.ie
LinkedIn Group: DevOps Ireland

devops.ie must be taking the iterative approach seriously as rev 1.0 of the website is up there alright…. but it’s empty! ;-)

Handy archive of boost binaries for Windows / Visual Studio

Every now and again I have to work on an old software project that may use an older version of the boost libraries. Well if like me, you occasionally find that you are missing some boost .lib file or other binary then have a look at this very handy archive of the boost windows binaries maintained by Thomas Kent:

http://boost.teeks99.com/

Thanks Thomas, very handy!

boost_software_library

Interesting Analysis of the State of Microsoft’s Software Development Tools

The Register published an interesting article on the state of Microsoft’s software development tools today – it focuses on tools for developing desktop apps. Although well written, the article doesn’t make up-beat reading and is in fact quite depressing. WPF and related development tools have been let languish for so long now it is hard to see if it can be brought up to scratch in any reasonable time-frame….

I suppose the message is that things have moved on and that most apps that are consumed on the desktop, except in a few niche areas (machine vision being one of them?), will be delivered on the web via our new friends HTML5, javascript, angular.js et. al.

What do you think? Does Microsoft have the ability or the will to pull out of this nose dive? I hope they do as they have been leaders in this area before and it is a shame to see things decay….

Streaming mjpeg video with a web2py and python server

Recently I investigated whether I could implement software streaming of mjpeg video on a camera that uses web2py and python as its HTTP interface. Web2py makes most common operations quite straightforward and streaming is no exception, although I had to go digging for some details, this post along with SergeyPo’s answer to this question were of immense help.

mjpeg or Motion JPEG streaming over HTTP is a popular way of streaming video from IP cameras. If your camera has already gone to the effort of jpeg’ing its frames then it is reasonably cheap to stream them out via software over HTTP as an mjpeg video stream (as opposed to encoding to h264 etc.).

Mjpeg can be viewed natively by most browsers (except Internet Explorer) and can also be viewed on video viewers like VLC etc. An mjpeg stream is quite simple, it really just contains the individual jpeg frames’ data separated by a defined frame boundary marker.

Web2py takes care of chunked streaming via the stream() function, we just have to write a file object that we pass to stream(), this will take care of loading the jpeg frames and providing the data back to stream(), which in turn will stream this down the line to the client.

So to create an mjpeg stream we:

1.) Add a web2py handler for the stream, for example /mjpeg

2.) Add the following to the response headers: “multipart/x-mixed-replace; boundary=the_answer_is_42”
“the_answer_is_42” is just a made-up boundary marker which we hope won’t appear in the jpeg frame data, it can be changed to something else.

3.) Call stream() passing an instance of our MJPEGStreamer file object (see #4!), and a fairly arbitrary chunk size.

4.) Define a file compatible object that will loop ‘forever’ and provide the data to stream(), it will provide the data for the individual jpeg frames as well as insert the frame boundaries (–the_answer_is_42) between frames, it also inserts the headers for the individual frames (Content-Type: image/jpeg).

The following provides an overview of a stream implementation. Here we imagine that the latest jpeg frame is to be found in a ram-disk file called image.jpg, we load this data so that we can stream it to the client.

So in our web2py controller we have something like:

#
# Proof of concept web2py mjpeg streamer
#
def mjpeg():
    # Set the initial response header
    response.headers['Content-Type'] = 'multipart/x-mixed-replace; boundary=the_answer_is_42'
    # stream the mjpeg data (via MJPEGStreamer) with a chunk size of 
    # 30000, the chuck size must be less than the size of the smallest 
    # jpeg frame or the stream will stall....
    return response.stream(MJPEGStreamer(), 30000)
class MJPEGStreamer(): 
    def __init__(self): 
        self.iterator = self.make_iterator() 
    def make_iterator(self): 
        while True:
            out = ''
            # Read a jpeg frame from image.jpg
            data =  open('/media/ram/image.jpg', 'rb').read()
            
            # Add the frame boundary to the output
            out += "--the_answer_is_42\r\n"
            
            # Add the jpg frame header
            out += "Content-Type: image/jpeg\r\n"
            # Add the frame content length
            out += "Content-length: "+str(len(data))+"\r\n\r\n"
            # Add the actual binary jpeg frame data
            out += data
            
            yield out  
            # Sleep for a bit..
            time.sleep(0.07)
    # stream() calls read() to get data.
    def read(self, n):
        # Get some more stream data
        n = self.iterator.next() 
        return n 
#
#

To view the mjpeg stream, open VLC viewer and choose Media / Open Network Stream and provide the stream URL (e.g. http://my_streaming_host/mjpeg) and hit play…

I found that it was important to set the chunk size to be (a good bit?) less than the data size of the smallest frame to be sent or else the stream will stall…