1
1
# Python Document Scanner SDK
2
- The project is a Python binding to [ Dynamsoft C/C++ Document Scanner SDK] ( https://www.dynamsoft.com/document-normalizer/docs/introduction/?ver=latest ) . It aims to help developers quickly build desktop document scanner applications in Python on Windows and Linux.
2
+ This project provides Python bindings for the [ Dynamsoft C/C++ Document Scanner SDK v1.x ] ( https://www.dynamsoft.com/document-normalizer/docs/core/ introduction/?ver=latest&ver=latest ) , enabling developers to quickly create document scanner applications for Windows and Linux desktop environments .
3
3
4
4
## About Dynamsoft Document Scanner
5
- Get a [ 30-day FREE trial license] ( https://www.dynamsoft.com/customer/license/trialLicense?product=ddn ) to activate the SDK .
5
+ - Activate the SDK with a [ 30-day FREE trial license] ( https://www.dynamsoft.com/customer/license/trialLicense?product=ddn ) .
6
6
7
7
8
- ## Supported Python Edition
8
+ ## Supported Python Versions
9
9
* Python 3.x
10
10
11
11
## Dependencies
12
+ Install the required dependencies using pip:
12
13
13
14
``` bash
14
15
pip install opencv-python
15
16
```
16
17
17
18
## Command-line Usage
18
- ``` bash
19
- # Scan documents from images
20
- $ scandocument -f < file-name> -l < license-key>
19
+ - Scan documents from images:
20
+
21
+ ``` bash
22
+ scandocument -f < file-name> -l < license-key>
23
+ ```
21
24
22
- # Scan documents from camera video stream
23
- $ scandocument -c 1 -l < license-key>
24
- ```
25
+ - Scan documents from a camera video stream:
26
+
27
+ ` ` ` bash
28
+ scandocument -c 1 -l < license-key>
29
+ ` ` `
25
30
26
31
# # Quick Start
27
32
- Scan documents from an image file:
@@ -80,7 +85,7 @@ $ scandocument -c 1 -l <license-key>
80
85
81
86
# set license
82
87
if license == ' ' :
83
- docscanner.initLicense(" DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ== " )
88
+ docscanner.initLicense(" LICENSE-KEY " )
84
89
else:
85
90
docscanner.initLicense(license)
86
91
@@ -112,26 +117,29 @@ $ scandocument -c 1 -l <license-key>
112
117
g_results = None
113
118
g_normalized_images = []
114
119
120
+
115
121
def callback(results):
116
122
global g_results
117
123
g_results = results
118
124
125
+
119
126
def showNormalizedImage(name, normalized_image):
120
127
mat = docscanner.convertNormalizedImage2Mat(normalized_image)
121
128
cv2.imshow(name, mat)
122
129
return mat
123
-
130
+
131
+
124
132
def process_video(scanner):
125
133
scanner.addAsyncListener(callback)
126
-
134
+
127
135
cap = cv2.VideoCapture(0)
128
136
while True:
129
137
ret, image = cap.read ()
130
-
138
+
131
139
ch = cv2.waitKey(1)
132
140
if ch == 27:
133
141
break
134
- elif ch == ord (' n' ): # normalize image
142
+ elif ch == ord(' n' ): # normalize image
135
143
if g_results ! = None:
136
144
g_normalized_images = []
137
145
index = 0
@@ -144,23 +152,25 @@ $ scandocument -c 1 -l <license-key>
144
152
y3 = result.y3
145
153
x4 = result.x4
146
154
y4 = result.y4
147
-
148
- normalized_image = scanner.normalizeBuffer(image, x1, y1, x2, y2, x3, y3, x4, y4)
149
- g_normalized_images.append((str (index), normalized_image))
155
+
156
+ normalized_image = scanner.normalizeBuffer(
157
+ image, x1, y1, x2, y2, x3, y3, x4, y4)
158
+ g_normalized_images.append(
159
+ (str(index), normalized_image))
150
160
mat = showNormalizedImage(str(index), normalized_image)
151
161
index += 1
152
- elif ch == ord (' s' ): # save image
162
+ elif ch == ord(' s' ): # save image
153
163
for data in g_normalized_images:
154
164
# cv2.imwrite('images/' + str(time.time()) + '.png', image)
155
165
cv2.destroyWindow(data[0])
156
166
data[1].save(str(time.time ()) + ' .png' )
157
167
print(' Image saved' )
158
-
168
+
159
169
g_normalized_images = []
160
-
170
+
161
171
if image is not None:
162
172
scanner.detectMatAsync(image)
163
-
173
+
164
174
if g_results ! = None:
165
175
for result in g_results:
166
176
x1 = result.x1
@@ -171,71 +181,48 @@ $ scandocument -c 1 -l <license-key>
171
181
y3 = result.y3
172
182
x4 = result.x4
173
183
y4 = result.y4
174
-
175
- cv2.drawContours(image, [np.intp([(x1, y1), (x2, y2), (x3, y3), (x4, y4)])], 0 , (0 , 255 , 0 ), 2 )
176
-
177
- cv2.putText(image, ' Press "n" to normalize image' , (10 , 30 ), cv2.FONT_HERSHEY_SIMPLEX , 0.8 , (0 , 0 , 255 ), 2 )
178
- cv2.putText(image, ' Press "s" to save image' , (10 , 60 ), cv2.FONT_HERSHEY_SIMPLEX , 0.8 , (0 , 0 , 255 ), 2 )
179
- cv2.putText(image, ' Press "ESC" to exit' , (10 , 90 ), cv2.FONT_HERSHEY_SIMPLEX , 0.8 , (0 , 0 , 255 ), 2 )
184
+
185
+ cv2.drawContours(
186
+ image, [np.intp([(x1, y1), (x2, y2), (x3, y3), (x4, y4)])], 0, (0, 255, 0), 2)
187
+
188
+ cv2.putText(image, ' Press "n" to normalize image' ,
189
+ (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 2)
190
+ cv2.putText(image, ' Press "s" to save image' , (10, 60),
191
+ cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 2)
192
+ cv2.putText(image, ' Press "ESC" to exit' , (10, 90),
193
+ cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 2)
180
194
cv2.imshow(' Document Scanner' , image)
181
195
182
- def scandocument ():
183
- """
184
- Command-line script for scanning documents from camera video stream.
185
- """
186
- parser = argparse.ArgumentParser(description = ' Scan documents from camera' )
187
- parser.add_argument(' -c' , ' --camera' , default = False , type = bool , help = ' Whether to show the image' )
188
- parser.add_argument(' -l' , ' --license' , default = ' ' , type = str , help = ' Set a valid license key' )
189
- args = parser.parse_args()
190
- # print(args)
191
- try :
192
- license = args.license
193
- camera = args.camera
194
-
195
- if camera is False :
196
- parser.print_help()
197
- return
198
-
199
- # set license
200
- if license == ' ' :
201
- docscanner.initLicense(" DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ==" )
202
- else :
203
- docscanner.initLicense(license )
204
-
205
- # initialize mrz scanner
206
- scanner = docscanner.createInstance()
207
- ret = scanner.setParameters(docscanner.Templates.color)
208
196
209
- if camera is True :
210
- process_video(scanner )
211
-
212
- except Exception as err:
213
- print (err )
214
- sys.exit( 1 )
197
+ docscanner.initLicense(
198
+ " LICENSE-KEY " )
199
+
200
+ scanner = docscanner.createInstance ()
201
+ ret = scanner.setParameters(docscanner.Templates.color )
202
+ process_video(scanner )
215
203
216
- scandocument()
217
204
` ` `
218
205
219
206
! [python document scanner from camera](https://www.dynamsoft.com/codepool/img/2022/09/python-document-scanner.png)
220
207
221
- # # Methods
222
- - `docscanner.initLicense(' YOUR-LICENSE-KEY' )` # set the license key
208
+ # # API Methods
209
+ - ` docscanner.initLicense(' YOUR-LICENSE-KEY' )` : Set the license key.
223
210
224
211
` ` ` python
225
- docscanner.initLicense(" DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ== " )
212
+ docscanner.initLicense(" LICENSE-KEY " )
226
213
` ` `
227
214
228
- - `docscanner.createInstance()` # create a Document Scanner instance
215
+ - ` docscanner.createInstance()` : Create a Document Scanner instance.
229
216
230
217
` ` ` python
231
218
scanner = docscanner.createInstance ()
232
219
` ` `
233
- - `detectFile(filename)` # do edge detection from an image file
220
+ - ` detectFile(filename)` : Perform edge detection from an image file.
234
221
235
222
` ` ` python
236
223
results = scanner.detectFile(< filename> )
237
224
` ` `
238
- - `detectMat(Mat image)` # do edge detection from Mat
225
+ - ` detectMat(Mat image)` : Perform edge detection from an OpenCV Mat.
239
226
` ` ` python
240
227
image = cv2.imread(< filename> )
241
228
results = scanner.detectMat(image)
@@ -250,14 +237,14 @@ $ scandocument -c 1 -l <license-key>
250
237
y4 = result.y4
251
238
` ` `
252
239
253
- - `setParameters(Template)` # Select color, binary or grayscale template
240
+ - ` setParameters(Template)` : Select color, binary, or grayscale template.
254
241
255
242
` ` ` python
256
243
scanner.setParameters(docscanner.Templates.color)
257
244
` ` `
258
245
259
- - `addAsyncListener(callback function)` # start a native thread to run document scanning tasks
260
- - `detectMatAsync(< opencv mat data> )` # put a document scanning task into the native queue
246
+ - ` addAsyncListener(callback function)` : Start a native thread to run document scanning tasks asynchronously.
247
+ - ` detectMatAsync(< opencv mat data> )` : Queue a document scanning task into the native thread.
261
248
` ` ` python
262
249
def callback(results):
263
250
for result in results:
@@ -277,23 +264,23 @@ $ scandocument -c 1 -l <license-key>
277
264
sleep(5)
278
265
` ` `
279
266
280
- - `normalizeBuffer(mat, x1, y1, x2, y2, x3, y3, x4, y4)` # do perspective correction from Mat
267
+ - ` normalizeBuffer(mat, x1, y1, x2, y2, x3, y3, x4, y4)` : Perform perspective correction from an OpenCV Mat.
268
+
281
269
` ` ` python
282
270
normalized_image = scanner.normalizeBuffer(image, x1, y1, x2, y2, x3, y3, x4, y4)
283
271
` ` `
284
- - `normalizeFile(filename, x1, y1, x2, y2, x3, y3, x4, y4)` # do perspective correction from a file
272
+ - ` normalizeFile(filename, x1, y1, x2, y2, x3, y3, x4, y4)` : Perform perspective correction from an image file.
273
+
285
274
` ` ` python
286
275
normalized_image = scanner.normalizeFile(< filename> , x1, y1, x2, y2, x3, y3, x4, y4)
287
276
` ` `
288
- - `normalized_image.save(filename)` # save the normalized image to a file
277
+ - ` normalized_image.save(filename)` : Save the normalized image to a file.
289
278
` ` ` python
290
279
normalized_image.save(< filename> )
291
280
` ` `
292
- - `normalized_image.recycle()` # release the memory of the normalized image
293
- - `clearAsyncListener()` # stop the native thread and clear the registered Python function
294
- # # C/C++ API
295
- To customize Python API based on C/ C++ , please refer to the
296
- [online documentation](https:// www.dynamsoft.com/ document- normalizer/ docs/ programming/ c/ api- reference/ ? ver = latest).
281
+ - ` normalized_image.recycle()` : Release the memory of the normalized image.
282
+ - ` clearAsyncListener()` : Stop the native thread and clear the registered Python function.
283
+
297
284
298
285
# # How to Build the Python Document Scanner Extension
299
286
- Create a source distribution:
0 commit comments