idvpackage 3.0.10__tar.gz → 3.0.11__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. {idvpackage-3.0.10/idvpackage.egg-info → idvpackage-3.0.11}/PKG-INFO +1 -1
  2. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/common.py +0 -2
  3. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/ocr.py +71 -52
  4. {idvpackage-3.0.10 → idvpackage-3.0.11/idvpackage.egg-info}/PKG-INFO +1 -1
  5. {idvpackage-3.0.10 → idvpackage-3.0.11}/setup.cfg +1 -1
  6. {idvpackage-3.0.10 → idvpackage-3.0.11}/setup.py +1 -1
  7. {idvpackage-3.0.10 → idvpackage-3.0.11}/LICENSE +0 -0
  8. {idvpackage-3.0.10 → idvpackage-3.0.11}/MANIFEST.in +0 -0
  9. {idvpackage-3.0.10 → idvpackage-3.0.11}/README.md +0 -0
  10. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/__init__.py +0 -0
  11. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/blur_detection.py +0 -0
  12. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/constants.py +0 -0
  13. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/ekyc.py +0 -0
  14. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/genai_utils.py +0 -0
  15. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/icons/battery1.png +0 -0
  16. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/icons/battery3.png +0 -0
  17. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/icons/network1.png +0 -0
  18. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/icons/network2.png +0 -0
  19. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/icons/wifi1.png +0 -0
  20. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/icons/wifi3.png +0 -0
  21. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/icons/wifi4.png +0 -0
  22. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/iraq_id_extraction.py +0 -0
  23. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/iraq_id_extraction_withopenai.py +0 -0
  24. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/iraq_passport_extraction.py +0 -0
  25. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/jor_passport_extraction.py +0 -0
  26. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/lazy_imports.py +0 -0
  27. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/lebanon_id_extraction.py +0 -0
  28. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/lebanon_passport_extraction.py +0 -0
  29. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/liveness_spoofing_v2.py +0 -0
  30. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/ocr_utils.py +0 -0
  31. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/pse_passport_extraction.py +0 -0
  32. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/qatar_id_extraction.py +0 -0
  33. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/sau_id_extraction.py +0 -0
  34. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/spoof_resources/2.7_80x80_MiniFASNetV2.pth +0 -0
  35. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/spoof_resources/4_0_0_80x80_MiniFASNetV1SE.pth +0 -0
  36. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/spoof_resources/MiniFASNet.py +0 -0
  37. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/spoof_resources/__init__.py +0 -0
  38. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/spoof_resources/functional.py +0 -0
  39. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/spoof_resources/generate_patches.py +0 -0
  40. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/spoof_resources/transform.py +0 -0
  41. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/sudan_id_extraction.py +0 -0
  42. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/sudan_passport_extraction.py +0 -0
  43. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/syr_passport_extraction.py +0 -0
  44. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage/uae_id_extraction.py +0 -0
  45. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage.egg-info/SOURCES.txt +0 -0
  46. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage.egg-info/dependency_links.txt +0 -0
  47. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage.egg-info/requires.txt +0 -0
  48. {idvpackage-3.0.10 → idvpackage-3.0.11}/idvpackage.egg-info/top_level.txt +0 -0
  49. {idvpackage-3.0.10 → idvpackage-3.0.11}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: idvpackage
3
- Version: 3.0.10
3
+ Version: 3.0.11
4
4
  Summary: This repository contains a Python program designed to execute Optical Character Recognition (OCR) and Facial Recognition on images.
5
5
  Home-page: https://github.com/NymCard-Payments/project_idv_package
6
6
  Classifier: Programming Language :: Python :: 3
@@ -909,8 +909,6 @@ def load_and_process_image_deepface(image_input, country=None):
909
909
  # Keep best fallback (just in case)
910
910
 
911
911
 
912
- if country == "QAT":
913
- return 0, 0
914
912
 
915
913
  if best_face_objs is None or best_confidence < CONFIDENCE_THRESHOLD:
916
914
  print(f"No valid face found (threshold={CONFIDENCE_THRESHOLD})")
@@ -206,27 +206,12 @@ class IdentityVerification:
206
206
  video_capture = cv2.VideoCapture(temp_video_file.name)
207
207
 
208
208
  if video_capture.isOpened():
209
- frame_count = int(video_capture.get(cv2.CAP_PROP_FRAME_COUNT))
210
-
211
- for _ in range(frame_count):
212
- ret, frame = video_capture.read()
213
- # if ret:
214
- # frame_count_vid+=1
215
- # if frame_count_vid % 10 == 0:
216
- _, buffer = cv2.imencode(".jpg", frame)
217
- image_data = buffer.tobytes()
218
-
219
- image = vision_v1.Image(content=image_data)
220
-
221
- response = self.client.face_detection(image=image)
222
- if len(response.face_annotations) >= 1:
223
- break
224
-
225
- video_capture.set(cv2.CAP_PROP_POS_FRAMES, 0)
209
+ video_capture.set(cv2.CAP_PROP_POS_FRAMES, 0)
226
210
 
227
211
  selfie_result = self.extract_selfie_from_video(video_capture)
228
212
  if isinstance(selfie_result, dict):
229
213
  video_quality["error"] = selfie_result["error"]
214
+
230
215
  else:
231
216
  (
232
217
  selfie_blurry_result,
@@ -241,22 +226,38 @@ class IdentityVerification:
241
226
  video_quality["selfie"] = selfie_result
242
227
  video_quality["shape"] = selfie_result.shape
243
228
 
244
- video_capture.release() # Release the video capture
245
-
246
- # except Exception as e:
247
- # video_quality["error"] = "bad_video"
248
-
229
+ return video_quality
230
+
231
+ except Exception as e:
232
+ logging.exception("check_document_quality failed")
233
+ video_quality["error"] = "face_not_clear_in_video"
234
+ return video_quality
235
+
249
236
  finally:
250
- # Ensure the temporary file is deleted
251
- if os.path.exists(temp_video_file_path):
252
- os.remove(temp_video_file_path)
253
- # print(f"Temporary file {temp_video_file_path} has been deleted.")
237
+
238
+ if video_capture is not None:
239
+ try:
240
+ video_capture.release()
241
+ except Exception:
242
+ pass
243
+ del video_capture
254
244
 
255
- return video_quality
245
+ # Remove temp file
246
+ if temp_video_file_path and os.path.exists(temp_video_file_path):
247
+ try:
248
+ os.remove(temp_video_file_path)
249
+ except Exception:
250
+ logging.warning("Failed to delete temp file %s", temp_video_file_path)
251
+
252
+ # Force cleanup of OpenCV / numpy memory
253
+ import gc
254
+ gc.collect()
255
+
256
256
 
257
257
  def extract_selfie_from_video(self, video_capture):
258
258
  """Extract the best quality selfie from video with speed optimizations for frontal faces."""
259
259
  video_dict = {'error': ''}
260
+
260
261
 
261
262
  try:
262
263
  # Get rotation metadata from video
@@ -286,12 +287,12 @@ class IdentityVerification:
286
287
 
287
288
  best_face = None
288
289
  best_score = -1
289
- best_frame = None
290
290
  best_frame_position = None
291
- frame_results = []
291
+ best_frame = None
292
292
 
293
- print(f"Analyzing video with {total_frames} frames")
294
- print(f"Checking {len(frame_positions)} strategic frames")
293
+ logging.info(f"Analyzing video with {total_frames} frames")
294
+ logging.info(f"Checking {len(frame_positions)} strategic frames")
295
+ logging.info(f"Frame positions to analyze: {frame_positions}")
295
296
 
296
297
  for target_frame in frame_positions:
297
298
  if target_frame >= total_frames:
@@ -299,6 +300,7 @@ class IdentityVerification:
299
300
  if target_frame < 0:
300
301
  target_frame = 0
301
302
 
303
+ logging.info(f"Processing frame {target_frame}")
302
304
  video_capture.set(cv2.CAP_PROP_POS_FRAMES, target_frame)
303
305
  ret, frame = video_capture.read()
304
306
  if not ret or frame is None or frame.size == 0:
@@ -319,8 +321,17 @@ class IdentityVerification:
319
321
  encode_params = [cv2.IMWRITE_JPEG_QUALITY, 90]
320
322
  _, buffer = cv2.imencode(".jpg", small_frame, encode_params)
321
323
 
322
- image = vision_v1.Image(content=buffer.tobytes())
324
+ # image = vision_v1.Image(content=buffer.tobytes())
325
+ # response = self.client.face_detection(image=image, max_results=2)
326
+ # faces = response.face_annotations
327
+
328
+ image_bytes = buffer.tobytes()
329
+ del buffer
330
+
331
+ image = vision_v1.Image(content=image_bytes)
323
332
  response = self.client.face_detection(image=image, max_results=2)
333
+ del image_bytes
334
+
324
335
  faces = response.face_annotations
325
336
 
326
337
  if not faces:
@@ -431,40 +442,46 @@ class IdentityVerification:
431
442
  }
432
443
 
433
444
  if frame_best_face is not None:
434
- frame_results.append({
435
- 'frame': target_frame,
436
- 'face': frame_best_face,
437
- 'score': frame_best_score,
438
- 'frame_data': frame.copy()
439
- })
445
+
446
+
447
+ # frame_results.append({
448
+ # 'frame': target_frame,
449
+ # 'face': frame_best_face,
450
+ # 'score': frame_best_score,
451
+ # 'frame_data': frame.copy()
452
+ # })
453
+ logging.info(f"Frame {target_frame}: Best face score {frame_best_score:.2f} "
454
+ f"(Frontal: {frame_best_face['frontal_score']:.2f}, "
455
+ f"Center: {frame_best_face['center_score']:.2f}, "
456
+ f"Confidence: {frame_best_face['confidence']:.2f})")
440
457
 
441
458
  if frame_best_score > best_score:
459
+ logging.info(f"New best face found at frame {target_frame} with score {frame_best_score:.2f}")
442
460
  best_score = frame_best_score
443
461
  best_face = frame_best_face
444
462
  best_frame = frame.copy()
445
463
  best_frame_position = target_frame
446
464
 
447
465
  except Exception as e:
466
+ logging.info(f"Error processing frame {target_frame}: {e}")
448
467
  continue
449
468
 
450
- # Process results
451
- if len(frame_results) > 0:
452
- # Sort faces by score
453
- frame_results.sort(key=lambda x: x['score'], reverse=True)
469
+ # # Process results
470
+ # if len(frame_results) > 0:
471
+ # # Sort faces by score
472
+ # frame_results.sort(key=lambda x: x['score'], reverse=True)
454
473
 
455
- for i, result in enumerate(frame_results[:min(3, len(frame_results))]):
456
- face_info = result['face']
457
- print(f"Rank {i+1}: Frame {face_info['frame']}, "
458
- f"Score: {result['score']:.2f}, "
459
- f"Frontal: {face_info['frontal_score']:.2f}, "
460
- f"Center: {face_info['center_score']:.2f}")
474
+ # for i, result in enumerate(frame_results[:min(3, len(frame_results))]):
475
+ # face_info = result['face']
476
+ # print(f"Rank {i+1}: Frame {face_info['frame']}, "
477
+ # f"Score: {result['score']:.2f}, "
478
+ # f"Frontal: {face_info['frontal_score']:.2f}, "
479
+ # f"Center: {face_info['center_score']:.2f}")
461
480
 
462
481
  # Use the best frame
463
- best_result = frame_results[0]
464
- best_face = best_result['face']
465
- best_frame = best_result['frame_data']
482
+ # best_frame = frame_best_face['frame']
466
483
 
467
- print(f"Selected frame {best_face['frame']} as best selfie")
484
+ # print(f"Selected frame {best_face['frame']} as best selfie")
468
485
 
469
486
  if best_face and best_frame is not None:
470
487
  try:
@@ -493,9 +510,11 @@ class IdentityVerification:
493
510
  return video_dict
494
511
 
495
512
  except Exception as e:
513
+ logging.info(f"Exception in extract_selfie_from_video: {e}")
496
514
  video_dict['error'] = 'video_processing_error'
497
515
  return video_dict
498
516
 
517
+
499
518
 
500
519
  def is_colored(self, base64_image):
501
520
  img = self.image_conversion(base64_image)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: idvpackage
3
- Version: 3.0.10
3
+ Version: 3.0.11
4
4
  Summary: This repository contains a Python program designed to execute Optical Character Recognition (OCR) and Facial Recognition on images.
5
5
  Home-page: https://github.com/NymCard-Payments/project_idv_package
6
6
  Classifier: Programming Language :: Python :: 3
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = idvpackage
3
- version = 3.0.10
3
+ version = 3.0.11
4
4
  description = This repository contains a Python program designed to execute Optical Character Recognition (OCR) and Facial Recognition on images.
5
5
  long_description = file: README.md
6
6
  long_description_content_type = text/markdown
@@ -9,7 +9,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
9
9
 
10
10
  setup(
11
11
  name="idvpackage",
12
- version="3.0.10",
12
+ version="3.0.11",
13
13
  description=(
14
14
  "This repository contains a Python program designed to execute Optical Character Recognition (OCR)"
15
15
  " and Facial Recognition on images."
File without changes
File without changes
File without changes
File without changes