Development of the ocr part of AOI
Samo Penic
2018-11-21 5460bf601a854c842342a740df0f6d36ad785bbc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
3
W¬õ[Úã@stddlZddlZddlmZmZddlZdZeje    eƒZ
dd„Z dd„Z dd    „Z d
d „Zd d „Zdd„Zdd„ZdS)éN)Ú
morphologyÚ img_as_ubytez/template-8.pngcCstj||ftjƒS)z8
    Function greates square kernel of size x and y
    )ÚnpZonesÚuint8)ÚxÚy©rú@/home/samo/programiranje/python/sizif-ocr/aoi_ocr/sid_process.pyÚkernel sr
cCsâ|ddkrd}n|ddkr$d}nd}tj|tjtddƒdd}tj|tjtd    d
ƒd d}t|d kƒ}tjd |ƒtj|jƒtj    tj
ƒ\}}}t |dd„d}    tj |    dƒ\}
} } } || | | …|
d
||
| d…f}|S)NrÚ1é#ré(éé)Ú
iterationséééé2z/tmp/sidblock1.pngcSs
tj|ƒS)N)Úcv2Z contourArea)Úctrrrr    Ú<lambda>%sz#find_biggest_blob.<locals>.<lambda>)Úkeyééÿÿÿÿ) rÚ morphologyExÚ
MORPH_OPENr
Ú MORPH_DILATErÚimwriteÚ findContoursÚcopyÚ RETR_EXTERNALÚCHAIN_APPROX_SIMPLEÚsortedÚ boundingRect)ÚimageÚoriginal_imageÚsid_maskZ    move_leftZimage2Zimage1Úim2ÚctrsÚhierÚ sorted_ctrsrrÚwÚhrrr    Úfind_biggest_blobs"    (r.cCs0x*t||ƒD]\}}|dkr ||kr dSq WdS)zÎ
    Function compares student id number with student id mask if the recognised number is valid according to the mask
    :param sid_no:
    :param sid_mask:
    :return: True if they match, else False
    rFT)Úzip)Úsid_nor'ÚsÚesrrr    Ú sid_compare,sr3cCsòd}t|||ƒ}tjd|ƒtj|jƒtjtjƒ\}}}t|dd„d}x¤t|ƒD]˜\}    }
tj    |
ƒ\} } } }| |dkr‚|d}qR|| | |…| | | …f}t
|dkƒ}tj |dƒ}tjd
j |    ƒ|ƒ|t |j|jd dƒd ƒd ƒ}qRW|S)zæ
    First algorithm. it segments numerals with contours. It works with numbers where individual numerals does not touch.
    :param image:
    :param original_image:
    :param classifier:
    :return: student id as a string
    Úz/tmp/sid_contour1.pngcSstj|ƒdS)Nr)rr$)rrrr    rHsz%segment_by_contours.<locals>.<lambda>)rrr é€é z/tmp/sid_no_{}.pngrgào@r)r6r6r)r.rrrr r!r"r#Ú    enumerater$rÚresizeÚformatÚstrÚpredictÚreshape)r%r&Ú
classifierr'r0r(r)r*r+Úirrrr,r-Úroirrr    Úsegment_by_contours9s"         &r@c CsÆd}t|ƒ}t|||ƒ}tjd|ƒ|jdd…\}}t||ƒ}x~td|ƒD]p}    |dd…|    ||    d|…f}
t|
dkƒ}
tj|
d ƒ}
tjd    j    |    ƒ|
ƒ|t
|j |
j dd ƒd
ƒdƒ}qNW|S) aR
    Third algorithm. It trys to get biggest "blob" in the image and then it cuts it into individual numbers by force.
    It has some problems with finding individual numbers, so some tweaking must be done!
 
    :param image:
    :param original_image:
    :param sid_mask:
    :param classifier:
    :return: student id as a string
    r4z/tmp/sidblock2.pngrrNrr5r6z/tmp/sid_no_{}.pnggào@)r6r6r) Úlenr.rrÚshapeÚintÚrangerr8r9r:r;r<) r%r&r'r=r0Zsid_lenÚ    imgHeightÚimgWidthZnumWidthr>Únumrrr    Úsegment_by_sid_len[s       &rHc CsHtj|tjtddƒdd}t|dkƒ}tjd|ƒtjtdƒ}|jddd…\}}tj    ||tj
ƒ}t j |d    kƒ}    tj |tjƒ}
g} g} xNt|    ddd…ŽD]8} | dd| ddf} | j| dƒ| j| dƒqšWt| ƒdkræd
Sttt| | ƒƒŽ\} } t j| ƒt|dƒk}t j|d ƒ}t j| ƒ} t j| ƒ} | || |g}xBt|ddd…ŽD],} tj|
| | d|| d|fddƒqVWtjd |
ƒd
}x¬tt|ddd…ŽƒD]’\}} || d| d|…| d| d|…f}t|dkƒ}ytj|dƒ}Wn
d
Stjdj|ƒ|ƒ|t|j|jddƒdƒdƒ}q®W|S)aI
    Second attempt. It dilates the image to get all 7 segments wisible as 8888888 then it does pattern matching of 8 with
    pattern image. It works if the scaned gray level is high enough.
 
    :param image:
    :param original_image:
    :param sid_mask:
    :param classifier:
    :return: student id number as a string
    ré
)rrz/tmp/sid_3rd1.pngrNrgè?r4Téÿz/tmp/sid_3rd2.pngr5r6z/tmp/sid_3no_{}.pnggào@rrr)rrJrJr)r6r6r)rrÚ MORPH_CLOSEr
rrÚimreadÚ    template8rBÚ matchTemplateÚTM_CCOEFF_NORMEDrÚwhereÚcvtColorÚCOLOR_GRAY2BGRr/ÚappendrAr#ÚdiffrCÚarrayÚ    rectangler7r8r9r:r;r<)r%r&r'r=Z block_imageÚtemplater,r-ÚresÚlocÚcimgÚloc_filtered_xÚloc_filtered_yÚptÚaÚpointsr0r>rGrrr    Úsegment_by_7segmentsusJ      
 
,  , (r`cCsrg}g}d|}|jƒ}t|dkƒ}tjd|ƒtj|tjtddƒdd}tj|tjtddƒdd}ttj    |d    kƒƒ}tjd
|ƒtj|tj
tddƒdd}tj|tjtd d ƒƒ}ttj |d kƒƒ}tj|tj
td d ƒƒ}tjd |ƒt ||||ƒ}t |ƒt |ƒkst||ƒ r,|jdƒt||||ƒ}t |ƒt |ƒkrVt||||ƒ}|jdƒt||ƒshdg}|||fS)aÔ
    Tries different approaches on image to get student id number. Firstly clears image of noise and then skeletonizes
    numbers and thickens it until it gets normalized image. It sends it to the segmentation and recognition functions.
 
    Tweak both MORPH_OPEN lines....
 
    :param image:
    :param classifier:
    :param sid_mask:
    :return: (student_id, error, warning) student id as a string, list of errors and list of warnings during the recognition
 
    rJéFz/tmp/enSID0.pngrrr)rrr5z/tmp/enSID1.pngrIgà?z/tmp/enhancedSID.pngzTrying second SID algorithm.zTrying third SID algorithm.z
Wrong SID!)r rrrrrKr
rrZthinrZ skeletonizer@rAr3rSr`rH)r%r=r'Zsid_warnZsid_errZimage_originalr0rrr    ÚgetSID­s2      
 
 rb)rÚnumpyrZskimagerrÚ pkg_resourcesZ templatefileÚresource_filenameÚ__name__rMr
r.r3r@rHr`rbrrrr    Ú<module>s  "8