Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
E
erp5-archive
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
erp5-archive
Commits
392e5268
Commit
392e5268
authored
May 15, 2024
by
Jérome Perrin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
erp5_receipt_recognition: archived from erp5.git ( 1e1df305 )
parent
b0a1f5ca
Changes
36
Hide whitespace changes
Inline
Side-by-side
Showing
36 changed files
with
1997 additions
and
0 deletions
+1997
-0
bt5/erp5_receipt_recognition/ActionTemplateItem/portal_types/Receipt%20Recognition%20Module/view.xml
...Item/portal_types/Receipt%20Recognition%20Module/view.xml
+83
-0
bt5/erp5_receipt_recognition/ActionTemplateItem/portal_types/Receipt%20Recognition/receipt_convert.xml
...em/portal_types/Receipt%20Recognition/receipt_convert.xml
+85
-0
bt5/erp5_receipt_recognition/ActionTemplateItem/portal_types/Receipt%20Recognition/view.xml
...nTemplateItem/portal_types/Receipt%20Recognition/view.xml
+85
-0
bt5/erp5_receipt_recognition/ExtensionTemplateItem/portal_components/extension.erp5.ReceiptRecognition.py
...em/portal_components/extension.erp5.ReceiptRecognition.py
+480
-0
bt5/erp5_receipt_recognition/ExtensionTemplateItem/portal_components/extension.erp5.ReceiptRecognition.xml
...m/portal_components/extension.erp5.ReceiptRecognition.xml
+127
-0
bt5/erp5_receipt_recognition/ModuleTemplateItem/receipt_recognition_module.xml
...gnition/ModuleTemplateItem/receipt_recognition_module.xml
+96
-0
bt5/erp5_receipt_recognition/PortalTypeAllowedContentTypeTemplateItem/allowed_content_types.xml
...eAllowedContentTypeTemplateItem/allowed_content_types.xml
+5
-0
bt5/erp5_receipt_recognition/PortalTypeBaseCategoryTemplateItem/base_category_list.xml
...PortalTypeBaseCategoryTemplateItem/base_category_list.xml
+5
-0
bt5/erp5_receipt_recognition/PortalTypePropertySheetTemplateItem/property_sheet_list.xml
...rtalTypePropertySheetTemplateItem/property_sheet_list.xml
+5
-0
bt5/erp5_receipt_recognition/PortalTypeTemplateItem/portal_types/Receipt%20Recognition%20Module.xml
...plateItem/portal_types/Receipt%20Recognition%20Module.xml
+151
-0
bt5/erp5_receipt_recognition/PortalTypeTemplateItem/portal_types/Receipt%20Recognition.xml
...alTypeTemplateItem/portal_types/Receipt%20Recognition.xml
+73
-0
bt5/erp5_receipt_recognition/SkinTemplateItem/portal_skins/erp5_receipt_recognition.xml
...kinTemplateItem/portal_skins/erp5_receipt_recognition.xml
+26
-0
bt5/erp5_receipt_recognition/SkinTemplateItem/portal_skins/erp5_receipt_recognition/ReceiptRecognitionModule_viewReceiptRecognitionList.xml
...n/ReceiptRecognitionModule_viewReceiptRecognitionList.xml
+131
-0
bt5/erp5_receipt_recognition/SkinTemplateItem/portal_skins/erp5_receipt_recognition/ReceiptRecognitionModule_viewReceiptRecognitionList/listbox.xml
...tRecognitionModule_viewReceiptRecognitionList/listbox.xml
+122
-0
bt5/erp5_receipt_recognition/SkinTemplateItem/portal_skins/erp5_receipt_recognition/ReceiptRecognition_convertImage.py
...p5_receipt_recognition/ReceiptRecognition_convertImage.py
+18
-0
bt5/erp5_receipt_recognition/SkinTemplateItem/portal_skins/erp5_receipt_recognition/ReceiptRecognition_convertImage.xml
...5_receipt_recognition/ReceiptRecognition_convertImage.xml
+62
-0
bt5/erp5_receipt_recognition/SkinTemplateItem/portal_skins/erp5_receipt_recognition/ReceiptRecognition_getReceiptValue.xml
...eceipt_recognition/ReceiptRecognition_getReceiptValue.xml
+28
-0
bt5/erp5_receipt_recognition/SkinTemplateItem/portal_skins/erp5_receipt_recognition/ReceiptRecognition_view.xml
...kins/erp5_receipt_recognition/ReceiptRecognition_view.xml
+133
-0
bt5/erp5_receipt_recognition/SkinTemplateItem/portal_skins/erp5_receipt_recognition/ReceiptRecognition_view/my_follow_up_title.xml
...ecognition/ReceiptRecognition_view/my_follow_up_title.xml
+96
-0
bt5/erp5_receipt_recognition/SkinTemplateItem/portal_skins/erp5_receipt_recognition/ReceiptRecognition_view/my_title.xml
..._receipt_recognition/ReceiptRecognition_view/my_title.xml
+84
-0
bt5/erp5_receipt_recognition/SkinTemplateItem/portal_skins/erp5_receipt_recognition/ReceiptRecognition_view/my_total.xml
..._receipt_recognition/ReceiptRecognition_view/my_total.xml
+84
-0
bt5/erp5_receipt_recognition/bt/dependency_list
bt5/erp5_receipt_recognition/bt/dependency_list
+1
-0
bt5/erp5_receipt_recognition/bt/license
bt5/erp5_receipt_recognition/bt/license
+1
-0
bt5/erp5_receipt_recognition/bt/skip_coding_style_test
bt5/erp5_receipt_recognition/bt/skip_coding_style_test
+1
-0
bt5/erp5_receipt_recognition/bt/template_action_path_list
bt5/erp5_receipt_recognition/bt/template_action_path_list
+3
-0
bt5/erp5_receipt_recognition/bt/template_extension_id_list
bt5/erp5_receipt_recognition/bt/template_extension_id_list
+1
-0
bt5/erp5_receipt_recognition/bt/template_format_version
bt5/erp5_receipt_recognition/bt/template_format_version
+1
-0
bt5/erp5_receipt_recognition/bt/template_module_id_list
bt5/erp5_receipt_recognition/bt/template_module_id_list
+1
-0
bt5/erp5_receipt_recognition/bt/template_portal_type_allowed_content_type_list
...gnition/bt/template_portal_type_allowed_content_type_list
+1
-0
bt5/erp5_receipt_recognition/bt/template_portal_type_base_category_list
...pt_recognition/bt/template_portal_type_base_category_list
+1
-0
bt5/erp5_receipt_recognition/bt/template_portal_type_id_list
bt5/erp5_receipt_recognition/bt/template_portal_type_id_list
+2
-0
bt5/erp5_receipt_recognition/bt/template_portal_type_property_sheet_list
...t_recognition/bt/template_portal_type_property_sheet_list
+1
-0
bt5/erp5_receipt_recognition/bt/template_skin_id_list
bt5/erp5_receipt_recognition/bt/template_skin_id_list
+1
-0
bt5/erp5_receipt_recognition/bt/test_dependency_list
bt5/erp5_receipt_recognition/bt/test_dependency_list
+1
-0
bt5/erp5_receipt_recognition/bt/title
bt5/erp5_receipt_recognition/bt/title
+1
-0
bt5/erp5_receipt_recognition/bt/version
bt5/erp5_receipt_recognition/bt/version
+1
-0
No files found.
bt5/erp5_receipt_recognition/ActionTemplateItem/portal_types/Receipt%20Recognition%20Module/view.xml
0 → 100644
View file @
392e5268
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ActionInformation"
module=
"Products.CMFCore.ActionInformation"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
action
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
categories
</string>
</key>
<value>
<tuple>
<string>
action_type/object_list
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
category
</string>
</key>
<value>
<string>
object_list
</string>
</value>
</item>
<item>
<key>
<string>
condition
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
icon
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
view
</string>
</value>
</item>
<item>
<key>
<string>
permissions
</string>
</key>
<value>
<tuple>
<string>
View
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Action Information
</string>
</value>
</item>
<item>
<key>
<string>
priority
</string>
</key>
<value>
<float>
1.0
</float>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
View
</string>
</value>
</item>
<item>
<key>
<string>
visible
</string>
</key>
<value>
<int>
1
</int>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"Expression"
module=
"Products.CMFCore.Expression"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
text
</string>
</key>
<value>
<string>
string:${object_url}/ReceiptRecognitionModule_viewReceiptRecognitionList
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_receipt_recognition/ActionTemplateItem/portal_types/Receipt%20Recognition/receipt_convert.xml
0 → 100644
View file @
392e5268
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ActionInformation"
module=
"Products.CMFCore.ActionInformation"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
action
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
categories
</string>
</key>
<value>
<tuple>
<string>
action_type/object_action
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
category
</string>
</key>
<value>
<string>
object_action
</string>
</value>
</item>
<item>
<key>
<string>
condition
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
icon
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
receipt_convert
</string>
</value>
</item>
<item>
<key>
<string>
permissions
</string>
</key>
<value>
<tuple>
<string>
Modify portal content
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Action Information
</string>
</value>
</item>
<item>
<key>
<string>
priority
</string>
</key>
<value>
<float>
1.0
</float>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
Convert Receipt
</string>
</value>
</item>
<item>
<key>
<string>
visible
</string>
</key>
<value>
<int>
1
</int>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"Expression"
module=
"Products.CMFCore.Expression"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
text
</string>
</key>
<value>
<string>
string:${object_url}/ReceiptRecognition_convertImage
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_receipt_recognition/ActionTemplateItem/portal_types/Receipt%20Recognition/view.xml
0 → 100644
View file @
392e5268
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ActionInformation"
module=
"Products.CMFCore.ActionInformation"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
action
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
categories
</string>
</key>
<value>
<tuple>
<string>
action_type/object_view
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
category
</string>
</key>
<value>
<string>
object_view
</string>
</value>
</item>
<item>
<key>
<string>
condition
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
icon
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
view
</string>
</value>
</item>
<item>
<key>
<string>
permissions
</string>
</key>
<value>
<tuple>
<string>
View
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Action Information
</string>
</value>
</item>
<item>
<key>
<string>
priority
</string>
</key>
<value>
<float>
1.0
</float>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
View
</string>
</value>
</item>
<item>
<key>
<string>
visible
</string>
</key>
<value>
<int>
1
</int>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"Expression"
module=
"Products.CMFCore.Expression"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
text
</string>
</key>
<value>
<string>
string:${object_url}/ReceiptRecognition_view
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_receipt_recognition/ExtensionTemplateItem/portal_components/extension.erp5.ReceiptRecognition.py
0 → 100644
View file @
392e5268
# -*- coding: utf-8 -*-
"""
Extension to find receipts inside images.
Most of the functions is code from ocropy binaries modified
to work inside erp5 and adapt to receipt binaries and with more
explanation
https://github.com/tmbdev/ocropy
"""
# pylint: disable=unpacking-non-sequence
# Pylint is confused by ocropy.
import
numpy
as
np
import
scipy.ndimage
as
ndi
import
StringIO
from
matplotlib
import
pylab
import
matplotlib.image
as
mpimg
import
scipy.stats
as
stats
import
re
import
cPickle
import
ocrolib
def
getReceiptValue
(
self
,
image_data
,
model_name
=
"en-default.pyrnn"
):
"""
Function called from an erp5 script through externalMethod
that take an image and its name and save its binarized
version in the image portal.
----------------------------
@args:
- self: object
Represent the erp5 object from which externalmethods or module
objects can be called
- image_data:
Representation of the image to analyse
@return:
- anon: float
Represent total value paid on the receipt
----------------------------
This function look for euros only and return a price with a two digit
precison like "135.79" or "43,89".
"""
image_as_string
=
StringIO
.
StringIO
(
image_data
)
image_as_array
=
mpimg
.
imread
(
image_as_string
,
format
=
'JPG'
)
line_list
,
cleared
=
getLinesFromPicture
(
image_as_array
)
# Start the neural network
network
,
lnorm
=
initRnnModel
(
model_name
)
return
findReceiptValue
(
line_list
,
cleared
,
network
,
lnorm
)
def
findReceiptValue
(
line_list
,
cleared
,
network
,
lnorm
):
"""
Function that run the neural network through the receipt and extract
meaningfull value
-----------------------------
@args:
- lines: array list
Represent lines of text that will be extracted
from the image
- cleared:2D array
Represent binarized image cropped and cleaned,
from which we will extract text lines
- network: lstm object
Represent the trained neural net
- lnorm: method from lstm object
Represent the size of the lstm object. Is used to scale the objects
to recognize from original size to the average network object.
@return:
- anon: float
Represent total value paid on the receipt
-----------------------------
This function can bemodified to add more field to detect. It might be
possible to run a classification neural net on the result.
"""
value_list
=
[]
tofind
=
r"(EUR)|€|(TOT)"
for
_
,
line
in
enumerate
(
line_list
):
binline
=
ocrolib
.
extract_masked
(
1
-
cleared
,
line
,
3
,
3
)
# Corner case: he dewarping function from the normalizer fail
# sometimes on empty lines. Can be corrected with better segmentation
try
:
evaluate
=
getStringFromImage
(
binline
,
lnorm
,
network
)
if
re
.
search
(
tofind
,
evaluate
.
upper
()):
number
=
re
.
findall
(
r"\
d+[
\.|,]\
d
\d"
,
evaluate
)
value_list
+=
[
float
(
char
.
replace
(
','
,
'.'
))
for
char
in
number
]
except
ValueError
:
pass
return
round
(
max
(
value_list
),
2
)
def
getRnnModelFromDataStream
(
self
,
model_name
=
"en-default.pyrnn"
):
"""
This function load a neural network from a dataStream
----------------------------
@args:
- model_name: string, default: en-default.pyrnn
Id of the object in data_stream_module that contain the rnn model
@return:
- network: lstm object
Represent the trained neural net
- lnorm: method from lstm object
Represent the size of the lstm object. Is used to scale the objects
to recognize from original size to the average network object.
----------------------------
WARNING: This function present a security issue and should NOT be called with
an user-defined model name (see cpickle security issue)
"""
network
=
cPickle
.
loads
(
self
.
data_stream_module
[
model_name
].
getData
())
lnorm
=
getattr
(
network
,
"lnorm"
,
None
)
return
network
,
lnorm
def
initRnnModel
(
model_name
=
"en-default.pyrnn"
):
"""
This function load the neural network model from slapos backend
and initialise it.
----------------------------
@args:
- model_name: string, default: en-default.pyrnn
Id of the object in the filesystem that contain the rnn model
@return:
- network: lstm object
Represent the trained neural net
- lnorm: method from lstm object
Represent the size of the lstm object. Is used to scale the objects
to recognize from original size to the average network object.
----------------------------
LSTM meaning: https://en.wikipedia.org/wiki/Long_short-term_memory
lnorm is extracted for clarity. This function initialize the neural net after
loading.
"""
network
=
ocrolib
.
load_object
(
model_name
)
for
node
in
network
.
walk
():
if
isinstance
(
node
,
ocrolib
.
lstm
.
LSTM
):
node
.
allocate
(
5000
)
lnorm
=
getattr
(
network
,
"lnorm"
,
None
)
return
network
,
lnorm
def
getLinesFromPicture
(
image_as_array
):
"""
Function that take an colorized image in argument and return a
cleared binarized image and a list of lines
----------------------------
@args:
- image_as_array: 3d array
Represent a colored image
@return:
- lines: array list
Represent lines of text that will be extracted
from the image
- cleared:2D array
Represent binarized image cropped and cleaned,
from which we will extract text lines
----------------------------
This function find the text position of text line in an image
The neural network recognition only works on independant lines
of a binarized image.
Could be improved by making this function return each line as
independant picture
"""
grey_image
=
convertGreyscale
(
image_as_array
)
cropped_image
=
cropImage
(
grey_image
)
binarized_image
=
imageBinarization
(
cropped_image
)
binary
=
1
-
binarized_image
cleaned
,
scale
=
removeObjects
(
binary
)
angle
=
getEstimatedSkewAngle
(
cleaned
,
np
.
linspace
(
-
4
,
4
,
24
))
cleaned
=
ndi
.
interpolation
.
rotate
(
cleaned
,
angle
,
mode
=
'constant'
,
reshape
=
0
)
segmentation
=
getSegmentizedImage
(
cleaned
,
scale
)
# Sort the labels from top to bottom
line_list
=
ocrolib
.
compute_lines
(
segmentation
,
scale
)
order
=
ocrolib
.
reading_order
([
line
.
bounds
for
line
in
line_list
])
sorted_lines
=
ocrolib
.
topsort
(
order
)
# Renumber the labels with growing values
total_labels
=
np
.
amax
(
segmentation
)
+
1
renumber
=
np
.
zeros
(
total_labels
,
'i'
)
for
i
,
line
in
enumerate
(
sorted_lines
):
renumber
[
line_list
[
line
].
label
]
=
0x010000
+
(
i
+
1
)
segmentation
=
renumber
[
segmentation
]
line_list
=
[
line_list
[
i
]
for
i
in
sorted_lines
]
return
line_list
,
cleaned
def
getStringFromImage
(
image
,
lnorm
,
network
):
"""
Function that use a neural network to get a string of character from
an image that contain a line of text
------------------------------------
@args:
- image: 2D array
Represent a binarized image that contain a line of text
- lnorm: norm attribute of the neural network
Used to scale the letters from the image to the text of the
neural network
- network: neural network
Used to predict text
@return:
- pred: string
Text extracted from image
------------------------------------
Getting the text of each line allow the neural network not to be confused
with noise.
"""
temp
=
np
.
amax
(
image
)
-
image
temp
=
temp
*
1.0
/
np
.
amax
(
temp
)
lnorm
.
measure
(
temp
)
image
=
lnorm
.
normalize
(
image
,
cval
=
np
.
amax
(
image
))
image
=
ocrolib
.
lstm
.
prepare_line
(
image
,
16
)
return
network
.
predictString
(
image
)
def
getLineSeed
(
binary
,
scale
,
bottom
,
top
):
"""
Function that find "line seeds" inside a binarized image. The line
seeds are multiple boxes that surround text in a picture.
--------------------------------------
@args:
- binary: 2D array
Represent the image from which line seed will be extracted
- scale: double
Represent the size of the average object
- bottom: 2D array
Represent the bottom boundary of line seeds
- top: 2D array
Represent the top boundary of line seeds
--------------------------------------
The line seeds act as a "mask" that isolate lines from each other
to allow segmentation
"""
# Use scale as a int
vrange
=
int
(
scale
)
threshold
=
0.1
# Find the bottom boundary
bmarked
=
ndi
.
maximum_filter
(
bottom
==
ndi
.
maximum_filter
(
bottom
,
(
vrange
,
0
)),
(
2
,
2
))
bmarked
=
bmarked
*
(
bottom
>
threshold
*
np
.
amax
(
bottom
)
*
threshold
)
# Find the top boundary
tmarked
=
ndi
.
maximum_filter
(
top
==
ndi
.
maximum_filter
(
top
,(
vrange
,
0
)),
(
2
,
2
))
tmarked
=
tmarked
*
(
top
>
threshold
*
np
.
amax
(
top
)
*
threshold
/
2
)
tmarked
=
ndi
.
maximum_filter
(
tmarked
,
(
1
,
20
))
# Create seeds
seeds
=
np
.
zeros
(
binary
.
shape
,
'i'
)
line_spacing
=
vrange
/
2
for
x
in
range
(
bmarked
.
shape
[
1
]):
transitions
=
sorted
([(
y
,
1
)
for
y
in
pylab
.
find
(
bmarked
[
:
,
x
])]
\
+
[(
y
,
0
)
for
y
in
pylab
.
find
(
tmarked
[
:
,
x
])])[::
-
1
]
transitions
+=
[(
0
,
0
)]
for
i
in
range
(
len
(
transitions
)
-
1
):
y0
,
s0
=
transitions
[
i
]
if
s0
==
0
:
continue
seeds
[
y0
-
line_spacing
:
y0
,
x
]
=
1
y1
,
s1
=
transitions
[
i
+
1
]
if
s1
==
0
and
(
y0
-
y1
)
<
5
*
scale
:
seeds
[
y1
:
y0
,
x
]
=
1
return
ndi
.
maximum_filter
(
seeds
,
(
1
,
vrange
))
def
getSegmentizedImage
(
binary
,
scale
):
"""
Function that give every pixel of every text character on a same line
the same value so it can be easily separated latter
This function find the upper and lower boundaries of text lines with
a filter using the first derivative of gaussian kernel to get
horizontal change of intensity and stretching it
----------------------------
@args:
binary: 2D array
Represent a clean, straight binarized image from witch we will
find the seeds
scale: double
Represent the size of the mean object
@return:
segmentation: 2D array
Represent a picture with different pixel value for each line
of text.
----------------------------
The segmentization give us independant text lines. Rotating the
picture to make lines more straight could improve result.
Some args could be added to play on the stretching of the blur or
the threeshold for finding the mask boundaries
"""
boxmap
=
ocrolib
.
compute_boxmap
(
binary
,
scale
,
threshold
=
(.
25
,
4
))
cleaned_image
=
boxmap
*
binary
# Finding horizontals gradient
gradient
=
ndi
.
gaussian_filter
(
1.0
*
cleaned_image
,
(
0.5
*
scale
,
scale
*
6
),
order
=
(
1
,
0
))
gradient
=
ndi
.
uniform_filter
(
gradient
,(
1
,
20
))
# Find the bottom (whiter) and top (darker) zones from grad
bottom
=
ocrolib
.
norm_max
((
gradient
<
0
)
*
(
-
gradient
))
top
=
ocrolib
.
norm_max
((
gradient
>
0
)
*
gradient
)
seeds
=
getLineSeed
(
cleaned_image
,
scale
,
bottom
,
top
)
# Label the seeds then group them by line inside boxmaps
seeds
,
_
=
ocrolib
.
morph
.
label
(
seeds
)
labels
=
ocrolib
.
morph
.
propagate_labels
(
boxmap
,
seeds
,
conflict
=
1
)
spread
=
ocrolib
.
morph
.
spread_labels
(
seeds
,
maxdist
=
(
scale
/
4
))
labels
=
np
.
where
(
labels
>
0
,
labels
,
spread
*
binary
)
return
labels
*
binary
def
removeObjects
(
binarized
):
"""
This function identify objects as contigunious spot of white on a
black image and remove the bigger and smaller ones.
---------------------------
@args:
binarized: 2D array
Represent the inversed color binarized picture from which
objects bigger than the mean will be taken from.
@return:
binarized: 2D array
"cleaned" array
scale: double
Represent the size of the mean object
---------------------------
This function improve line detection and "clean" the image.
A coefficient could be added to the function to change the value of
height and width of the deleted object, or to choose only horizontal
or vertical objects.
"""
labels
,
n
=
ocrolib
.
morph
.
label
(
binarized
)
objects
=
ocrolib
.
morph
.
find_objects
(
labels
)
# Calculate the median of all objects
bysize
=
sorted
(
objects
,
key
=
ocrolib
.
sl
.
area
)
scalemap
=
np
.
zeros
(
binarized
.
shape
)
for
sub_object
in
bysize
:
if
np
.
amax
(
scalemap
[
sub_object
])
>
0
:
continue
scalemap
[
sub_object
]
=
ocrolib
.
sl
.
area
(
sub_object
)
**
0.5
scale
=
ndi
.
median
(
scalemap
[(
scalemap
>
3
)
&
(
scalemap
<
100
)])
# Take the mesurement of small objects
sums
=
ndi
.
measurements
.
sum
(
binarized
,
labels
,
range
(
n
+
1
))
sums
=
sums
[
labels
]
# Find all objects and remove big ones
for
i
,
b
in
enumerate
(
objects
):
if
(
ocrolib
.
sl
.
width
(
b
)
>
scale
*
8
)
\
or
(
ocrolib
.
sl
.
height
(
b
)
>
scale
*
8
):
labels
[
b
][
labels
[
b
]
==
i
+
1
]
=
0
# Recreate an array without big objects
binarized
=
np
.
array
(
labels
!=
0
,
'B'
)
# Remove small objects from this image
binarized
=
np
.
minimum
(
binarized
,
1
-
(
sums
>
0
)
*
(
sums
<
scale
))
return
binarized
,
scale
def
getEstimatedSkewAngle
(
image
,
angle_list
):
"""
Function that estimate at which angle the image is the most
straight
-------------------------------
@args:
- image: 2d array
Represent the greyscale original image
- angle_list: float list
Represent the list of angles that will be tested in the
function
@return:
a: float
Represent the value of the angle (in degrees) for which the
image is the less skew
-------------------------------
This function is needed to get a better segmentation (since the
segmentation is done horizontally). It calculate the mean of each
line in the picture then calculate the variance, and return the
angle value for which the variance is the highest.
"""
estimates
=
[]
for
angle
in
angle_list
:
mean
=
np
.
mean
(
ndi
.
interpolation
.
rotate
(
image
,
angle
,
order
=
0
,
mode
=
'constant'
),
axis
=
1
)
variance
=
np
.
var
(
mean
)
estimates
.
append
((
variance
,
angle
))
_
,
angle
=
max
(
estimates
)
return
angle
def
removeBackground
(
image
,
percentile
=
50
):
"""
Function that help flatten the image by estimating locals
whitelevels. This remove local extremes and give an image with
homogenous background and no details
------------------------------
@args:
- image: 2D array
Represent a greyscale image
- percentile: integer between -100 and 100
A percentile filter with a value of 50 is basically a
median filter, value of 0 is a minimum filter and with
a value of 100 a maximum filter
@return:
- 2D array
Represent a greyscale image with no local extreme
------------------------------
The filter result will be substracted from the original image
to make that only local extremes stand out.
A Kuwahara filter might give better results.
"""
# Reduce extreme differences in the greyscale image
image
=
image
-
pylab
.
amin
(
image
)
image
/=
pylab
.
amax
(
image
)
white_image
=
ndi
.
filters
.
percentile_filter
(
image
,
percentile
,
size
=
(
80
,
2
))
white_image
=
ndi
.
filters
.
percentile_filter
(
white_image
,
percentile
,
size
=
(
2
,
80
))
# Get the difference between the whiteleveled image and the
# original one and put them betewwn 0 an 1
return
np
.
clip
(
image
-
white_image
+
1
,
0
,
1
)
def
cropImage
(
image
):
"""
Function that perform cropping and flattening -- Removing
homogenous background and small extremes-- on an image.
-------------------------------
@args:
grey: 2D array
Represent the original greyscale image
@return:
flat: 2D array
Represent the original image cropped and flattened
-------------------------------
This function reduce the size of the image and clear noise from
homogenous background
"""
# Reduce extreme differences in the greyscale image
white_image
=
removeBackground
(
image
)
# Calculate coordinate to crop the image, can be done in another
# function to improve readability
mask
=
ndi
.
gaussian_filter
(
white_image
,
7.0
)
<
0.9
*
np
.
amax
(
white_image
)
coords
=
np
.
argwhere
(
mask
)
# Bounding box of kept pixels.
x_min
,
y_min
=
coords
.
min
(
axis
=
0
)
x_max
,
y_max
=
coords
.
max
(
axis
=
0
)
return
white_image
[
x_min
-
10
:
x_max
+
10
,
y_min
-
10
:
y_max
+
10
]
def
imageBinarization
(
flattened_image
):
"""
Fontion that take a flattened image and binarize it to make OCR
easier
-------------------------------
@args:
- flattened_image: 2D array
Represent a greyscale image
@return:
- binarized_image: 2D array
Represent a binarized image
-------------------------------
Binarized image is needed to get text boundaries and make text
easier to distinguish from background.
"""
gaussian_image
=
ndi
.
gaussian_filter
(
flattened_image
,
1
)
# Applying a Gaussian filter with a small sigma and substracting
# it from the "original" image allow to do an approximation of
# Laplacian.
blurred_gaussian
=
ndi
.
gaussian_filter
(
gaussian_image
,
3
)
# Add the scaled Laplacian to the smoothed image to sharpen its edges
sharpened
=
1.5
*
gaussian_image
-
blurred_gaussian
# Estimate low and high threshold
low
=
stats
.
scoreatpercentile
(
sharpened
.
ravel
(),
5
)
high
=
stats
.
scoreatpercentile
(
sharpened
.
ravel
(),
70
)
# rescale the image to enhance differences
sharpened
=
(
sharpened
-
low
)
/
(
high
-
low
)
sharpened
=
np
.
clip
(
sharpened
,
0
,
1
)
# Binarization
return
sharpened
>
0.7
def
convertGreyscale
(
image
):
"""
Function that take a three dimension numpy array
representing a RGB picture and return a two dimension
numpy array of this picture in greyscale with values between
0 and 1
@args:
- image: 3 dimension numpy array from a RGB picture with
values between 0 and 255
@return:
grey: 2 dimension numpy array with values between 0 and 1
The greyscale conversion is needed to detect edge in
the preprocessing and later to extract easier to process data
"""
return
image
.
astype
(
float
).
sum
(
axis
=
-
1
)
/
3.
/
255
bt5/erp5_receipt_recognition/ExtensionTemplateItem/portal_components/extension.erp5.ReceiptRecognition.xml
0 → 100644
View file @
392e5268
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Extension Component"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_recorded_property_dict
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
default_reference
</string>
</key>
<value>
<string>
ReceiptRecognition
</string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
extension.erp5.ReceiptRecognition
</string>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Extension Component
</string>
</value>
</item>
<item>
<key>
<string>
sid
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
text_content_error_message
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
text_content_warning_message
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
version
</string>
</key>
<value>
<string>
erp5
</string>
</value>
</item>
<item>
<key>
<string>
workflow_history
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAM=
</string>
</persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
data
</string>
</key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"3"
aka=
"AAAAAAAAAAM="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
data
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
component_validation_workflow
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAQ=
</string>
</persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"4"
aka=
"AAAAAAAAAAQ="
>
<pickle>
<global
name=
"WorkflowHistoryList"
module=
"Products.ERP5Type.Workflow"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_log
</string>
</key>
<value>
<list>
<dictionary>
<item>
<key>
<string>
action
</string>
</key>
<value>
<string>
validate
</string>
</value>
</item>
<item>
<key>
<string>
validation_state
</string>
</key>
<value>
<string>
validated
</string>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_receipt_recognition/ModuleTemplateItem/receipt_recognition_module.xml
0 → 100644
View file @
392e5268
<module>
<id>
receipt_recognition_module
</id>
<permission_list>
<permission
type=
'tuple'
>
<name>
Access Transient Objects
</name>
<role>
Assignee
</role>
<role>
Assignor
</role>
<role>
Associate
</role>
<role>
Auditor
</role>
<role>
Author
</role>
<role>
Manager
</role>
</permission>
<permission
type=
'tuple'
>
<name>
Access contents information
</name>
<role>
Assignee
</role>
<role>
Assignor
</role>
<role>
Associate
</role>
<role>
Auditor
</role>
<role>
Author
</role>
<role>
Manager
</role>
</permission>
<permission
type=
'tuple'
>
<name>
Access session data
</name>
<role>
Assignee
</role>
<role>
Assignor
</role>
<role>
Associate
</role>
<role>
Auditor
</role>
<role>
Author
</role>
<role>
Manager
</role>
</permission>
<permission
type=
'tuple'
>
<name>
Add portal content
</name>
<role>
Assignor
</role>
<role>
Author
</role>
<role>
Manager
</role>
</permission>
<permission
type=
'tuple'
>
<name>
Add portal folders
</name>
<role>
Assignor
</role>
<role>
Author
</role>
<role>
Manager
</role>
</permission>
<permission
type=
'tuple'
>
<name>
Change local roles
</name>
<role>
Assignor
</role>
<role>
Manager
</role>
</permission>
<permission
type=
'tuple'
>
<name>
Copy or Move
</name>
<role>
Assignee
</role>
<role>
Assignor
</role>
<role>
Associate
</role>
<role>
Auditor
</role>
<role>
Author
</role>
<role>
Manager
</role>
</permission>
<permission
type=
'tuple'
>
<name>
Delete objects
</name>
<role>
Assignor
</role>
<role>
Manager
</role>
</permission>
<permission
type=
'tuple'
>
<name>
List folder contents
</name>
<role>
Assignee
</role>
<role>
Assignor
</role>
<role>
Associate
</role>
<role>
Auditor
</role>
<role>
Author
</role>
<role>
Manager
</role>
</permission>
<permission
type=
'tuple'
>
<name>
Modify portal content
</name>
<role>
Assignor
</role>
<role>
Manager
</role>
</permission>
<permission
type=
'tuple'
>
<name>
View
</name>
<role>
Assignee
</role>
<role>
Assignor
</role>
<role>
Associate
</role>
<role>
Auditor
</role>
<role>
Manager
</role>
</permission>
<permission
type=
'tuple'
>
<name>
View History
</name>
<role>
Assignee
</role>
<role>
Assignor
</role>
<role>
Associate
</role>
<role>
Auditor
</role>
<role>
Author
</role>
<role>
Manager
</role>
</permission>
</permission_list>
<portal_type>
Receipt Recognition Module
</portal_type>
<title>
Receipt Recognition
</title>
</module>
\ No newline at end of file
bt5/erp5_receipt_recognition/PortalTypeAllowedContentTypeTemplateItem/allowed_content_types.xml
0 → 100644
View file @
392e5268
<allowed_content_type_list>
<portal_type
id=
"Receipt Recognition Module"
>
<item>
Receipt Recognition
</item>
</portal_type>
</allowed_content_type_list>
\ No newline at end of file
bt5/erp5_receipt_recognition/PortalTypeBaseCategoryTemplateItem/base_category_list.xml
0 → 100644
View file @
392e5268
<base_category_list>
<portal_type
id=
"Receipt Recognition Module"
>
<item>
business_application
</item>
</portal_type>
</base_category_list>
\ No newline at end of file
bt5/erp5_receipt_recognition/PortalTypePropertySheetTemplateItem/property_sheet_list.xml
0 → 100644
View file @
392e5268
<property_sheet_list>
<portal_type
id=
"Receipt Recognition"
>
<item>
Document
</item>
</portal_type>
</property_sheet_list>
\ No newline at end of file
bt5/erp5_receipt_recognition/PortalTypeTemplateItem/portal_types/Receipt%20Recognition%20Module.xml
0 → 100644
View file @
392e5268
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Base Type"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_property_domain_dict
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
acquire_local_roles
</string>
</key>
<value>
<int>
1
</int>
</value>
</item>
<item>
<key>
<string>
content_icon
</string>
</key>
<value>
<string>
folder_icon.gif
</string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
factory
</string>
</key>
<value>
<string>
addFolder
</string>
</value>
</item>
<item>
<key>
<string>
filter_content_types
</string>
</key>
<value>
<int>
1
</int>
</value>
</item>
<item>
<key>
<string>
group_list
</string>
</key>
<value>
<tuple>
<string>
module
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
Receipt Recognition Module
</string>
</value>
</item>
<item>
<key>
<string>
init_script
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
permission
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Base Type
</string>
</value>
</item>
<item>
<key>
<string>
searchable_text_property_id
</string>
</key>
<value>
<tuple>
<string>
title
</string>
<string>
description
</string>
<string>
reference
</string>
<string>
short_title
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
type_class
</string>
</key>
<value>
<string>
Folder
</string>
</value>
</item>
<item>
<key>
<string>
type_interface
</string>
</key>
<value>
<tuple/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
data
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
short_title
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAM=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAQ=
</string>
</persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"3"
aka=
"AAAAAAAAAAM="
>
<pickle>
<global
name=
"TranslationInformation"
module=
"Products.ERP5Type.TranslationProviderBase"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
domain_name
</string>
</key>
<value>
<string>
erp5_ui
</string>
</value>
</item>
<item>
<key>
<string>
property_name
</string>
</key>
<value>
<string>
short_title
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"4"
aka=
"AAAAAAAAAAQ="
>
<pickle>
<global
name=
"TranslationInformation"
module=
"Products.ERP5Type.TranslationProviderBase"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
domain_name
</string>
</key>
<value>
<string>
erp5_ui
</string>
</value>
</item>
<item>
<key>
<string>
property_name
</string>
</key>
<value>
<string>
title
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_receipt_recognition/PortalTypeTemplateItem/portal_types/Receipt%20Recognition.xml
0 → 100644
View file @
392e5268
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Base Type"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
acquire_local_roles
</string>
</key>
<value>
<int>
1
</int>
</value>
</item>
<item>
<key>
<string>
content_icon
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
factory
</string>
</key>
<value>
<string>
addXMLObject
</string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
Receipt Recognition
</string>
</value>
</item>
<item>
<key>
<string>
init_script
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
permission
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Base Type
</string>
</value>
</item>
<item>
<key>
<string>
searchable_text_property_id
</string>
</key>
<value>
<tuple>
<string>
title
</string>
<string>
description
</string>
<string>
reference
</string>
<string>
short_title
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
type_class
</string>
</key>
<value>
<string>
XMLObject
</string>
</value>
</item>
<item>
<key>
<string>
type_interface
</string>
</key>
<value>
<tuple/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_receipt_recognition/SkinTemplateItem/portal_skins/erp5_receipt_recognition.xml
0 → 100644
View file @
392e5268
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Folder"
module=
"OFS.Folder"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_objects
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
erp5_receipt_recognition
</string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_receipt_recognition/SkinTemplateItem/portal_skins/erp5_receipt_recognition/ReceiptRecognitionModule_viewReceiptRecognitionList.xml
0 → 100644
View file @
392e5268
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ERP5 Form"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_objects
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
action
</string>
</key>
<value>
<string>
Base_doSelect
</string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
edit_order
</string>
</key>
<value>
<list/>
</value>
</item>
<item>
<key>
<string>
encoding
</string>
</key>
<value>
<string>
UTF-8
</string>
</value>
</item>
<item>
<key>
<string>
enctype
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
group_list
</string>
</key>
<value>
<list>
<string>
left
</string>
<string>
right
</string>
<string>
center
</string>
<string>
bottom
</string>
<string>
hidden
</string>
</list>
</value>
</item>
<item>
<key>
<string>
groups
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
bottom
</string>
</key>
<value>
<list>
<string>
listbox
</string>
</list>
</value>
</item>
<item>
<key>
<string>
center
</string>
</key>
<value>
<list/>
</value>
</item>
<item>
<key>
<string>
hidden
</string>
</key>
<value>
<list/>
</value>
</item>
<item>
<key>
<string>
left
</string>
</key>
<value>
<list/>
</value>
</item>
<item>
<key>
<string>
right
</string>
</key>
<value>
<list/>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
ReceiptRecognitionModule_viewReceiptRecognitionList
</string>
</value>
</item>
<item>
<key>
<string>
method
</string>
</key>
<value>
<string>
POST
</string>
</value>
</item>
<item>
<key>
<string>
name
</string>
</key>
<value>
<string>
ReceiptRecognitionModule_viewReceiptRecognitionList
</string>
</value>
</item>
<item>
<key>
<string>
pt
</string>
</key>
<value>
<string>
form_list
</string>
</value>
</item>
<item>
<key>
<string>
row_length
</string>
</key>
<value>
<int>
4
</int>
</value>
</item>
<item>
<key>
<string>
stored_encoding
</string>
</key>
<value>
<string>
UTF-8
</string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
Receipt Recognition
</string>
</value>
</item>
<item>
<key>
<string>
unicode_mode
</string>
</key>
<value>
<int>
0
</int>
</value>
</item>
<item>
<key>
<string>
update_action
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
update_action_title
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_receipt_recognition/SkinTemplateItem/portal_skins/erp5_receipt_recognition/ReceiptRecognitionModule_viewReceiptRecognitionList/listbox.xml
0 → 100644
View file @
392e5268
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ProxyField"
module=
"Products.ERP5Form.ProxyField"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
delegated_list
</string>
</key>
<value>
<list>
<string>
columns
</string>
<string>
portal_types
</string>
<string>
title
</string>
</list>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
listbox
</string>
</value>
</item>
<item>
<key>
<string>
message_values
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
external_validator_failed
</string>
</key>
<value>
<string>
The input failed the external validator.
</string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
overrides
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
field_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
tales
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
field_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
values
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
columns
</string>
</key>
<value>
<list>
<tuple>
<string>
title
</string>
<string>
Title
</string>
</tuple>
<tuple>
<string>
total
</string>
<string>
Total
</string>
</tuple>
<tuple>
<string>
follow_up_title
</string>
<string>
Image
</string>
</tuple>
</list>
</value>
</item>
<item>
<key>
<string>
field_id
</string>
</key>
<value>
<string>
my_list_mode_listbox
</string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string>
Base_viewFieldLibrary
</string>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<list>
<tuple>
<string>
Receipt Recognition
</string>
<string>
Receipt Recognition
</string>
</tuple>
</list>
</value>
</item>
<item>
<key>
<string>
portal_types
</string>
</key>
<value>
<list/>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
Receipt Recognition
</string>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_receipt_recognition/SkinTemplateItem/portal_skins/erp5_receipt_recognition/ReceiptRecognition_convertImage.py
0 → 100644
View file @
392e5268
image
=
context
.
getFollowUpValue
()
if
image
is
not
None
:
try
:
total
=
container
.
ReceiptRecognition_getReceiptValue
(
image
.
getData
())
message
=
"Total found"
context
.
edit
(
total
=
total
,
)
except
ValueError
as
e
:
message
=
"Could not find value, please submit it manually"
else
:
message
=
"Cannot find the image"
if
batch_mode
:
return
context
.
Base_redirect
(
'view'
,
keep_items
=
dict
(
portal_status_message
=
message
,
my_source
=
"test"
))
bt5/erp5_receipt_recognition/SkinTemplateItem/portal_skins/erp5_receipt_recognition/ReceiptRecognition_convertImage.xml
0 → 100644
View file @
392e5268
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"PythonScript"
module=
"Products.PythonScripts.PythonScript"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_bind_names
</string>
</key>
<value>
<object>
<klass>
<global
name=
"_reconstructor"
module=
"copy_reg"
/>
</klass>
<tuple>
<global
name=
"NameAssignments"
module=
"Shared.DC.Scripts.Bindings"
/>
<global
name=
"object"
module=
"__builtin__"
/>
<none/>
</tuple>
<state>
<dictionary>
<item>
<key>
<string>
_asgns
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
name_container
</string>
</key>
<value>
<string>
container
</string>
</value>
</item>
<item>
<key>
<string>
name_context
</string>
</key>
<value>
<string>
context
</string>
</value>
</item>
<item>
<key>
<string>
name_m_self
</string>
</key>
<value>
<string>
script
</string>
</value>
</item>
<item>
<key>
<string>
name_subpath
</string>
</key>
<value>
<string>
traverse_subpath
</string>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key>
<string>
_params
</string>
</key>
<value>
<string>
batch_mode=False, **kw
</string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
ReceiptRecognition_convertImage
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_receipt_recognition/SkinTemplateItem/portal_skins/erp5_receipt_recognition/ReceiptRecognition_getReceiptValue.xml
0 → 100644
View file @
392e5268
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ExternalMethod"
module=
"Products.ExternalMethod.ExternalMethod"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_function
</string>
</key>
<value>
<string>
getReceiptValue
</string>
</value>
</item>
<item>
<key>
<string>
_module
</string>
</key>
<value>
<string>
ReceiptRecognition
</string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
ReceiptRecognition_getReceiptValue
</string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_receipt_recognition/SkinTemplateItem/portal_skins/erp5_receipt_recognition/ReceiptRecognition_view.xml
0 → 100644
View file @
392e5268
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ERP5 Form"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_objects
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
action
</string>
</key>
<value>
<string>
Base_edit
</string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
edit_order
</string>
</key>
<value>
<list/>
</value>
</item>
<item>
<key>
<string>
encoding
</string>
</key>
<value>
<string>
UTF-8
</string>
</value>
</item>
<item>
<key>
<string>
enctype
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
group_list
</string>
</key>
<value>
<list>
<string>
left
</string>
<string>
right
</string>
<string>
center
</string>
<string>
bottom
</string>
<string>
hidden
</string>
</list>
</value>
</item>
<item>
<key>
<string>
groups
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
bottom
</string>
</key>
<value>
<list/>
</value>
</item>
<item>
<key>
<string>
center
</string>
</key>
<value>
<list/>
</value>
</item>
<item>
<key>
<string>
hidden
</string>
</key>
<value>
<list/>
</value>
</item>
<item>
<key>
<string>
left
</string>
</key>
<value>
<list>
<string>
my_title
</string>
<string>
my_total
</string>
<string>
my_follow_up_title
</string>
</list>
</value>
</item>
<item>
<key>
<string>
right
</string>
</key>
<value>
<list/>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
ReceiptRecognition_view
</string>
</value>
</item>
<item>
<key>
<string>
method
</string>
</key>
<value>
<string>
POST
</string>
</value>
</item>
<item>
<key>
<string>
name
</string>
</key>
<value>
<string>
ReceiptRecognition_view
</string>
</value>
</item>
<item>
<key>
<string>
pt
</string>
</key>
<value>
<string>
form_view
</string>
</value>
</item>
<item>
<key>
<string>
row_length
</string>
</key>
<value>
<int>
4
</int>
</value>
</item>
<item>
<key>
<string>
stored_encoding
</string>
</key>
<value>
<string>
UTF-8
</string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
Receipt Recognition
</string>
</value>
</item>
<item>
<key>
<string>
unicode_mode
</string>
</key>
<value>
<int>
0
</int>
</value>
</item>
<item>
<key>
<string>
update_action
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
update_action_title
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_receipt_recognition/SkinTemplateItem/portal_skins/erp5_receipt_recognition/ReceiptRecognition_view/my_follow_up_title.xml
0 → 100644
View file @
392e5268
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ProxyField"
module=
"Products.ERP5Form.ProxyField"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
delegated_list
</string>
</key>
<value>
<list>
<string>
portal_type
</string>
<string>
title
</string>
</list>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
my_follow_up_title
</string>
</value>
</item>
<item>
<key>
<string>
message_values
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
external_validator_failed
</string>
</key>
<value>
<string>
The input failed the external validator.
</string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
overrides
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
field_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
tales
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
field_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
values
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
field_id
</string>
</key>
<value>
<string>
my_relation_field
</string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string>
Base_viewFieldLibrary
</string>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<list>
<tuple>
<string>
Image
</string>
<string>
Image
</string>
</tuple>
</list>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
Follow Up
</string>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_receipt_recognition/SkinTemplateItem/portal_skins/erp5_receipt_recognition/ReceiptRecognition_view/my_title.xml
0 → 100644
View file @
392e5268
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ProxyField"
module=
"Products.ERP5Form.ProxyField"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
delegated_list
</string>
</key>
<value>
<list>
<string>
title
</string>
</list>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
my_title
</string>
</value>
</item>
<item>
<key>
<string>
message_values
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
external_validator_failed
</string>
</key>
<value>
<string>
The input failed the external validator.
</string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
overrides
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
field_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
tales
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
field_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
values
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
field_id
</string>
</key>
<value>
<string>
my_string_field
</string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string>
Base_viewFieldLibrary
</string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
Title
</string>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_receipt_recognition/SkinTemplateItem/portal_skins/erp5_receipt_recognition/ReceiptRecognition_view/my_total.xml
0 → 100644
View file @
392e5268
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ProxyField"
module=
"Products.ERP5Form.ProxyField"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
delegated_list
</string>
</key>
<value>
<list>
<string>
title
</string>
</list>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
my_total
</string>
</value>
</item>
<item>
<key>
<string>
message_values
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
external_validator_failed
</string>
</key>
<value>
<string>
The input failed the external validator.
</string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
overrides
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
field_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
tales
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
field_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
values
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
field_id
</string>
</key>
<value>
<string>
my_string_field
</string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string>
Base_viewFieldLibrary
</string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
Total
</string>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_receipt_recognition/bt/dependency_list
0 → 100644
View file @
392e5268
erp5_dms
\ No newline at end of file
bt5/erp5_receipt_recognition/bt/license
0 → 100644
View file @
392e5268
GPL
\ No newline at end of file
bt5/erp5_receipt_recognition/bt/skip_coding_style_test
0 → 100644
View file @
392e5268
1
\ No newline at end of file
bt5/erp5_receipt_recognition/bt/template_action_path_list
0 → 100644
View file @
392e5268
Receipt Recognition Module | view
Receipt Recognition | receipt_convert
Receipt Recognition | view
\ No newline at end of file
bt5/erp5_receipt_recognition/bt/template_extension_id_list
0 → 100644
View file @
392e5268
extension.erp5.ReceiptRecognition
\ No newline at end of file
bt5/erp5_receipt_recognition/bt/template_format_version
0 → 100644
View file @
392e5268
1
\ No newline at end of file
bt5/erp5_receipt_recognition/bt/template_module_id_list
0 → 100644
View file @
392e5268
receipt_recognition_module
\ No newline at end of file
bt5/erp5_receipt_recognition/bt/template_portal_type_allowed_content_type_list
0 → 100644
View file @
392e5268
Receipt Recognition Module | Receipt Recognition
\ No newline at end of file
bt5/erp5_receipt_recognition/bt/template_portal_type_base_category_list
0 → 100644
View file @
392e5268
Receipt Recognition Module | business_application
\ No newline at end of file
bt5/erp5_receipt_recognition/bt/template_portal_type_id_list
0 → 100644
View file @
392e5268
Receipt Recognition
Receipt Recognition Module
\ No newline at end of file
bt5/erp5_receipt_recognition/bt/template_portal_type_property_sheet_list
0 → 100644
View file @
392e5268
Receipt Recognition | Document
\ No newline at end of file
bt5/erp5_receipt_recognition/bt/template_skin_id_list
0 → 100644
View file @
392e5268
erp5_receipt_recognition
\ No newline at end of file
bt5/erp5_receipt_recognition/bt/test_dependency_list
0 → 100644
View file @
392e5268
erp5_full_text_mroonga_catalog
\ No newline at end of file
bt5/erp5_receipt_recognition/bt/title
0 → 100644
View file @
392e5268
erp5_receipt_recognition
\ No newline at end of file
bt5/erp5_receipt_recognition/bt/version
0 → 100644
View file @
392e5268
0.1.0
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment