It would be better to take a bigger sample area and average, and even better to do auto-contrast enhancement. All do-able, but it works well enough for me.
' ****************************************
' ** **
' ** SevenSegment6.bas **
' ** **
' ** Jan 2013 tenochtitlanuk **
' ****************************************
nomainwin
global h1DC
WindowWidth = 650
WindowHeight = 360
graphicbox #w.gb1, 10, 10, 620, 106
textbox #w.tb1, 10,150, 620, 30
textbox #w.tb2, 10,190, 620, 60
open "Decode Seven Segment Display" for window as #w
#w "trapclose [quit]"
#w.gb1 "down"
loadbmp "dvm", "7Seg5.bmp"
#w.gb1 "drawbmp dvm 0 0 ; flush ; color red ; size 4"
#w.tb1 "!font courier_new bold 7"
#w.tb2 "!font courier_new bold 24"
#w.tb2 " Displaying 7-segment image"
handlegb1 =hwnd( #w.gb1)
calldll #user32, "GetDC", handlegb1 as ulong, h1DC as ulong
horizSepn =62.55
display$ =""
greyLevel =140
SevenSeg$ =""
timer 5000, [onward]
wait
[onward]
timer 0
for xPos =0 to 9 ' find value at this posn as integer 0 -->9
getValue =0: state$ =""
if getPixelGreyVal( horizSepn *xPos +32, 13) <greyLevel then state$ ="0" else state$ ="1"
#w.gb1 "set "; horizSepn *xPos +32; " "; 13
if getPixelGreyVal( horizSepn *xPos +47, 28) <greyLevel then state$ =state$ +"0" else state$ =state$ +"1"
#w.gb1 "set "; horizSepn *xPos +47; " "; 28
if getPixelGreyVal( horizSepn *xPos +42, 74) <greyLevel then state$ =state$ +"0" else state$ =state$ +"1"
#w.gb1 "set "; horizSepn *xPos +42; " "; 74
if getPixelGreyVal( horizSepn *xPos +23, 92) <greyLevel then state$ =state$ +"0" else state$ =state$ +"1"
#w.gb1 "set "; horizSepn *xPos +23; " "; 92
if getPixelGreyVal( horizSepn *xPos + 8, 72) <greyLevel then state$ =state$ +"0" else state$ =state$ +"1"
#w.gb1 "set "; horizSepn *xPos + 8; " "; 72
if getPixelGreyVal( horizSepn *xPos +14, 30) <greyLevel then state$ =state$ +"0" else state$ =state$ +"1"
#w.gb1 "set "; horizSepn *xPos +14; " "; 30
if getPixelGreyVal( horizSepn *xPos +27, 51) <greyLevel then state$ =state$ +"0" else state$ =state$ +"1"
#w.gb1 "set "; horizSepn *xPos +27; " "; 51
select case state$
case "1111110"
it =0
case "0110000"
it =1
case "1101101"
it =2
case "1111001"
it =3
case "0110011"
it =4
case "1011011"
it =5
case "1011111"
it =6
case "1110001"
it =7
case "1111111"
it =8
case "1110011"
it =9
case else
it =-999
end select
if it =-999 then display$ =display$ +"_" else display$ =display$ +str$( it)
SevenSeg$ =SevenSeg$ +state$+ " "+str$( it) +" "
next xPos
#w.gb1 "flush"
#w.tb1 SevenSeg$
#w.tb2 " Detected display was "; display$
wait
function getPixelGreyVal( x, y) ' return mean grey value, unweighted.
x =int( x)
y =int( y)
calldll #gdi32, "GetPixel", h1DC as ulong, x as long, y as long, pixcol as ulong
if pixcol >2^24 then notice str$( x) +" " +str$( y) +"Whoops!!": end
bl = int( pixcol /( 256*256))
gr = int( (pixcol -bl *256*256) / 256)
re = int( pixcol -bl *256*256 - gr *256)
getPixelGreyVal =( re +bl +gr) /3
end function
[quit]
callDll #user32, "ReleaseDC", handlegb1 as ulong, h1DC as ulong, result as ushort
close #w
end
function getPixelRGB$( x, y) ' return the three RGB components as a string.
calldll #gdi32, "GetPixel", h1DC as ulong, x as long, y as long, pixcol as ulong
bl = int( pixcol /( 256*256))
gr = int( (pixcol -bl *256*256) / 256)
re = int( pixcol -bl *256*256 - gr *256)
getPixelRGB$ =str$( re) +" " +str$( gr) +" " +str$( bl)
end function
This is certainly not the only way to do it. Convolution or OCR would be more universal. But it seemed a natural follow on from my early microcomputer days, when turning a screen pixel off or on could control external devices via a photodiode!