From 3fd270c8bd42ac27824f3ac241b2eb3d4e3ed369 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Ph=C6=B0=E1=BB=9Bc=20Th=C3=A0nh?= <93478665+Zeres-Engel@users.noreply.github.com> Date: Tue, 5 Aug 2025 20:53:47 +0700 Subject: [PATCH] refactor YOLO crop model --- README_ID_Card_Cropper.md | 56 ----- config/config.yaml | 4 +- data_augmentation.log | 222 ------------------ src/__init__.py | 10 +- src/__pycache__/__init__.cpython-313.pyc | Bin 589 -> 0 bytes src/__pycache__/__init__.cpython-39.pyc | Bin 559 -> 0 bytes src/__pycache__/config_manager.cpython-39.pyc | Bin 6334 -> 0 bytes .../data_augmentation.cpython-39.pyc | Bin 5323 -> 0 bytes .../image_processor.cpython-39.pyc | Bin 5218 -> 0 bytes src/__pycache__/utils.cpython-313.pyc | Bin 5478 -> 0 bytes src/__pycache__/utils.cpython-39.pyc | Bin 3426 -> 0 bytes src/config.py | 40 ---- src/data_augmentation.py | 134 ++++++++++- src/image_processor.py | 136 +---------- src/model/{ => YOLO_processor}/__init__.py | 0 .../{ => YOLO_processor}/id_card_processor.py | 0 .../roboflow_id_detector.py | 0 .../__pycache__/__init__.cpython-313.pyc | Bin 338 -> 0 bytes src/model/__pycache__/__init__.cpython-39.pyc | Bin 318 -> 0 bytes .../id_card_processor.cpython-39.pyc | Bin 8960 -> 0 bytes .../roboflow_id_detector.cpython-313.pyc | Bin 14131 -> 0 bytes .../roboflow_id_detector.cpython-39.pyc | Bin 9059 -> 0 bytes .../__pycache__/yolo_detector.cpython-39.pyc | Bin 7117 -> 0 bytes src/utils.py | 13 +- 24 files changed, 136 insertions(+), 479 deletions(-) delete mode 100644 README_ID_Card_Cropper.md delete mode 100644 data_augmentation.log delete mode 100644 src/__pycache__/__init__.cpython-313.pyc delete mode 100644 src/__pycache__/__init__.cpython-39.pyc delete mode 100644 src/__pycache__/config_manager.cpython-39.pyc delete mode 100644 src/__pycache__/data_augmentation.cpython-39.pyc delete mode 100644 src/__pycache__/image_processor.cpython-39.pyc delete mode 100644 src/__pycache__/utils.cpython-313.pyc delete mode 100644 src/__pycache__/utils.cpython-39.pyc delete mode 100644 src/config.py rename src/model/{ => YOLO_processor}/__init__.py (100%) rename src/model/{ => YOLO_processor}/id_card_processor.py (100%) rename src/model/{ => YOLO_processor}/roboflow_id_detector.py (100%) delete mode 100644 src/model/__pycache__/__init__.cpython-313.pyc delete mode 100644 src/model/__pycache__/__init__.cpython-39.pyc delete mode 100644 src/model/__pycache__/id_card_processor.cpython-39.pyc delete mode 100644 src/model/__pycache__/roboflow_id_detector.cpython-313.pyc delete mode 100644 src/model/__pycache__/roboflow_id_detector.cpython-39.pyc delete mode 100644 src/model/__pycache__/yolo_detector.cpython-39.pyc diff --git a/README_ID_Card_Cropper.md b/README_ID_Card_Cropper.md deleted file mode 100644 index c34a2aa..0000000 --- a/README_ID_Card_Cropper.md +++ /dev/null @@ -1,56 +0,0 @@ -# ID Card Cropper - -Script đơn giản để cắt ID cards từ ảnh sử dụng Roboflow API. - -## Cách sử dụng - -```bash -python id_card_cropper.py input_folder output_folder -``` - -### Ví dụ: - -```bash -# Sử dụng API key mặc định -python id_card_cropper.py data/IDcards/Archive output/cropped_cards - -# Sử dụng API key tùy chỉnh -python id_card_cropper.py data/IDcards/Archive output/cropped_cards --api-key YOUR_API_KEY -``` - -## Tham số - -- `input_folder`: Thư mục chứa ảnh cần xử lý -- `output_folder`: Thư mục lưu ID cards đã cắt -- `--api-key`: API key Roboflow (mặc định: demo key) - -## Hỗ trợ định dạng ảnh - -- JPG/JPEG -- PNG -- BMP -- TIFF - -## Kết quả - -Script sẽ: -1. Tìm tất cả ảnh trong thư mục input -2. Phát hiện ID cards trong mỗi ảnh -3. Cắt và lưu ID cards vào thư mục output -4. Đặt tên file theo format: `{tên_ảnh_gốc}_card_{số}.jpg` - -## Ví dụ kết quả - -``` -output/cropped_cards/ -├── im1__card_1.jpg -├── im5_card_1.jpg -├── im11_card_1.jpg -└── im11_card_2.jpg -``` - -## Lưu ý - -- Cần kết nối internet để sử dụng Roboflow API -- Có delay 1 giây giữa các request để tránh rate limiting -- Chỉ lưu ID cards đã cắt, không lưu ảnh gốc với bounding boxes \ No newline at end of file diff --git a/config/config.yaml b/config/config.yaml index 96b942f..cf5299c 100644 --- a/config/config.yaml +++ b/config/config.yaml @@ -3,7 +3,7 @@ # Paths configuration paths: - input_dir: "data/Archive" + input_dir: "data/IDcards/processed" output_dir: "out" log_file: "logs/data_augmentation.log" @@ -17,7 +17,7 @@ augmentation: # Processing configuration processing: - target_size: [224, 224] # [width, height] + target_size: [640, 640] # [width, height] - Increased for better coverage batch_size: 32 num_augmentations: 3 # number of augmented versions per image save_format: "jpg" diff --git a/data_augmentation.log b/data_augmentation.log deleted file mode 100644 index 2405a6d..0000000 --- a/data_augmentation.log +++ /dev/null @@ -1,222 +0,0 @@ -2025-08-05 18:53:06,981 - src.model.yolo_detector - INFO - Using pre-trained YOLOv8n model -2025-08-05 18:53:07,004 - src.model.yolo_detector - INFO - Using device: cuda -2025-08-05 18:53:07,038 - src.model.yolo_detector - INFO - Using pre-trained YOLOv8n model -2025-08-05 18:53:07,038 - src.model.yolo_detector - INFO - Using device: cuda -2025-08-05 18:53:07,361 - src.model.yolo_detector - INFO - Using pre-trained YOLOv8n model -2025-08-05 18:53:07,362 - src.model.yolo_detector - INFO - Using device: cuda -2025-08-05 18:53:07,363 - src.model.id_card_processor - INFO - Detecting and cropping ID cards... -2025-08-05 18:53:07,363 - src.model.yolo_detector - ERROR - No images found in data\IDcards -2025-08-05 18:53:07,364 - src.model.id_card_processor - INFO - Processing cropped ID cards... -2025-08-05 18:53:07,364 - src.model.id_card_processor - ERROR - No images found in data\test_output\cropped -2025-08-05 19:04:14,903 - src.model.yolo_detector - INFO - Using pre-trained YOLOv8n model -2025-08-05 19:04:14,995 - src.model.yolo_detector - INFO - Using device: cuda -2025-08-05 19:04:14,996 - src.model.id_card_processor - INFO - Detecting and cropping ID cards... -2025-08-05 19:04:14,997 - src.model.yolo_detector - INFO - Processing 29 images from data\IDcards and subdirectories -2025-08-05 19:04:14,998 - src.model.yolo_detector - INFO - Processing 1/29: im10.png -2025-08-05 19:04:19,785 - src.model.yolo_detector - INFO - Found 1 detections in im10.png -2025-08-05 19:04:19,813 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\Archive\im10_card_1.jpg -2025-08-05 19:04:19,813 - src.model.yolo_detector - INFO - Processed im10.png: 1 cards cropped -2025-08-05 19:04:19,814 - src.model.yolo_detector - INFO - Processing 2/29: im11.png -2025-08-05 19:04:19,926 - src.model.yolo_detector - INFO - Found 2 detections in im11.png -2025-08-05 19:04:19,937 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\Archive\im11_card_1.jpg -2025-08-05 19:04:19,946 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\Archive\im11_card_2.jpg -2025-08-05 19:04:19,946 - src.model.yolo_detector - INFO - Processed im11.png: 2 cards cropped -2025-08-05 19:04:19,946 - src.model.yolo_detector - INFO - Processing 3/29: im12.png -2025-08-05 19:04:20,056 - src.model.yolo_detector - INFO - Found 2 detections in im12.png -2025-08-05 19:04:20,069 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\Archive\im12_card_1.jpg -2025-08-05 19:04:20,082 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\Archive\im12_card_2.jpg -2025-08-05 19:04:20,083 - src.model.yolo_detector - INFO - Processed im12.png: 2 cards cropped -2025-08-05 19:04:20,083 - src.model.yolo_detector - INFO - Processing 4/29: im13.png -2025-08-05 19:04:20,116 - src.model.yolo_detector - INFO - Found 0 detections in im13.png -2025-08-05 19:04:20,117 - src.model.yolo_detector - WARNING - No ID cards detected in im13.png -2025-08-05 19:04:20,117 - src.model.yolo_detector - INFO - Processing 5/29: im14.png -2025-08-05 19:04:20,156 - src.model.yolo_detector - INFO - Found 1 detections in im14.png -2025-08-05 19:04:20,172 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\Archive\im14_card_1.jpg -2025-08-05 19:04:20,173 - src.model.yolo_detector - INFO - Processed im14.png: 1 cards cropped -2025-08-05 19:04:20,174 - src.model.yolo_detector - INFO - Processing 6/29: im15.png -2025-08-05 19:04:20,208 - src.model.yolo_detector - INFO - Found 1 detections in im15.png -2025-08-05 19:04:20,222 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\Archive\im15_card_1.jpg -2025-08-05 19:04:20,222 - src.model.yolo_detector - INFO - Processed im15.png: 1 cards cropped -2025-08-05 19:04:20,223 - src.model.yolo_detector - INFO - Processing 7/29: im1_.png -2025-08-05 19:04:20,466 - src.model.yolo_detector - INFO - Found 0 detections in im1_.png -2025-08-05 19:04:20,466 - src.model.yolo_detector - WARNING - No ID cards detected in im1_.png -2025-08-05 19:04:20,466 - src.model.yolo_detector - INFO - Processing 8/29: im2.png -2025-08-05 19:04:20,534 - src.model.yolo_detector - INFO - Found 2 detections in im2.png -2025-08-05 19:04:20,564 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\Archive\im2_card_1.jpg -2025-08-05 19:04:20,594 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\Archive\im2_card_2.jpg -2025-08-05 19:04:20,594 - src.model.yolo_detector - INFO - Processed im2.png: 2 cards cropped -2025-08-05 19:04:20,595 - src.model.yolo_detector - INFO - Processing 9/29: im3.png -2025-08-05 19:04:20,648 - src.model.yolo_detector - INFO - Found 1 detections in im3.png -2025-08-05 19:04:20,671 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\Archive\im3_card_1.jpg -2025-08-05 19:04:20,671 - src.model.yolo_detector - INFO - Processed im3.png: 1 cards cropped -2025-08-05 19:04:20,672 - src.model.yolo_detector - INFO - Processing 10/29: im4.png -2025-08-05 19:04:20,724 - src.model.yolo_detector - INFO - Found 1 detections in im4.png -2025-08-05 19:04:20,753 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\Archive\im4_card_1.jpg -2025-08-05 19:04:20,754 - src.model.yolo_detector - INFO - Processed im4.png: 1 cards cropped -2025-08-05 19:04:20,754 - src.model.yolo_detector - INFO - Processing 11/29: im5.png -2025-08-05 19:04:20,798 - src.model.yolo_detector - INFO - Found 2 detections in im5.png -2025-08-05 19:04:20,816 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\Archive\im5_card_1.jpg -2025-08-05 19:04:20,835 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\Archive\im5_card_2.jpg -2025-08-05 19:04:20,836 - src.model.yolo_detector - INFO - Processed im5.png: 2 cards cropped -2025-08-05 19:04:20,837 - src.model.yolo_detector - INFO - Processing 12/29: im6.png -2025-08-05 19:04:20,994 - src.model.yolo_detector - INFO - Found 2 detections in im6.png -2025-08-05 19:04:21,052 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\Archive\im6_card_1.jpg -2025-08-05 19:04:21,118 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\Archive\im6_card_2.jpg -2025-08-05 19:04:21,119 - src.model.yolo_detector - INFO - Processed im6.png: 2 cards cropped -2025-08-05 19:04:21,120 - src.model.yolo_detector - INFO - Processing 13/29: im7.png -2025-08-05 19:04:21,159 - src.model.yolo_detector - INFO - Found 3 detections in im7.png -2025-08-05 19:04:21,168 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\Archive\im7_card_1.jpg -2025-08-05 19:04:21,176 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\Archive\im7_card_2.jpg -2025-08-05 19:04:21,184 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\Archive\im7_card_3.jpg -2025-08-05 19:04:21,184 - src.model.yolo_detector - INFO - Processed im7.png: 3 cards cropped -2025-08-05 19:04:21,185 - src.model.yolo_detector - INFO - Processing 14/29: im8.png -2025-08-05 19:04:21,353 - src.model.yolo_detector - INFO - Found 2 detections in im8.png -2025-08-05 19:04:21,387 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\Archive\im8_card_1.jpg -2025-08-05 19:04:21,423 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\Archive\im8_card_2.jpg -2025-08-05 19:04:21,424 - src.model.yolo_detector - INFO - Processed im8.png: 2 cards cropped -2025-08-05 19:04:21,425 - src.model.yolo_detector - INFO - Processing 15/29: im9.png -2025-08-05 19:04:21,522 - src.model.yolo_detector - INFO - Found 1 detections in im9.png -2025-08-05 19:04:21,532 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\Archive\im9_card_1.jpg -2025-08-05 19:04:21,532 - src.model.yolo_detector - INFO - Processed im9.png: 1 cards cropped -2025-08-05 19:04:21,532 - src.model.yolo_detector - INFO - Processing 16/29: im10.png -2025-08-05 19:04:21,585 - src.model.yolo_detector - INFO - Found 3 detections in im10.png -2025-08-05 19:04:21,601 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\titre-sejour-fr\im10_card_1.jpg -2025-08-05 19:04:21,618 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\titre-sejour-fr\im10_card_2.jpg -2025-08-05 19:04:21,636 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\titre-sejour-fr\im10_card_3.jpg -2025-08-05 19:04:21,636 - src.model.yolo_detector - INFO - Processed im10.png: 3 cards cropped -2025-08-05 19:04:21,638 - src.model.yolo_detector - INFO - Processing 17/29: im11.png -2025-08-05 19:04:21,679 - src.model.yolo_detector - INFO - Found 2 detections in im11.png -2025-08-05 19:04:21,696 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\titre-sejour-fr\im11_card_1.jpg -2025-08-05 19:04:21,712 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\titre-sejour-fr\im11_card_2.jpg -2025-08-05 19:04:21,713 - src.model.yolo_detector - INFO - Processed im11.png: 2 cards cropped -2025-08-05 19:04:21,713 - src.model.yolo_detector - INFO - Processing 18/29: im12.png -2025-08-05 19:04:21,755 - src.model.yolo_detector - INFO - Found 0 detections in im12.png -2025-08-05 19:04:21,756 - src.model.yolo_detector - WARNING - No ID cards detected in im12.png -2025-08-05 19:04:21,756 - src.model.yolo_detector - INFO - Processing 19/29: im13.png -2025-08-05 19:04:21,793 - src.model.yolo_detector - INFO - Found 1 detections in im13.png -2025-08-05 19:04:21,806 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\titre-sejour-fr\im13_card_1.jpg -2025-08-05 19:04:21,806 - src.model.yolo_detector - INFO - Processed im13.png: 1 cards cropped -2025-08-05 19:04:21,806 - src.model.yolo_detector - INFO - Processing 20/29: im14.png -2025-08-05 19:04:21,846 - src.model.yolo_detector - INFO - Found 2 detections in im14.png -2025-08-05 19:04:21,862 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\titre-sejour-fr\im14_card_1.jpg -2025-08-05 19:04:21,877 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\titre-sejour-fr\im14_card_2.jpg -2025-08-05 19:04:21,877 - src.model.yolo_detector - INFO - Processed im14.png: 2 cards cropped -2025-08-05 19:04:21,878 - src.model.yolo_detector - INFO - Processing 21/29: im15.png -2025-08-05 19:04:21,914 - src.model.yolo_detector - INFO - Found 0 detections in im15.png -2025-08-05 19:04:21,914 - src.model.yolo_detector - WARNING - No ID cards detected in im15.png -2025-08-05 19:04:21,914 - src.model.yolo_detector - INFO - Processing 22/29: im1_.png -2025-08-05 19:04:21,959 - src.model.yolo_detector - INFO - Found 3 detections in im1_.png -2025-08-05 19:04:21,971 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\titre-sejour-fr\im1__card_1.jpg -2025-08-05 19:04:21,983 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\titre-sejour-fr\im1__card_2.jpg -2025-08-05 19:04:21,996 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\titre-sejour-fr\im1__card_3.jpg -2025-08-05 19:04:21,997 - src.model.yolo_detector - INFO - Processed im1_.png: 3 cards cropped -2025-08-05 19:04:21,997 - src.model.yolo_detector - INFO - Processing 23/29: im2.png -2025-08-05 19:04:22,101 - src.model.yolo_detector - INFO - Found 1 detections in im2.png -2025-08-05 19:04:22,174 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\titre-sejour-fr\im2_card_1.jpg -2025-08-05 19:04:22,174 - src.model.yolo_detector - INFO - Processed im2.png: 1 cards cropped -2025-08-05 19:04:22,176 - src.model.yolo_detector - INFO - Processing 24/29: im3.png -2025-08-05 19:04:22,220 - src.model.yolo_detector - INFO - Found 2 detections in im3.png -2025-08-05 19:04:22,235 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\titre-sejour-fr\im3_card_1.jpg -2025-08-05 19:04:22,251 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\titre-sejour-fr\im3_card_2.jpg -2025-08-05 19:04:22,252 - src.model.yolo_detector - INFO - Processed im3.png: 2 cards cropped -2025-08-05 19:04:22,252 - src.model.yolo_detector - INFO - Processing 25/29: im5.png -2025-08-05 19:04:22,307 - src.model.yolo_detector - INFO - Found 1 detections in im5.png -2025-08-05 19:04:22,316 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\titre-sejour-fr\im5_card_1.jpg -2025-08-05 19:04:22,316 - src.model.yolo_detector - INFO - Processed im5.png: 1 cards cropped -2025-08-05 19:04:22,317 - src.model.yolo_detector - INFO - Processing 26/29: im6.png -2025-08-05 19:04:22,375 - src.model.yolo_detector - INFO - Found 2 detections in im6.png -2025-08-05 19:04:22,387 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\titre-sejour-fr\im6_card_1.jpg -2025-08-05 19:04:22,397 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\titre-sejour-fr\im6_card_2.jpg -2025-08-05 19:04:22,398 - src.model.yolo_detector - INFO - Processed im6.png: 2 cards cropped -2025-08-05 19:04:22,399 - src.model.yolo_detector - INFO - Processing 27/29: im7.png -2025-08-05 19:04:22,441 - src.model.yolo_detector - INFO - Found 1 detections in im7.png -2025-08-05 19:04:22,458 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\titre-sejour-fr\im7_card_1.jpg -2025-08-05 19:04:22,459 - src.model.yolo_detector - INFO - Processed im7.png: 1 cards cropped -2025-08-05 19:04:22,460 - src.model.yolo_detector - INFO - Processing 28/29: im8.png -2025-08-05 19:04:22,492 - src.model.yolo_detector - INFO - Found 2 detections in im8.png -2025-08-05 19:04:22,502 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\titre-sejour-fr\im8_card_1.jpg -2025-08-05 19:04:22,509 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\titre-sejour-fr\im8_card_2.jpg -2025-08-05 19:04:22,510 - src.model.yolo_detector - INFO - Processed im8.png: 2 cards cropped -2025-08-05 19:04:22,510 - src.model.yolo_detector - INFO - Processing 29/29: im9.png -2025-08-05 19:04:22,540 - src.model.yolo_detector - INFO - Found 1 detections in im9.png -2025-08-05 19:04:22,546 - src.model.yolo_detector - INFO - Saved cropped image to data\processed_id_cards\cropped\titre-sejour-fr\im9_card_1.jpg -2025-08-05 19:04:22,546 - src.model.yolo_detector - INFO - Processed im9.png: 1 cards cropped -2025-08-05 19:04:22,546 - src.model.yolo_detector - INFO - Batch processing completed: -2025-08-05 19:04:22,548 - src.model.yolo_detector - INFO - - Total images: 29 -2025-08-05 19:04:22,548 - src.model.yolo_detector - INFO - - Processed: 25 -2025-08-05 19:04:22,548 - src.model.yolo_detector - INFO - - Total detections: 42 -2025-08-05 19:04:22,549 - src.model.yolo_detector - INFO - - Total cropped: 42 -2025-08-05 19:04:22,549 - src.model.id_card_processor - INFO - Processing cropped ID cards... -2025-08-05 19:04:22,552 - src.model.id_card_processor - INFO - Processing 42 images from data\processed_id_cards\cropped and subdirectories -2025-08-05 19:04:22,552 - src.model.id_card_processor - INFO - Processing 1/42: im10_card_1.jpg -2025-08-05 19:04:22,564 - src.model.id_card_processor - INFO - Removing background from im10_card_1.jpg -2025-08-05 19:04:22,877 - src.model.id_card_processor - INFO - Enhancing im10_card_1.jpg -2025-08-05 19:04:23,016 - src.model.id_card_processor - INFO - Normalizing im10_card_1.jpg -2025-08-05 19:04:23,023 - src.model.id_card_processor - INFO - Processed im10_card_1.jpg -2025-08-05 19:04:23,023 - src.model.id_card_processor - INFO - Processing 2/42: im11_card_1.jpg -2025-08-05 19:04:23,034 - src.model.id_card_processor - INFO - Removing background from im11_card_1.jpg -2025-08-05 19:04:23,264 - src.model.id_card_processor - INFO - Enhancing im11_card_1.jpg -2025-08-05 19:04:23,265 - src.model.id_card_processor - INFO - Normalizing im11_card_1.jpg -2025-08-05 19:04:23,270 - src.model.id_card_processor - INFO - Processed im11_card_1.jpg -2025-08-05 19:04:23,271 - src.model.id_card_processor - INFO - Processing 3/42: im11_card_2.jpg -2025-08-05 19:04:23,282 - src.model.id_card_processor - INFO - Removing background from im11_card_2.jpg -2025-08-05 19:04:23,312 - src.model.id_card_processor - INFO - Enhancing im11_card_2.jpg -2025-08-05 19:04:23,313 - src.model.id_card_processor - INFO - Normalizing im11_card_2.jpg -2025-08-05 19:04:23,316 - src.model.id_card_processor - INFO - Processed im11_card_2.jpg -2025-08-05 19:04:23,316 - src.model.id_card_processor - INFO - Processing 4/42: im12_card_1.jpg -2025-08-05 19:04:23,328 - src.model.id_card_processor - INFO - Removing background from im12_card_1.jpg -2025-08-05 19:04:23,670 - src.model.id_card_processor - INFO - Enhancing im12_card_1.jpg -2025-08-05 19:04:23,671 - src.model.id_card_processor - INFO - Normalizing im12_card_1.jpg -2025-08-05 19:04:23,675 - src.model.id_card_processor - INFO - Processed im12_card_1.jpg -2025-08-05 19:04:23,676 - src.model.id_card_processor - INFO - Processing 5/42: im12_card_2.jpg -2025-08-05 19:04:23,686 - src.model.id_card_processor - INFO - Removing background from im12_card_2.jpg -2025-08-05 19:04:29,279 - src.model.id_card_processor - INFO - Enhancing im12_card_2.jpg -2025-08-05 19:04:29,284 - src.model.id_card_processor - INFO - Normalizing im12_card_2.jpg -2025-08-05 19:04:29,289 - src.model.id_card_processor - INFO - Processed im12_card_2.jpg -2025-08-05 19:04:29,290 - src.model.id_card_processor - INFO - Processing 6/42: im14_card_1.jpg -2025-08-05 19:04:29,301 - src.model.id_card_processor - INFO - Removing background from im14_card_1.jpg -2025-08-05 19:04:29,774 - src.model.id_card_processor - INFO - Enhancing im14_card_1.jpg -2025-08-05 19:04:29,775 - src.model.id_card_processor - INFO - Normalizing im14_card_1.jpg -2025-08-05 19:04:29,779 - src.model.id_card_processor - INFO - Processed im14_card_1.jpg -2025-08-05 19:04:29,780 - src.model.id_card_processor - INFO - Processing 7/42: im15_card_1.jpg -2025-08-05 19:04:29,791 - src.model.id_card_processor - INFO - Removing background from im15_card_1.jpg -2025-08-05 19:04:30,009 - src.model.id_card_processor - INFO - Enhancing im15_card_1.jpg -2025-08-05 19:04:30,010 - src.model.id_card_processor - INFO - Normalizing im15_card_1.jpg -2025-08-05 19:04:30,015 - src.model.id_card_processor - INFO - Processed im15_card_1.jpg -2025-08-05 19:04:30,015 - src.model.id_card_processor - INFO - Processing 8/42: im2_card_1.jpg -2025-08-05 19:04:30,017 - src.model.id_card_processor - INFO - Removing background from im2_card_1.jpg -2025-08-05 19:04:31,861 - src.model.id_card_processor - INFO - Enhancing im2_card_1.jpg -2025-08-05 19:04:31,863 - src.model.id_card_processor - INFO - Normalizing im2_card_1.jpg -2025-08-05 19:04:31,869 - src.model.id_card_processor - INFO - Processed im2_card_1.jpg -2025-08-05 19:04:31,869 - src.model.id_card_processor - INFO - Processing 9/42: im2_card_2.jpg -2025-08-05 19:04:31,884 - src.model.id_card_processor - INFO - Removing background from im2_card_2.jpg -2025-08-05 19:04:38,985 - src.model.id_card_processor - INFO - Enhancing im2_card_2.jpg -2025-08-05 19:04:38,996 - src.model.id_card_processor - INFO - Normalizing im2_card_2.jpg -2025-08-05 19:04:39,007 - src.model.id_card_processor - INFO - Processed im2_card_2.jpg -2025-08-05 19:04:39,008 - src.model.id_card_processor - INFO - Processing 10/42: im3_card_1.jpg -2025-08-05 19:04:39,009 - src.model.id_card_processor - INFO - Removing background from im3_card_1.jpg -2025-08-05 19:04:39,177 - src.model.id_card_processor - INFO - Enhancing im3_card_1.jpg -2025-08-05 19:04:39,178 - src.model.id_card_processor - INFO - Normalizing im3_card_1.jpg -2025-08-05 19:04:39,182 - src.model.id_card_processor - INFO - Processed im3_card_1.jpg -2025-08-05 19:04:39,182 - src.model.id_card_processor - INFO - Processing 11/42: im4_card_1.jpg -2025-08-05 19:04:39,184 - src.model.id_card_processor - INFO - Removing background from im4_card_1.jpg -2025-08-05 19:04:39,374 - src.model.id_card_processor - INFO - Enhancing im4_card_1.jpg -2025-08-05 19:04:39,375 - src.model.id_card_processor - INFO - Normalizing im4_card_1.jpg -2025-08-05 19:04:39,379 - src.model.id_card_processor - INFO - Processed im4_card_1.jpg -2025-08-05 19:04:39,379 - src.model.id_card_processor - INFO - Processing 12/42: im5_card_1.jpg -2025-08-05 19:04:39,389 - src.model.id_card_processor - INFO - Removing background from im5_card_1.jpg -2025-08-05 19:04:39,842 - src.model.id_card_processor - INFO - Enhancing im5_card_1.jpg -2025-08-05 19:04:39,843 - src.model.id_card_processor - INFO - Normalizing im5_card_1.jpg -2025-08-05 19:04:39,846 - src.model.id_card_processor - INFO - Processed im5_card_1.jpg -2025-08-05 19:04:39,846 - src.model.id_card_processor - INFO - Processing 13/42: im5_card_2.jpg -2025-08-05 19:04:39,859 - src.model.id_card_processor - INFO - Removing background from im5_card_2.jpg -2025-08-05 19:04:42,430 - src.model.id_card_processor - INFO - Enhancing im5_card_2.jpg -2025-08-05 19:04:42,434 - src.model.id_card_processor - INFO - Normalizing im5_card_2.jpg -2025-08-05 19:04:42,438 - src.model.id_card_processor - INFO - Processed im5_card_2.jpg -2025-08-05 19:04:42,439 - src.model.id_card_processor - INFO - Processing 14/42: im6_card_1.jpg -2025-08-05 19:04:42,449 - src.model.id_card_processor - INFO - Removing background from im6_card_1.jpg -2025-08-05 19:04:47,647 - src.model.id_card_processor - INFO - Enhancing im6_card_1.jpg -2025-08-05 19:04:47,652 - src.model.id_card_processor - INFO - Normalizing im6_card_1.jpg -2025-08-05 19:04:47,657 - src.model.id_card_processor - INFO - Processed im6_card_1.jpg -2025-08-05 19:04:47,657 - src.model.id_card_processor - INFO - Processing 15/42: im6_card_2.jpg -2025-08-05 19:04:47,680 - src.model.id_card_processor - INFO - Removing background from im6_card_2.jpg diff --git a/src/__init__.py b/src/__init__.py index 47078f4..ad079ad 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -1,9 +1,9 @@ """ -Data Augmentation Package +Data Augmentation Package for ID Cards """ -__version__ = "1.0.0" -__author__ = "OCR Data Augmentation Tool" +__version__ = "2.0.0" +__author__ = "ID Card Data Augmentation Tool" from .utils import * from .image_processor import ImageProcessor @@ -12,12 +12,12 @@ from .config_manager import ConfigManager __all__ = [ "ImageProcessor", - "DataAugmentation", + "DataAugmentation", "ConfigManager", "setup_logging", "get_image_files", "load_image", "save_image", - "validate_image", + "create_augmented_filename", "print_progress", ] \ No newline at end of file diff --git a/src/__pycache__/__init__.cpython-313.pyc b/src/__pycache__/__init__.cpython-313.pyc deleted file mode 100644 index 49581cad59e510881d38143517717adc2f997416..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 589 zcmZWlO>5gg5Z#p}%U&b9ff7o4(N!rp>8TJ(p(GS)(>ATzn_yYw&1Q+L6}u}#d`kX7 zFZ~g{_kZ+S7JN!Cy`}XZ=txRGpmP}B3^Q-un{5;k1o7qbhqG&p&~;P%4(}Fhp9A=a zQlwFeHBLS4rM=Xj_a1vO0u;>sS)hX!_vigtsKXYA^TBMWhcVhm>EI34L<|$Men5_y zW%09GEO}{}m8y(SSboj~C+pzR^k90hzW@5@ZT$b(JEe;6pb{n6;XO#>7fV<>(JJT0 zC=H!E&DOu%(2I^#c`C(AR>H7OhS~=T9W<#A$wh|Sx}t>=LYBf!1h-T+#Pn1a+&EGw zw&*&J7`EcKc)VhTTrm5muCy#It+Wyv^t?(&E~Ip!a!TEZ(iPVR%tApZWwkw18gNis zSr|9z4#I9{rPb(mfStkY-&eJ=-8gR@(Pd|;vjMkQQBe8`ZNU|Cd--AZ-oVkU6!itq zj=4Fvs>0yk2cpmm|257Q-Ir0hcAv;+VE diff --git a/src/__pycache__/__init__.cpython-39.pyc b/src/__pycache__/__init__.cpython-39.pyc deleted file mode 100644 index 9f1a7a0866e72a66b9e1b0a522636a7980d2075b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 559 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 TxC31)L%vcYuY<(jOX`0B6u*8o diff --git a/src/__pycache__/image_processor.cpython-39.pyc b/src/__pycache__/image_processor.cpython-39.pyc deleted file mode 100644 index 93f0a66971a81c47e97ff7ce74af5194986183ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5218 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 diff --git a/src/__pycache__/utils.cpython-39.pyc b/src/__pycache__/utils.cpython-39.pyc deleted file mode 100644 index b62b19a15b19d1660e5af26da604618214e16804..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3426 zcmZWsTXPi074Gi2>_yr|hy@Fa*aMi$5Sw5^B`$&;gOG?4At{nD#YEK9XuEeAF}t(w z=~dXRmCIG4@ezuz^_ZPF9XD`0rJ&R)2W2B; zNhPS5`PEXAVGCE-rwOk@Ho+&K+re?jrg;th zIzNW~34R`ul4yuVi=8H-EGD*3V#U-eiy!CH&~l1@re&Dbz{V4(pW+_&aCRM!_98HKMV=E13NLs^l_k{AIB=KVHMP3W0 zf=kM@hvH|ajTWnE54Jv;u%~t)3p*^p4;st-IB*} z`rOS@sRZ|J*+4fqzW!i!b!Ba1{%*LivUdOW#(F+s_7Bbefdvi5_(d_TRU89S;gLx* z5N350gq308GX74{GgQt(0_#?bsXYYGPtD6P=bd@i&>4OO_l6Po>EC8{>4?5z`(Uhx zFuF}_vIqC?PJKzTE7u^^e~*e$1hq|+HCQ^7a%-Jj!zvRbXTOV*7+x*BxMd9M#hDj* zJ6c+pdwF94Ceh)T+i6d919wNrxHZTt^Us>Xgt*V-8H@*3+-ZMklDbia4GO!Q$Gl9t z9bpU}cagd%<)`TTmQj*Vs7PuvX7NxIR?(I?{It_)IyX-D7c_}vaSgMt_S+C_Zh~hyo0tgLJPIa*$Ydrcu0(mN`oIM*@Yd4=TwRNTnrqj%& zb=sivGDhBpD4_Wws(d2tt6pD)+I{oV_kFmG8qDfl7fWe7QW>0ZvH9z^MY9sKLnwdA!HT*|mSL zxeJ_3%i!d|<4eQo^=M}dj;B)N^Bai8QZJH7Y*}753=yVJhbIc4vS{Z$PVy{nu)N?` zfSu+SO1Kl-@ zj_JQsCyqT`r!1`}(a`{H%z#qv+{)(+HY)(|Sf^8!^J^h{5V$A=i_3pA`*#1-iK{2bgF45N8dXD{=b7$;FNW|^FZfpzUV*N=!yiH^LA zz2prPa5wz~kiR?>$Y1H!2X;8!G)lo{JJa+<;K|ce{u(Wv+4O0Q4Sq_! z`u(9v$6Q*|cahDu;iBeBYLkfo6v3nEVaed3jZ)ZNzv6la!i$sl79IRH`C8ntDVR=nQ?ud-&Qzm~@)*f;XuLJ#K!|7E`M_zAy8*eL;Z#AH8{O~>c z_N_Me0sZ=besMr+L+hsZry+an4Xq2_tdKnIEL0j&~w2$oVw7_4g zh@6uA8hYe6y7(=Mpo*RF$n3V&lb{AuCvb{!w~QxOQ%8GXVbX`#)D3}#hbIo8Y@Ebx zI)en>pr3;tEfOUI;wYs=ul5jyIZt)&8&ouLz$nC8(O-v${i%<}h zx*Ru)28Oq#j$GsU@(;SD9n75n$kk0inO98tRww2CM0}%x$#hP!E&X(v#LZ338k3EQ Osmi&=%+x7&%Kje`FF>yV diff --git a/src/config.py b/src/config.py deleted file mode 100644 index 2231176..0000000 --- a/src/config.py +++ /dev/null @@ -1,40 +0,0 @@ -""" -Configuration file for data augmentation -""" -import os -from pathlib import Path - -# Paths -BASE_DIR = Path(__file__).parent.parent -DATA_DIR = BASE_DIR / "data" -INPUT_IMAGES_DIR = DATA_DIR / "dataset" / "training_data" / "images" -OUTPUT_DIR = DATA_DIR / "augmented_data" - -# Data augmentation parameters -AUGMENTATION_CONFIG = { - "rotation_range": 15, # degrees - "width_shift_range": 0.1, # fraction of total width - "height_shift_range": 0.1, # fraction of total height - "brightness_range": [0.8, 1.2], # brightness factor - "zoom_range": [0.9, 1.1], # zoom factor - "horizontal_flip": True, - "vertical_flip": False, - "fill_mode": "nearest", - "cval": 0, - "rescale": 1./255, -} - -# Processing parameters -PROCESSING_CONFIG = { - "target_size": (224, 224), # (width, height) - "batch_size": 32, - "num_augmentations": 3, # number of augmented versions per image - "save_format": "jpg", - "quality": 95, -} - -# Supported image formats -SUPPORTED_FORMATS = ['.jpg', '.jpeg', '.png', '.bmp', '.tiff'] - -# Create output directory if it doesn't exist -OUTPUT_DIR.mkdir(parents=True, exist_ok=True) \ No newline at end of file diff --git a/src/data_augmentation.py b/src/data_augmentation.py index 430ee79..fbc9b63 100644 --- a/src/data_augmentation.py +++ b/src/data_augmentation.py @@ -1,5 +1,5 @@ """ -Data augmentation class for image augmentation - ONLY ROTATION +Data augmentation class for image augmentation - ONLY ROTATION with quality preservation """ import cv2 import numpy as np @@ -23,32 +23,134 @@ class DataAugmentation: self.config = config or {} self.image_processor = ImageProcessor() - def rotate_image(self, image: np.ndarray, angle: float) -> np.ndarray: + def rotate_image_preserve_quality(self, image: np.ndarray, angle: float) -> np.ndarray: """ - Rotate image by given angle + Rotate image by given angle with white background and crop to preserve quality Args: image: Input image angle: Rotation angle in degrees Returns: - Rotated image + Rotated and cropped image """ height, width = image.shape[:2] - center = (width // 2, height // 2) + + # Calculate new dimensions for rotation + angle_rad = math.radians(angle) + cos_val = abs(math.cos(angle_rad)) + sin_val = abs(math.sin(angle_rad)) + + # Calculate new width and height + new_width = int(width * cos_val + height * sin_val) + new_height = int(height * cos_val + width * sin_val) + + # Create larger canvas with white background + canvas = np.ones((new_height, new_width, 3), dtype=np.uint8) * 255 + + # Calculate offset to center the image + offset_x = (new_width - width) // 2 + offset_y = (new_height - height) // 2 + + # Ensure offsets are valid + if offset_x >= 0 and offset_y >= 0 and offset_x + width <= new_width and offset_y + height <= new_height: + # Place original image in center of canvas + canvas[offset_y:offset_y+height, offset_x:offset_x+width] = image + else: + # If calculation is wrong, use a simpler approach + canvas = np.ones((max(height, width) * 2, max(height, width) * 2, 3), dtype=np.uint8) * 255 + center_y, center_x = canvas.shape[0] // 2, canvas.shape[1] // 2 + start_y = center_y - height // 2 + start_x = center_x - width // 2 + canvas[start_y:start_y+height, start_x:start_x+width] = image + new_width, new_height = canvas.shape[1], canvas.shape[0] + + # Calculate center for rotation + center = (new_width // 2, new_height // 2) # Create rotation matrix rotation_matrix = cv2.getRotationMatrix2D(center, angle, 1.0) # Perform rotation - rotated = cv2.warpAffine(image, rotation_matrix, (width, height), - borderMode=cv2.BORDER_REPLICATE) + rotated = cv2.warpAffine(canvas, rotation_matrix, (new_width, new_height), + borderMode=cv2.BORDER_CONSTANT, borderValue=(255, 255, 255)) + + # Crop white borders to get the actual image content + rotated = self._crop_white_borders(rotated) return rotated + def _crop_white_borders(self, image: np.ndarray) -> np.ndarray: + """ + Crop white borders from image to get the actual content + + Args: + image: Input image with white borders + + Returns: + Cropped image without white borders + """ + # Convert to grayscale for edge detection + gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) + + # Find non-white pixels (content) + non_white = gray < 250 # Threshold for white pixels + + # Find bounding box of content + coords = cv2.findNonZero(non_white.astype(np.uint8)) + if coords is not None: + x, y, w, h = cv2.boundingRect(coords) + return image[y:y+h, x:x+w] + + return image + + def resize_preserve_aspect(self, image: np.ndarray, target_size: Tuple[int, int]) -> np.ndarray: + """ + Resize image preserving aspect ratio with white padding + + Args: + image: Input image + target_size: Target size (width, height) + + Returns: + Resized image with preserved aspect ratio + """ + target_width, target_height = target_size + img_height, img_width = image.shape[:2] + + # Calculate aspect ratios + target_aspect = target_width / target_height + img_aspect = img_width / img_height + + if img_aspect > target_aspect: + # Image is wider than target + new_width = target_width + new_height = int(target_width / img_aspect) + else: + # Image is taller than target + new_height = target_height + new_width = int(target_height * img_aspect) + + # Resize image + resized = cv2.resize(image, (new_width, new_height), interpolation=cv2.INTER_AREA) + + # Create white background + result = np.ones((target_height, target_width, 3), dtype=np.uint8) * 255 + + # Calculate offset to center the image + offset_x = (target_width - new_width) // 2 + offset_y = (target_height - new_height) // 2 + + # Place resized image in center + result[offset_y:offset_y+new_height, offset_x:offset_x+new_width] = resized + + return result + + + def augment_single_image(self, image: np.ndarray, num_augmentations: int = None) -> List[np.ndarray]: """ - Apply rotation augmentation to a single image + Apply rotation augmentation to a single image with quality preservation Args: image: Input image @@ -65,12 +167,18 @@ class DataAugmentation: angles = rotation_config.get("angles", [30, 60, 120, 150, 180, 210, 240, 300, 330]) for i in range(num_augmentations): + # Start with original image augmented = image.copy() - # Apply rotation with random angle from the specified list + # Apply rotation with quality preservation if rotation_config.get("enabled", False): angle = random.choice(angles) - augmented = self.rotate_image(augmented, angle) + augmented = self.rotate_image_preserve_quality(augmented, angle) + + # Resize preserving aspect ratio + target_size = self.image_processor.target_size + if target_size: + augmented = self.resize_preserve_aspect(augmented, target_size) augmented_images.append(augmented) @@ -78,7 +186,7 @@ class DataAugmentation: def augment_image_file(self, image_path: Path, output_dir: Path, num_augmentations: int = None) -> List[Path]: """ - Augment a single image file and save results + Augment a single image file and save results with quality preservation Args: image_path: Path to input image @@ -88,8 +196,8 @@ class DataAugmentation: Returns: List of paths to saved augmented images """ - # Load image - image = load_image(image_path, self.image_processor.target_size) + # Load image without resizing to preserve original quality + image = load_image(image_path, None) # Load original size if image is None: return [] diff --git a/src/image_processor.py b/src/image_processor.py index 46c3111..f082219 100644 --- a/src/image_processor.py +++ b/src/image_processor.py @@ -1,14 +1,14 @@ """ -Image processing class for basic image operations +Image processing class for data augmentation """ import cv2 import numpy as np from pathlib import Path -from typing import Tuple, Optional, List -from utils import load_image, save_image, validate_image, get_image_files +from typing import Tuple, Optional +from utils import load_image class ImageProcessor: - """Class for basic image processing operations""" + """Class for image processing operations used in data augmentation""" def __init__(self, target_size: Tuple[int, int] = None): """ @@ -17,67 +17,7 @@ class ImageProcessor: Args: target_size: Target size for image resizing (width, height) """ - self.target_size = target_size or (224, 224) # Default size - - def load_and_preprocess(self, image_path: Path) -> Optional[np.ndarray]: - """ - Load and preprocess image - - Args: - image_path: Path to image file - - Returns: - Preprocessed image as numpy array or None if failed - """ - if not validate_image(image_path): - print(f"Invalid image file: {image_path}") - return None - - image = load_image(image_path, self.target_size) - if image is None: - return None - - # Normalize pixel values - image = image.astype(np.float32) / 255.0 - - return image - - def resize_image(self, image: np.ndarray, target_size: Tuple[int, int]) -> np.ndarray: - """ - Resize image to target size - - Args: - image: Input image as numpy array - target_size: Target size (width, height) - - Returns: - Resized image - """ - return cv2.resize(image, target_size, interpolation=cv2.INTER_AREA) - - def normalize_image(self, image: np.ndarray) -> np.ndarray: - """ - Normalize image pixel values to [0, 1] - - Args: - image: Input image - - Returns: - Normalized image - """ - return image.astype(np.float32) / 255.0 - - def denormalize_image(self, image: np.ndarray) -> np.ndarray: - """ - Denormalize image pixel values to [0, 255] - - Args: - image: Input image (normalized) - - Returns: - Denormalized image - """ - return (image * 255).astype(np.uint8) + self.target_size = target_size or (640, 640) # Default size for ID cards def get_image_info(self, image_path: Path) -> dict: """ @@ -107,68 +47,4 @@ class ImageProcessor: } except Exception as e: print(f"Error getting image info for {image_path}: {e}") - return {} - - def batch_process_images(self, input_dir: Path, output_dir: Path) -> List[Path]: - """ - Process all images in a directory - - Args: - input_dir: Input directory containing images - output_dir: Output directory for processed images - - Returns: - List of processed image paths - """ - image_files = get_image_files(input_dir) - processed_files = [] - - print(f"Found {len(image_files)} images to process") - - for i, image_path in enumerate(image_files): - print_progress(i + 1, len(image_files), "Processing images") - - # Load and preprocess image - image = self.load_and_preprocess(image_path) - if image is None: - continue - - # Create output path - output_path = output_dir / image_path.name - - # Denormalize for saving - image = self.denormalize_image(image) - - # Save processed image - if save_image(image, output_path): - processed_files.append(output_path) - - print(f"\nProcessed {len(processed_files)} images successfully") - return processed_files - - def create_thumbnail(self, image: np.ndarray, size: Tuple[int, int] = (100, 100)) -> np.ndarray: - """ - Create thumbnail of image - - Args: - image: Input image - size: Thumbnail size (width, height) - - Returns: - Thumbnail image - """ - return cv2.resize(image, size, interpolation=cv2.INTER_AREA) - - def convert_to_grayscale(self, image: np.ndarray) -> np.ndarray: - """ - Convert image to grayscale - - Args: - image: Input image (RGB) - - Returns: - Grayscale image - """ - if len(image.shape) == 3: - return cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) - return image \ No newline at end of file + return {} \ No newline at end of file diff --git a/src/model/__init__.py b/src/model/YOLO_processor/__init__.py similarity index 100% rename from src/model/__init__.py rename to src/model/YOLO_processor/__init__.py diff --git a/src/model/id_card_processor.py b/src/model/YOLO_processor/id_card_processor.py similarity index 100% rename from src/model/id_card_processor.py rename to src/model/YOLO_processor/id_card_processor.py diff --git a/src/model/roboflow_id_detector.py b/src/model/YOLO_processor/roboflow_id_detector.py similarity index 100% rename from src/model/roboflow_id_detector.py rename to src/model/YOLO_processor/roboflow_id_detector.py diff --git a/src/model/__pycache__/__init__.cpython-313.pyc b/src/model/__pycache__/__init__.cpython-313.pyc deleted file mode 100644 index d7e494eee2bd02668f0f74449f0002de015f1715..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 338 zcmXv~u}Z{15Z&EGE<~;oL9lV#6l!H7DuMwyMGJ%7!jjAG<$~*On9U()=O)a+jig?We8A)GjfS92oQ?0 zU>`$JhRNFFX?$gbRP^46nUZv3fZmv~nJDwHJI<{Xbd=H}2SJ5wWYJVc(_9N$fT`cdD-zsptlCCt`p+}~fh%1nVLRYln1b_m6Z+Y_5_~zZr+H4U6z8v~^Wxj%vqN@k zC0M4**<7+z+PlWoY?OL6_FQTSd1HWCD40_(72~|pRm1sSJ#V9<d5h`O03uiW1Fb4z;Q#;t diff --git a/src/model/__pycache__/__init__.cpython-39.pyc b/src/model/__pycache__/__init__.cpython-39.pyc deleted file mode 100644 index 232e1913c3eeb167304b6da57570e38f81a51a99..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 318 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 diff --git a/src/model/__pycache__/roboflow_id_detector.cpython-313.pyc b/src/model/__pycache__/roboflow_id_detector.cpython-313.pyc deleted file mode 100644 index 78cb388affa8f7fd19b4ab140d633bb548b4c351..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14131 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 diff --git a/src/model/__pycache__/roboflow_id_detector.cpython-39.pyc b/src/model/__pycache__/roboflow_id_detector.cpython-39.pyc deleted file mode 100644 index 3138a0d968bb717d25b31c9883c1ffbad87a4a8f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9059 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 diff --git a/src/model/__pycache__/yolo_detector.cpython-39.pyc b/src/model/__pycache__/yolo_detector.cpython-39.pyc deleted file mode 100644 index 300f3a968306aa66582af7ff3e98276e055c5787..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7117 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

-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 MH07#%K~PiqKVW+n&Hw-a diff --git a/src/utils.py b/src/utils.py index fa7f80a..816baa8 100644 --- a/src/utils.py +++ b/src/utils.py @@ -32,14 +32,7 @@ def get_image_files(directory: Path) -> List[Path]: image_files.extend(directory.glob(f"*{ext.upper()}")) return sorted(image_files) -def validate_image(image_path: Path) -> bool: - """Validate if file is a valid image""" - try: - with Image.open(image_path) as img: - img.verify() - return True - except Exception: - return False + def load_image(image_path: Path, target_size: Tuple[int, int] = None) -> Optional[np.ndarray]: """Load and resize image""" @@ -83,9 +76,7 @@ def create_augmented_filename(original_path: Path, index: int, suffix: str = "au suffix = f"_{suffix}_{index:02d}" return original_path.parent / f"{stem}{suffix}{original_path.suffix}" -def get_file_size_mb(file_path: Path) -> float: - """Get file size in MB""" - return file_path.stat().st_size / (1024 * 1024) + def print_progress(current: int, total: int, prefix: str = "Progress"): """Print progress bar"""