Cross compiling libEXIF for ARM on Ubutnu

libexif is a software library that allows you to add EXIF tags to JPEG images, for example when saving JPEG images via libJPEG.

The following is a log of the steps taken to cross compile libexif on ubuntu for an ARM IoT device, you will need the arm-linux-gnueabi tool-chain installed on your build machine:

1.) Download the latest libexif source code from:

http://sourceforge.net/projects/libexif/files/latest/download?source=files

2.) uzip & untar the software:

3.) Execute the following from bash or similar:

cd libexif-0.6.21
./configure --host=arm-linux-gnueabi CC=arm-linux-gnueabi-gcc AR=arm-linux-gnueabi-ar \ 
             --prefix=/home/me/build_exif/_install
make
make install

This should put the output files into /home/me/build_exif/_install ready for copying onto your ARM device.

Code to test u-blox Binary GPS Packet Checksum

Here’s something random for a Thursday, the following is some simple C++ code for checking the checksum of a u-blox binary GPS packet, for some reason we get quite a few packet data errors, so it turns out that it is important to check the checksum!

There must be an unwritten (or written?) software engineering rule which states that you should always check a checksum if one’s provided??!?

Note: Make sure to pass only complete packets to this function, it assumes it has everything to work with!

//
//
bool is_checksum_ok(unsigned char* buf) {
	// Packet format:
	// SYNC<1> SYNC<1> CLASS<1> ID<1> LENGTH<2> PAYLOAD CHKA<1> CHKB<1>
	// --------------- 4 ----------->|
	// --------------- 6 --------------------->|
	// --------------- 6 + length ---------------------------->|
	// Payload length field is little-endian (bless)
	unsigned short length = buf[5] << 8 | buf[4];
	unsigned char a = 0;
	unsigned char b = 0;
	// We calculate the checksum over the entire packet _except_
	// for the 2 bytes at the beginning and the 2 checksum bytes at
	// the end.
	for (unsigned short i = 2; i < 6 + length; ++i) {
		a += buf[i];
		b += a;
	}
	// Pull out checksum bytes
	unsigned char ra = buf[6 + length];
	unsigned char rb = buf[6 + 1 + length];
	// and compare
	return a = ra && b == rb;
}
//
//

IEEE has C as top Programming Language in 2016

The IEEE reports here that C is the number 1 programming language in 2016. As usual, I am slightly dubious about a lot of these rankings, each one seems to yield a different order. Still you would hope that the IEEE would employ a little more rigour than most! Funny thing is I just don’t see many of these C programmers about… Mind you I know one C programmer who personally outputs about 10 times the amount of code as most…

Friday – Programming in pure unadulterated C Today

Today I have the pleasure in programming in pure & unadulterated C, there is something really refreshing about the clean and minimal elegance of the language and its associated design principles, especially considering the weight of baggage the software engineering discipline has gathered of late – not bad for a rainy Friday!

2*c || !(2*c)

Accuracy of the various Windows software timers

This (admittedly quite old) article provides an interesting comparison of the accuracy of the various software timers available under windows, it looks like the Multimedia timers are still the best despite apparently being frowned upon my Microsoft.

http://omeg.pl/blog/2011/11/on-winapi-timers-and-their-resolution/

I plan to trial camera acquisition using a software trigger, and in order to obtain as accurate and reliable a trigger as possible I want to get as close to a timer interrupt handler as windows will allow, in the hopes that it will be ‘good enough’ for my computer vision application. For a really reliable trigger time-base I normally use a hardware trigger generated by a micro-controller or similar, but this time as the timing constraints aren’t as onerous I have decided to see if I can get away without one, so we will see…. I guess I will have to test the various options and see which is best and if any of them are (generally) within spec..

Good NTP Client Setup Description

As a software engineer (rather than an NTP guru), I find that configuring and debugging an NTP setup can be quite challenging, it is (by its nature) a difficult subject, and a lot of the info out there is quite dense and hard to parse, so I was presently surprised to come across this nice article, called ‘Real Life NTP’ which gives a good overview and describes the use of ntpq -p etc.

https://pthree.org/2013/11/05/real-life-ntp/

Thanks Aaron!

Nice Bootsrap / AngularJS based templates

I was browsing yesterday and came across some nice bootstrap based templates for web app development, especially this one:

http://wrapbootstrap.com/preview/WB04HF123

The nice this is that a version built on AngularJS is available, although I can’t vouch for its build quality not having seen the code…

Templates like these are a great starting point for software developers wishing to put together a web application that doesn’t necessarily look terrible – without the need of one of those GUI guys! Perfect for developing a HMI for an embedded device for example or for developing a cloud application, or even for developing a local app on your PC with Node.js!?

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!