Decoding Seven segment digit images


This was part of my experimenting with detecting the value of digits from a seven-segment display of them. I'd tried using OCR and found it really poor. Instead the idea is to detect the on-segments and deduce what digit is being displayed. I want to be able to read numeric values from cheap consumer items with digital display but no output, like digital luggage scales or audio level-meters.

As long as the camera is in a fixed position, so will the segments be. All you have to do then is to ensure good contrast, and examine a singlepixel in the middle of each segment position. I can call ImageMagick to size the image appropriately, provided the camera and display are in fixed relative positions.

The code shows how I generated the 3-D representation shown above, as part of developing the decoder program. Main thing to remeber is that the data in a BMP file can be in varying formats- I stuck to no-palette, 24 bpp. This means the pixels are stored as BGR triplets. By making sure the width is a multiple of four you know there will be no padding bytes to worry about. And top/bottom left are inverted!

It would probable be better to look at several pixels, and use all three colour's values, not just red, and perhaps calculate a threshold from average of a number of known background, off-segment pixels. In well controlled circumstances it is not necessary.


UpperLeftX   = 10
UpperLeftY   = 10
WindowWidth  =490
WindowHeight =540

graphicbox #w.gb1, 10, 10, 60, 79
graphicbox #w.gb2, 10,100,460,390

open "Examine BMP" for window as #w

#w "trapclose [quit]"
loadbmp "scr", "i8.bmp"
#w.gb1 "down ; drawbmp scr 0 0"
#w.gb2 "down ; fill darkgray"

open "i8.bmp" for binary as #inFile
    bytes$ =input$( #inFile, lof( #inFile))
close #inFile

for y =78 to 0 step -1
    #w.gb2 "up ; goto 10 "; 380 -4 *y; " ; down"
    '#w.gb2 "backcolor "; 256 *y /78; " 0 "; 256 *( 78 -y) /78
    for x =0 to 59
        byte =asc( mid$( bytes$, 54 +3 *( x +60 *y)))
        #w.gb2 "backcolor "; byte; " 0 "; 255 -byte
        if x =25 and y =78 - 7 then #w.gb2 "backcolor white"
        if x =39 and y =78 -19 then #w.gb2 "backcolor white"
        if x =34 and y =78 -47 then #w.gb2 "backcolor white"
        if x =19 and y =78 -62 then #w.gb2 "backcolor white"
        if x = 7 and y =78 -47 then #w.gb2 "backcolor white"
        if x =11 and y =78 -19 then #w.gb2 "backcolor white"
        if x =23 and y =78 -34 then #w.gb2 "backcolor white"
        #w.gb2 "goto ";        20 +y +x *6;    " "; 380 -4 *y
        #w.gb2 "boxfilled ";   20 +y +x *6 +6; " "; 380 -4 *y -byte /4
    next x
next y

#w.gb1 "flush"
#w.gb2 "flush"
close #w

You may want to visit my other pages at Diga Me!