It is currently Sat May 27, 2017 11:41 pm



Welcome
Welcome to rfobasic

You are currently viewing our boards as a guest, which gives you limited access to view most discussions and access our other features. By joining our free community, you will have access to post topics, communicate privately with other members (PM), respond to polls, upload content, and access many other special features. In addition, registered members also see less advertisements. Registration is fast, simple, and absolutely free, so please, join our community today. **You are not required to provide truthful information to any registration questions. Be whomever you wish to be.!


Post new topic Reply to topic  [ 26 posts ]  Go to page Previous  1, 2, 3
Author Message
 Post subject: Re: Image to Text
Unread postPosted: Wed May 10, 2017 9:32 pm 
Offline

Joined: Sat Dec 22, 2012 2:32 pm
Posts: 830
What i have until now, is following your 2nd path(b), i append below. I only focus on the upper left "card" (25 fields with numbers)

I hoped to get around by simply doing a vertical "cut" through the left/right center of each cipher and compare this cut with a reference cut, which i stored for each number. "Compare" means: sum up the difference of each pixel of this "cut" between the reference and the actual cut. So in the end i have ten scalars (0..9) and the minim of this group should represent the hit.

Unfortunately the error-qoute is much to high

- having 24 fields (center-field excluded, sp 5x5-1)
- having 44 ciphers (4 fields contain only one cypher)
- and getting 13 errors (wrong cyphers) ... 13/44 = 30%

At the same time, i'm already close to my "personal limit" of about max 0,5 sec per field....therefore my last post, that i think it will last "too long". Becaus i would expect that you would have to compare much more pixel than i do now. Maybe time will increase to more than 2..3 sec per field ...and in that time one can do the input manually!

Further more i still don't have representative scans, all is based upon a screenshot, i.e. with absolut best alignment conditions...

brochi

Code:
GR.OPEN     255,0,0,0,,1
GR.COLOR    255,0,255,0,0

bmp$      = "bingo_1.png"

GR.BITMAP.LOAD bmp1, bmp$

offx      = 10
offy      = 10

GR.BITMAP.DRAW nn,bmp1,offx,offy


! Find initial corner -------------------
drad = 5
DO
rad += drad
FOR phi=2 TO 88 STEP 2
  phir = TORADIANS(phi)
  px = rad*COS(phir)
  py = rad*SIN(phir)
  GR.GET.BMPIXEL bmp1, px,py,a,r,g,b
  GR.POINT  nn,px+offx,py+offy
  IF r<5 THEN : GR.RENDER : ex=1
  IF ex THEN F_N.BREAK
NEXT
IF ex THEN D_U.BREAK
UNTIL rad >=100

py = ROUND(py)
px = ROUND(px)


!Seach to next two horizontal lines towards "south" ------
FOR i=1 TO 2
py +=10
DO
  GR.GET.BMPIXEL bmp1, px+4,py++,a,r,g,b
UNTIL r<200
NEXT

!Fine-adust left border -----------------
!...just from the hip -> has to be refined !! -------
px +=-2

! now we have the reference-point:lower-left of first number-field
! mark it with two circles ---------
GR.COLOR 255,255,0,0,0
GR.CIRCLE nn, px+offx,py+offy,5
GR.CIRCLE nn, px+offx,py+offy,8
GR.RENDER
!------------------------------------------

!------------------------------------------

!Find next  lines to south --------------
LIST.CREATE   n,lpy
LIST.ADD      lpy, py
FOR i=1 TO 4
pyold= py
py +=10
DO
  GR.GET.BMPIXEL bmp1, px+4,py++,a,r,g,b
UNTIL r<200
LIST.ADD lpy, py
dy += py-pyold
GR.CIRCLE nn, px+offx,py+offy,4
NEXT
! dy is the average y-grid-size --
dy = ROUND(dy/4)
PRINT dy
!------------------------------------------

!Find next  lines to east --------------
LIST.CREATE n,lpx
LIST.ADD lpx, px
FOR i=1 TO 4
pxold= px
px +=10
DO
  GR.GET.BMPIXEL bmp1, px++,py-4,a,r,g,b
UNTIL r<200
LIST.ADD lpx, px
dx += px-pxold
GR.CIRCLE nn, px+offx,py+offy,4
NEXT
! dx is the average x-grid-size --
dx = ROUND(dx/4)
PRINT dx
!------------------------------------------

LIST.TOARRAY lpx,lpx[]
LIST.TOARRAY lpy,lpy[]


ox = offx*15
oy = offy*90


LIST.CREATE     n, charFun
LIST.ADD        charFun,0,0,1,1,1,0
GR.SET.STROKE   5
GR.COLOR        255,0,0,255,0
GR.POLY         nn, charFun, 20,700

LIST.CREATE     n, vals

GOSUB          _data

GR.TEXT.SIZE 40
GR.TEXT.DRAW txt1,ox+70,oy+50,"-"
GR.TEXT.DRAW txt2,ox+105,oy+50,"-"






FOR xx = 1   TO 5
FOR yy = 1   TO 5

  GR.MODIFY txt1,"text","-"
  GR.MODIFY txt2,"text","-"

  gosub crop


  GOSUB  numberCount

  IF !dblNumber THEN

   leStart = 0.28 : reStart = 0.68 : GOSUB findCenter
   GOSUB cut
   GOSUB compare
   GR.MODIFY txt1,"text",INT$(hit)
  ELSE

   leStart = 0.08 : reStart = posMinWeight : GOSUB findCenter
   GOSUB cut
   GOSUB compare
   GR.MODIFY txt1,"text",INT$(hit)

   leStart = posMinWeight : reStart = 0.90 : GOSUB findCenter
   GOSUB cut
   GOSUB compare
   GR.MODIFY txt2,"text",INT$(hit)
  ENDIF

  GR.RENDER
  DO : GR.TOUCH tou,tc,ty: UNTIL tou

NEXT
NEXT




GR.RENDER
DO:UNTIL forever

compare:
LIST.CREATE n,sums
LIST.TOARRAY vals,vals[]
ARRAY.SUM  sum_vals, vals[] : PRINT "sum_vals: "; sum_vals
ARRAY.LENGTH nval, vals[]
!ARRAY.LENGTH n_0, _0[]
!PRINT nval,n_0
FOR i=1 TO nval :sum+=vals[i]-_0 [i]:NEXT:LIST.ADD sums,sum:sum=0
FOR i=1 TO nval :sum+=vals[i]-_1 [i]:NEXT:LIST.ADD sums,sum:sum=0
FOR i=1 TO nval :sum+=vals[i]-_2 [i]:NEXT:LIST.ADD sums,sum:sum=0
FOR i=1 TO nval :sum+=vals[i]-_3 [i]:NEXT:LIST.ADD sums,sum:sum=0
FOR i=1 TO nval :sum+=vals[i]-_4 [i]:NEXT:LIST.ADD sums,sum:sum=0
FOR i=1 TO nval :sum+=vals[i]-_5 [i]:NEXT:LIST.ADD sums,sum:sum=0
FOR i=1 TO nval :sum+=vals[i]-_6 [i]:NEXT:LIST.ADD sums,sum:sum=0
FOR i=1 TO nval :sum+=vals[i]-_7 [i]:NEXT:LIST.ADD sums,sum:sum=0
FOR i=1 TO nval :sum+=vals[i]-_8 [i]:NEXT:LIST.ADD sums,sum:sum=0
FOR i=1 TO nval :sum+=vals[i]-_9 [i]:NEXT:LIST.ADD sums,sum:sum=0
PRINT "----"
minsum=1e20
FOR i=0 TO 9
LIST.GET sums,i+1,tmp
IF ABS(tmp)<minsum THEN minsum=ABS(tmp): hit=i
PRINT INT$(i);" : ";tmp
NEXT
PRINT "hit: "; hit
RETURN



_data:
ARRAY.LOAD _0[], -1.0,0.0,-10.0,-14.0,-192.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,-1.0,-36.0,-111.0,0.0
ARRAY.SUM  sum_0, _0[] % : PRINT "sum_0: "; sum_0

ARRAY.LOAD _1[], -2.0,-2.0,-2.0,0.0,-61.0,-255.0,-255.0,-255.0,-255.0,-255.0,-255.0,-255.0,-255.0,-255.0,-255.0,-255.0,-255.0,-255.0,-158.0,-1.0
ARRAY.SUM  sum_1, _1[] % : PRINT "sum_1: " ; sum_1

ARRAY.LOAD _2[], 0.0,0.0,0.0,0.0,-212.0,-255.0,-255.0,-62.0,-1.0,-1.0,0.0,-42.0,-77.0,-248.0,-73.0,-50.0,-249.0,-253.0,-174.0,0.0
ARRAY.SUM  sum_2, _2[] % : PRINT "sum_2: "; sum_2

ARRAY.LOAD _3[], -4.0,0.0,0.0,-17.0,-255.0,-157.0,-12.0,-1.0,-37.0,-237.0,-255.0,-87.0,-1.0,0.0,-10.0,0.0,-18.0,-255.0,-148.0,0.0
ARRAY.SUM  sum_3, _3[] % : PRINT "sum_3: "; sum_3

ARRAY.LOAD _4[], 0.0,-1.0,-1.0,-2.0,-4.0,-6.0,-20.0,-125.0,-151.0,-19.0,-2.0,-1.0,0.0,-166.0,-255.0,-148.0,-9.0,-4.0,0.0,0.0
ARRAY.SUM  sum_4, _4[] % : PRINT "sum_4: "; sum_4

ARRAY.LOAD _5[], -2.0,-4.0,-3.0,-10.0,-226.0,-255.0,-238.0,-14.0,-71.0,-243.0,-255.0,-255.0,0.0,0.0,0.0,-2.0,-6.0,-122.0,-157.0,-1.0
ARRAY.SUM  sum_5, _5[] % : PRINT "sum_5: "; sum_5

ARRAY.LOAD _6[], 0.0,-1.0,0.0,0.0,-26.0,-186.0,-242.0,-105.0,0.0,-79.0,-117.0,-2.0,-4.0,-8.0,0.0,0.0,-14.0,-49.0,-105.0,0.0
ARRAY.SUM  sum_6, _6[] % : PRINT "sum_6: "; sum_6

ARRAY.LOAD _7[], -2.0,-1.0,0.0,-9.0,-225.0,-255.0,-249.0,-22.0,-5.0,-1.0,0.0,-6.0,-6.0,-106.0,-205.0,-217.0,-255.0,-235.0,-37.0,-2.0
ARRAY.SUM  sum_7, _7[] % : PRINT "sum_7: "; sum_7

ARRAY.LOAD _8[], 0.0,0.0,-2.0,-9.0,-196.0,0.0,0.0,0.0,-7.0,-231.0,-254.0,-255.0,-161.0,0.0,0.0,0.0,-1.0,-39.0,-100.0,-1.0
ARRAY.SUM  sum_8, _8[] % : PRINT "sum_8: "; sum_8

ARRAY.LOAD _9[], -4.0,0.0,-12.0,0.0,-246.0,0.0,0.0,0.0,0.0,0.0,0.0,-31.0,-183.0,-12.0,-9.0,-38.0,-237.0,-88.0,0.0,0.0
ARRAY.SUM  sum_9, _9[] % : PRINT "sum_9: "; sum_9
RETURN




!-----------------------------
crop:
PRINT : PRINT "------  ",xx,yy
  GR.BITMAP.CROP     bmp2,bmp1, lpx[xx], lpy[yy]-dy , dx,dy
  GR.BITMAP.DRAW     nn,bmp2, ox,oy
  GR.RENDER
return
!-----------------------------

!-----------------------------
cut:
LIST.CLEAR charFun
LIST.CLEAR vals
rxdx = center *dx
FOR i=5 TO dy-5 STEP 2
GR.GET.BMPIXEL bmp2, rxdx ,i,  a,r,g,b
LIST.ADD charFun, i*10, -255+r
LIST.ADD  vals, -255+r
out$ += STR$(-255+r)+","
NEXT
CLIPBOARD.PUT out$

UNDIM vals[]
LIST.TOARRAY vals,vals[]

RETURN
!-----------------------------


!-----------------------------
findCenter:
FOR relx = leStart TO 1 STEP 0.01
GOSUB weight : IF weight>500 THEN left = relx : F_N.BREAK
NEXT
FOR relx = reStart TO 0 STEP -0.01
GOSUB weight : IF weight>500 THEN right = relx : F_N.BREAK
NEXT
center = (right- left)/2+left
!PRINT left, right, center
RETURN
!-----------------------------

!-----------------------------
weight:
rxdx = relx *dx
!GR.LINE  nn , ox + rxdx, oy, ox+ rxdx, oy+dy
weight =0
FOR i=5 TO dy-5 STEP 2
GR.GET.BMPIXEL bmp2, rxdx ,i,  a,r,g,b
weight += 255-r
NEXT
%print relx, weight
RETURN
!------------------------------
!------------------------------
numberCount:
minWeight      = 999999
dblNumber    = 0
FOR relx = 0.44 TO 0.56 STEP 0.02
GOSUB weight
IF weight< minWeight THEN minWeight= weight: posMinWeight=relx
NEXT
IF minWeight<300 THEN dblNumber =1
RETURN
!------------------------------



Report this post
Top
 Profile  
 
 Post subject: Re: Image to Text
Unread postPosted: Thu May 11, 2017 4:30 am 
Offline

Joined: Mon Oct 22, 2012 7:32 am
Posts: 139
I found a JavaScript OCR.
There are some docs here: http://antimatter15.com/ocrad.js/demo.html

Dragging the image of the bingo sheet into their system gives me the numbers I need.

I wrote a quick script in BASIC! but for some reason it does not show the same results.
What am I doing wrong?

I submit the following html string in rfo boasic and get nothing back
Code:
image$ = "..\bingo\images\bingocard.bmp"
h$ = "<script src='https://github.com/antimatter15/ocrad.js'></script>"
h$++ "<script>"
h$++ "var string = OCRAD("+image$+");"
h$++ "alert(string);"
h$++ "</script>"


Report this post
Top
 Profile  
 
 Post subject: Re: Image to Text
Unread postPosted: Thu May 11, 2017 7:58 am 
Offline
User avatar

Joined: Wed Jul 10, 2013 8:11 am
Posts: 327
Kokenge,

try

http://antimatter15.com/ocrad.js/ocrad.js

or

https://github.com/antimatter15/ocrad.js/ocrad.js

instead of

https://github.com/antimatter15/ocrad.js



/ Gregor


Report this post
Top
 Profile  
 
 Post subject: Re: Image to Text
Unread postPosted: Fri May 12, 2017 10:20 pm 
Offline

Joined: Sat Dec 22, 2012 2:32 pm
Posts: 830
I found my error....i just had to use the ABS() values while calculating the differences between the 10 compare functions with my actual function. Error-rate is =0% then. So, who wants to proof/test, would just have to replace the relevant part of the "compare" subroutine (see below).

With this i get about 8.5 sec for one card (24fields/44ciphers). Rounding up to 10 sec. for searching of each card, i would guess 1 min per sheet is realistic. But only under this best alignment-conditions....!
(but it seems to be obselet now anyway....just for fun)

brochi




Code:
compare:
LIST.CREATE n,sums
LIST.TOARRAY vals,vals[]
ARRAY.SUM  sum_vals, vals[] : PRINT "sum_vals: "; sum_vals
ARRAY.LENGTH nval, vals[]
!ARRAY.LENGTH n_0, _0[]
!PRINT nval,n_0
FOR i=1 TO nval:sum+=ABS(vals[i]-_0 [i]):NEXT:LIST.ADD sums,sum:sum=0
FOR i=1 TO nval:sum+=ABS(vals[i]-_1 [i]):NEXT:LIST.ADD sums,sum:sum=0
FOR i=1 TO nval:sum+=ABS(vals[i]-_2 [i]):NEXT:LIST.ADD sums,sum:sum=0
FOR i=1 TO nval:sum+=ABS(vals[i]-_3 [i]):NEXT:LIST.ADD sums,sum:sum=0
FOR i=1 TO nval:sum+=ABS(vals[i]-_4 [i]):NEXT:LIST.ADD sums,sum:sum=0
FOR i=1 TO nval:sum+=ABS(vals[i]-_5 [i]):NEXT:LIST.ADD sums,sum:sum=0
FOR i=1 TO nval:sum+=ABS(vals[i]-_6 [i]):NEXT:LIST.ADD sums,sum:sum=0
FOR i=1 TO nval:sum+=ABS(vals[i]-_7 [i]):NEXT:LIST.ADD sums,sum:sum=0
FOR i=1 TO nval:sum+=ABS(vals[i]-_8 [i]):NEXT:LIST.ADD sums,sum:sum=0
FOR i=1 TO nval:sum+=ABS(vals[i]-_9 [i]):NEXT:LIST.ADD sums,sum:sum=0
PRINT "----"
minsum=1e20
FOR i=0 TO 9
LIST.GET sums,i+1,tmp
IF ABS(tmp)<minsum THEN minsum=ABS(tmp): hit=i
PRINT INT$(i);" : ";tmp
NEXT
PRINT "hit: "; hit
RETURN


Report this post
Top
 Profile  
 
 Post subject: Re: Image to Text
Unread postPosted: Sat May 13, 2017 6:47 am 
Offline

Joined: Sat Dec 22, 2012 2:32 pm
Posts: 830
Here also possible solution for detecting/correcting an angular offset (below).
For testing, the bingo-sheet is drawn with an artificial rotation (rotrnd) and this is detected afterwards. Most attempts have accurary of 0.1 degree or better.

- could also easily be used for detecting of 6- or 4- card sheet, simply by the ratio of line-lengthes of red/green
- could be easily enhenced to determine upper left corner (calculation crosspoint of the two lines)

brochi

Code:
GR.OPEN     255,0,0,0,,1
GR.COLOR    255,0,255,0,0

bmp$      = "bingo_1.png"

GR.BITMAP.LOAD bmp0, bmp$


rotRnd = (RND()-0.5)*8
PRINT  ROUND( rotrnd,2)

GR.BITMAP.CREATE     bmp1,800,1200
GR.BITMAP.DRAW    nn,bmp1,0,0

GR.BITMAP.DRAWINTO.START bmp1
GR.COLOR         255,255,255,255,1
GR.RECT          nn, 0,0,800,1200
GR.ROTATE.START  rotRnd , 0,0
GR.BITMAP.DRAW   nn,bmp0, 60,120
GR.ROTATE.END


! Determine angular offset  ------------------
DIM px[4] : DIM py[4]
GR.COLOR 255,255,0,0,1
drad= 25


! left side -------
ex=0 : rad=0 : phis=88 : phie=20 : offsy=0 : _dir = -1
GOSUB search
px[1] = ROUND(px)
py[1] = ROUND(py)
GR.CIRCLE nn, px[1], py[1],8

ex=0 : rad=0 : phis=272 : phie = 320 : offsy=1200 : _dir=1
GOSUB search
px[2] = ROUND(px)
py[2] = ROUND(py)
GR.CIRCLE nn, px[2], py[2],8

GR.SET.STROKE 3
GR.LINE nm, px[1], py[1], px[2], py[2]


! top side --------------
GR.SET.STROKE 1
GR.COLOR 255, 0,255,0

ex=0 : rad=0 : phis=2 : phie = 60 : offsy=0 : _dir = 1
GOSUB search
px[3] = ROUND(px)
py[3] = ROUND(py)
GR.CIRCLE nn, px[3], py[3],8

ex=0 : rad=0 : phis=178 : phie = 120 : offsy=0 : offsx= 800 :_dir = -1
GOSUB search
px[4] = ROUND(px)
py[4] = ROUND(py)
GR.CIRCLE nn, px[4], py[4],8

GR.SET.STROKE 3
GR.LINE nm, px[3], py[3], px[4], py[4]


! ready ---------
rot1    = TODEGREES( ATAN2( py[2]-py[1], px[2]-px[1] ))-90
rot2    = TODEGREES( ATAN2( py[4]-py[3], px[4]-px[3] ))
rotkor  = rotrnd - (rot1+rot2)/2

PRINT     ROUND( rot1,2) , ROUND( rot2,2), ROUND( rotkor,2)

GR.RENDER
DO : GR.TOUCH tou,tc,ty: UNTIL tou



! draw with correction ------------
GR.COLOR         255,255,255,255,1
GR.RECT          nn, 0,0,800,1200

GR.ROTATE.START  rotkor , 0,0
GR.BITMAP.DRAW   nn,bmp0, 12,12
GR.ROTATE.END



GR.RENDER  : pause 500
DO : GR.TOUCH tou,tc,ty: UNTIL tou

END


!-----------------
search : 
DO
rad += drad
FOR phi=phis TO phie STEP _dir*drad/rad*4
  phir = TORADIANS(phi)
  px = rad*COS(phir) + offsx
  py = rad*SIN(phir) + offsy
  GR.GET.BMPIXEL bmp1, px,py,a,r,g,b
  GR.POINT  nn,px,py
  IF r<128 THEN ex=1 : F_N.BREAK
NEXT
GR.RENDER
UNTIL ex
RETURN
!--------------


Report this post
Top
 Profile  
 
 Post subject: Re: Image to Text
Unread postPosted: Sun May 14, 2017 12:56 pm 
Offline

Joined: Mon Oct 22, 2012 7:32 am
Posts: 139
Thank you brochi..
You've been a great help..

I'm still trying to understand your code. I like the idea of doing it native in BASIC!
I wrote code to do something similar. I defined a standard number array with each number being a set of pixels of 5 X 8.
I requested the number of boards across and down. Knowing the height and width of the image and the number of bingo boards across and down, I found those x y blocks for each square. Then I compared that block to the standard defined 5 x 8 array. It added the hits equal to the standard array and the max hits would give you the possible number.

It is interesting!!


Report this post
Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 26 posts ]  Go to page Previous  1, 2, 3


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
suspicion-preferred