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!