AsyiraFitri commited on
Commit
71870f0
·
1 Parent(s): b6e2fe9

output update

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. README.md +30 -0
  2. project_a_output_progress/project_a_overview.md +340 -0
  3. project_a_output_progress/synthetic/doc_001_chinese_employee_application_forged.png +3 -0
  4. project_a_output_progress/synthetic/doc_002_chinese_service_application_genuine.png +3 -0
  5. project_a_output_progress/synthetic/doc_003_tamil_public_service_forged.png +3 -0
  6. project_a_output_progress/synthetic/doc_004_chinese_service_application_genuine.png +3 -0
  7. project_a_output_progress/synthetic/doc_005_tamil_public_service_genuine.png +3 -0
  8. project_a_output_progress/synthetic/doc_006_tamil_public_service_genuine.png +3 -0
  9. project_a_output_progress/synthetic/doc_007_corporate_account_application_genuine.png +3 -0
  10. project_a_output_progress/synthetic/doc_008_shareholder_resolution_forged.png +3 -0
  11. project_a_output_progress/synthetic/doc_009_tamil_public_service_genuine.png +3 -0
  12. project_a_output_progress/synthetic/doc_010_wealth_management_forged.png +3 -0
  13. project_a_output_progress/synthetic/doc_011_corporate_account_application_genuine.png +3 -0
  14. project_a_output_progress/synthetic/doc_012_tamil_residence_assessment_forged.png +3 -0
  15. project_a_output_progress/synthetic/doc_013_bank_account_opening_forged.png +3 -0
  16. project_a_output_progress/synthetic/doc_014_chinese_service_application_genuine.png +3 -0
  17. project_a_output_progress/synthetic/doc_015_tamil_trade_license_forged.png +3 -0
  18. project_a_output_progress/synthetic/doc_016_cheque_standard_clearing_genuine.png +3 -0
  19. project_a_output_progress/synthetic/doc_017_wealth_management_genuine.png +3 -0
  20. project_a_output_progress/synthetic/doc_018_cheque_standard_clearing_genuine.png +3 -0
  21. project_a_output_progress/synthetic/doc_019_bank_account_opening_forged.png +3 -0
  22. project_a_output_progress/synthetic/doc_020_wealth_management_forged.png +3 -0
  23. project_a_output_progress/synthetic/doc_021_shareholder_resolution_forged.png +3 -0
  24. project_a_output_progress/synthetic/doc_022_cheque_continental_trust_forged.png +3 -0
  25. project_a_output_progress/synthetic/doc_023_chinese_employee_application_forged.png +3 -0
  26. project_a_output_progress/synthetic/doc_024_corporate_account_application_genuine.png +3 -0
  27. project_a_output_progress/synthetic/doc_025_tamil_trade_license_genuine.png +3 -0
  28. project_a_output_progress/synthetic/doc_026_shareholder_resolution_genuine.png +3 -0
  29. project_a_output_progress/synthetic/doc_027_wealth_management_forged.png +3 -0
  30. project_a_output_progress/synthetic/doc_028_corporate_account_application_forged.png +3 -0
  31. project_a_output_progress/synthetic/doc_029_corporate_account_application_genuine.png +3 -0
  32. project_a_output_progress/synthetic/doc_030_chinese_service_application_genuine.png +3 -0
  33. project_a_output_progress/synthetic/doc_031_banking_authorization_forged.png +3 -0
  34. project_a_output_progress/synthetic/doc_032_banking_authorization_genuine.png +3 -0
  35. project_a_output_progress/synthetic/doc_033_cheque_global_merchant_forged.png +3 -0
  36. project_a_output_progress/synthetic/doc_034_tamil_public_service_genuine.png +3 -0
  37. project_a_output_progress/synthetic/doc_035_tamil_trade_license_forged.png +3 -0
  38. project_a_output_progress/synthetic/doc_036_tamil_trade_license_forged.png +3 -0
  39. project_a_output_progress/synthetic/doc_037_cheque_global_merchant_genuine.png +3 -0
  40. project_a_output_progress/synthetic/doc_038_bank_account_opening_genuine.png +3 -0
  41. project_a_output_progress/synthetic/doc_039_shareholder_resolution_forged.png +3 -0
  42. project_a_output_progress/synthetic/doc_040_chinese_service_application_forged.png +3 -0
  43. project_a_output_progress/synthetic/doc_041_chinese_employee_application_genuine.png +3 -0
  44. project_a_output_progress/synthetic/doc_042_banking_authorization_forged.png +3 -0
  45. project_a_output_progress/synthetic/doc_043_chinese_employee_application_genuine.png +3 -0
  46. project_a_output_progress/synthetic/doc_044_bank_account_opening_genuine.png +3 -0
  47. project_a_output_progress/synthetic/doc_045_cheque_continental_trust_forged.png +3 -0
  48. project_a_output_progress/synthetic/doc_046_chinese_business_registration_forged.png +3 -0
  49. project_a_output_progress/synthetic/doc_047_tamil_residence_assessment_forged.png +3 -0
  50. project_a_output_progress/synthetic/doc_048_tamil_public_service_genuine.png +3 -0
README.md ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Progress Update
2
+
3
+ ---
4
+
5
+ ## Project A — Synthetic Test Data Generation
6
+
7
+ [Project A Overview](project_a_output_progress/project_a_overview.md)
8
+
9
+ ### What's Done
10
+
11
+ **Signature Pasting Pipeline**
12
+ Signatures from CEDAR and SigNet are cleaned, augmented, and pasted onto document templates. Signature field coordinates are currently hardcoded — obtained by running `pdfplumber` on the original born-digital PDF templates and converting PDF point coordinates to PNG pixel coordinates.
13
+
14
+ > [Document Template](project_a_output_progress/templates)
15
+
16
+ > [View Synthetic Dataset Output](project_a_output_progress/synthetic)
17
+
18
+ ---
19
+
20
+ **Field Auto-Detection** *(in progress)*
21
+ Currently working on automatically detecting signature and other fields from the template images using OpenCV, so the pipeline works even when new templates are added without needing to manually measure coordinates.
22
+
23
+ > [View Field Validation Overlays](project_a_output_progress/validation_overlays)
24
+
25
+ ---
26
+
27
+ **Test Cases** *(in progress)*
28
+ 50 structured test cases generated across 5 scenario types (PASS, NO_SIGNATURE, WRONG_PERSON, WRONG_ROLE, REQUIRED_PERSON_MISSING). Each case folder contains the generated document, reference signature images, and a `ground_truth.json`.
29
+
30
+ > [View Test Cases Output](project_a_output_progress/test_cases)
project_a_output_progress/project_a_overview.md ADDED
@@ -0,0 +1,340 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Project A — Synthetic Signature Dataset: Technical Overview
2
+
3
+ ## What the Project Does
4
+
5
+ Project A generates a **synthetic dataset of signed documents** for training and testing a signature verification model. Real signature images are taken from public datasets, cleaned up, and pasted onto document templates to produce labelled images — each one recording whether the signature on it is genuine or forged, and who signed where.
6
+
7
+ The project has two main components:
8
+
9
+ - **`prepare_signatures.py`** — loads signature images from datasets, removes backgrounds, and applies augmentation
10
+ - **`synthesize_documents.py`** — pastes prepared signatures onto document templates and builds the labelled dataset
11
+ - **`generate_test_cases.py`** — generates a structured 50-case test suite with ground truth labels across 5 failure scenarios
12
+
13
+ ---
14
+
15
+ ## Datasets Used
16
+
17
+ | Dataset | What it contains | How it is used |
18
+ |---|---|---|
19
+ | CEDAR | Genuine and forged signatures in flat folders (`full_org`, `full_forg`) | Loaded as a flat list of file paths |
20
+ | SigNet | Genuine and forged signatures organised per writer (`001/`, `001_forg/`, etc.) | Loaded per writer so writer identity is preserved |
21
+ | GPDS | Small sample only | Not actively used yet — reserved for future work |
22
+
23
+ ---
24
+
25
+ ## File 1: `prepare_signatures.py`
26
+
27
+ This file handles everything to do with **loading and preparing signature images** before they are pasted onto documents.
28
+
29
+ ### Loading Functions
30
+
31
+ **`list_signature_files(folder)`**
32
+
33
+ Scans a folder and returns all image file paths with valid extensions (`.png`, `.jpg`, `.jpeg`, `.tif`, `.bmp`). Used internally by other loading functions.
34
+
35
+ **`load_cedar_signatures(genuine, limit)`**
36
+
37
+ Loads CEDAR signature file paths. Pass `genuine=True` for real signatures, `False` for forged ones. The `limit` parameter allows loading a small sample for quick testing.
38
+
39
+ **`list_signet_writer_ids(split)`**
40
+
41
+ Lists all writer IDs available in SigNet for a given split (`"train"` or `"test"`). A writer is only included if both their genuine folder and their forged folder exist, ensuring no incomplete writers are returned.
42
+
43
+ **`load_signet_signatures(writer_id, split, genuine)`**
44
+
45
+ Loads signature file paths for a single writer in SigNet. This is per-writer (unlike CEDAR's flat load) because SigNet's folder structure is organised by writer, and knowing which writer a signature belongs to is needed for hard-negative sampling in later work (e.g. deliberately picking visually similar writers as tricky negatives).
46
+
47
+ **`load_signet_all(split, limit_writers)`**
48
+
49
+ Convenience wrapper that calls `load_signet_signatures()` for every available writer and returns one flat list. Each entry is a dictionary with the fields:
50
+
51
+ ```
52
+ {
53
+ "path": "/path/to/sig.png",
54
+ "writer_id": "001",
55
+ "label": "genuine" or "forged",
56
+ "source": "signet"
57
+ }
58
+ ```
59
+
60
+ This is the function `synthesize_documents.py` calls when building the signature pool.
61
+
62
+ ---
63
+
64
+ ### Background Removal
65
+
66
+ **`remove_background(image_path, threshold=200)`**
67
+
68
+ Loads a signature image and removes its white or light-coloured background using **OpenCV grayscale thresholding**:
69
+
70
+ 1. Convert the image to grayscale
71
+ 2. Any pixel brighter than the threshold (default 200) is treated as background
72
+ 3. Build an alpha channel from that mask so background pixels become transparent
73
+ 4. Return a BGRA (OpenCV) image with a transparent background
74
+
75
+ This is a simple, no-ML approach that works well for offline signature scans which typically have a white paper background.
76
+
77
+ **`crop_to_content(rgba_image, padding=5)`**
78
+
79
+ Finds the bounding box of all non-transparent pixels in the BGRA image and crops tightly around the signature ink, with a small padding margin. This removes excess whitespace so the signature fits neatly inside a document's signature box.
80
+
81
+ ---
82
+
83
+ ### Augmentation
84
+
85
+ Augmentation adds variation to the signatures so the model does not overfit to a fixed set of images. Three individual transforms are available, and one combined function applies them randomly.
86
+
87
+ **`augment_rotate(rgba_image, max_angle=10)`**
88
+
89
+ Randomly rotates the signature between −10° and +10° using `cv2.getRotationMatrix2D` and `warpAffine`. The border fill is transparent so no white rectangle is introduced.
90
+
91
+ **`augment_scale(rgba_image, scale_range=(0.85, 1.15))`**
92
+
93
+ Randomly resizes the signature to between 85% and 115% of its original size using `cv2.resize`.
94
+
95
+ **`augment_noise(rgba_image, amount=6)`**
96
+
97
+ Adds small random pixel noise (±6 per channel) to the RGB channels only, leaving the alpha channel unchanged. This simulates slight pen pressure variation or scan noise.
98
+
99
+ **`augment_signature(rgba_image)`**
100
+
101
+ Applies the three transforms above in combination with random probabilities:
102
+ - Rotation: 70% chance
103
+ - Scaling: 70% chance
104
+ - Noise: 50% chance
105
+
106
+ This is the function `synthesize_documents.py` calls when preparing each signature for pasting.
107
+
108
+ ---
109
+
110
+ ### Combined Pipeline
111
+
112
+ **`prepare_signature(image_path, threshold=200, padding=5, augment=False)`**
113
+
114
+ The full single-signature preparation pipeline in one call:
115
+
116
+ ```
117
+ cv2.imread() → remove_background() → crop_to_content() → [augment_signature()]
118
+ ```
119
+
120
+ Returns a BGRA numpy array ready to be pasted onto a document. Returns `None` if the image cannot be read. This is the main function called by the generation loop.
121
+
122
+ ---
123
+
124
+ ## File 2: `synthesize_documents.py`
125
+
126
+ This file handles **pasting prepared signatures onto document templates** and assembling the final labelled dataset.
127
+
128
+ ### Document Templates
129
+
130
+ The project uses **15 document templates** across 5 groups, stored as PNG files in `data/templates/`. The templates are real document layouts converted from PDF:
131
+
132
+ | Group | Documents |
133
+ |---|---|
134
+ | Banking forms | Bank account opening, corporate account application, wealth management |
135
+ | Corporate governance | Board resolution, banking authorisation, shareholder resolution |
136
+ | Chinese documents | Business registration, employee application, service application |
137
+ | Tamil documents | Public service, trade licence, residence assessment |
138
+ | Cheques | Continental Trust, Global Merchant, Standard Clearing |
139
+
140
+ ### Signature Box Coordinates
141
+
142
+ For each template, the pixel coordinates `(x1, y1, x2, y2)` of every signature field are hardcoded in the `DOCUMENT_TYPES` dictionary. These coordinates were measured once using `pdfplumber` on the original born-digital PDFs, then visually verified by cropping and inspecting each box. They are not detected at runtime — the pipeline reads the stored values directly.
143
+
144
+ This approach works reliably because the templates are fixed PNGs converted from those same PDFs at a consistent resolution (1241×1754 pixels at 150 dpi). If a template changes or is a scanned image at a different scale, the coordinates would need to be re-measured.
145
+
146
+ ---
147
+
148
+ ### Core Functions
149
+
150
+ **`remove_white_background(sig_pil)`**
151
+
152
+ A second, PIL-based background removal pass applied just before pasting. It converts the signature image to RGBA and sets any pixel where R > 200 AND G > 200 to fully transparent. This catches white and near-white paper while preserving ink — including blue ballpoint pen ink, which has a low green channel value and is not affected by this condition.
153
+
154
+ **`paste_signature(doc_pil, sig_pil, box)`**
155
+
156
+ The core pasting function. For each signature box it:
157
+
158
+ 1. Calls `remove_white_background()` to clean the signature
159
+ 2. Resizes it to fit inside the box using `thumbnail()` which preserves aspect ratio
160
+ 3. Applies a small random offset of ±5 pixels so signatures do not always land at the exact centre
161
+ 4. Converts the document to RGBA and pastes the signature using its alpha channel as a mask, so only ink pixels are blended in
162
+ 5. Applies a slight Gaussian blur (radius 0.3) to the whole document so the ink looks like it belongs on the paper rather than sitting on top of it
163
+ 6. Returns the final image as RGB
164
+
165
+ **`build_signature_pool()`**
166
+
167
+ Calls `load_cedar_signatures()` and `load_signet_all()` to combine all available signatures from both datasets into one flat pool. Each entry carries the file path, writer ID, label (genuine or forged), and source dataset. This pool is what the generation loop samples from randomly.
168
+
169
+ **`generate_synthetic_documents(num_documents=200)`**
170
+
171
+ The main generation loop. For each of the 200 documents it:
172
+
173
+ 1. Randomly picks a document type from `DOCUMENT_TYPES`
174
+ 2. Loads the corresponding template PNG
175
+ 3. For each signature box on that template, randomly picks a signature from the pool, runs it through `prepare_signature()` with augmentation, converts it from OpenCV BGRA to PIL RGBA, and calls `paste_signature()`
176
+ 4. Optional signature boxes (such as the officer rows in `banking_authorization`) have a 70% chance of being filled, simulating real documents that list one to three officers
177
+ 5. Labels the whole document as `"forged"` if any one signature on it is forged, otherwise `"genuine"`
178
+ 6. Saves the output PNG and appends a metadata row
179
+
180
+ **`write_dataset_csv(rows)`**
181
+
182
+ Writes metadata for all generated documents to `data/synthetic_dataset.csv`. Columns include filename, document type, group, overall label, number of signatures, and per-role details in the format `role:label:source`.
183
+
184
+ ---
185
+
186
+ ### What Gets Saved to Disk
187
+
188
+ | Item | Saved? | Location |
189
+ |---|---|---|
190
+ | Raw signature images | Never written — read-only inputs | `data/raw/` |
191
+ | Cleaned and augmented signatures | No — RAM only, discarded after pasting | — |
192
+ | Final document PNGs | Yes | `data/synthetic/doc_001_…_genuine.png` |
193
+ | Dataset metadata | Yes | `data/synthetic_dataset.csv` |
194
+
195
+ ---
196
+
197
+ ### Dataset Label Distribution
198
+
199
+ There is no fixed genuine-to-forged ratio. Because each document's overall label is `"forged"` if **any** signature on it is forged, documents with multiple signature boxes are more likely to be labelled forged — even with a 50/50 signature pool. For a document with three signature boxes, the probability of all three being genuine is only 12.5%, so the dataset will have significantly more forged documents than genuine ones by default.
200
+
201
+ To check the actual ratio after generation:
202
+
203
+ ```python
204
+ import pandas as pd
205
+ df = pd.read_csv("data/synthetic_dataset.csv")
206
+ print(df["label"].value_counts())
207
+ ```
208
+
209
+ ---
210
+
211
+ ## File 3: `generate_test_cases.py`
212
+
213
+ This file generates a **structured 50-case test suite** for evaluating a signature verification system. Each case is saved to its own folder and includes a generated document image, reference signature images, and a `ground_truth.json` file.
214
+
215
+ ### Test Case Types
216
+
217
+ | Type | Count | Description | Expected outcome | Rejection code |
218
+ |---|---|---|---|---|
219
+ | PASS | 20 | Correct person signs the correct field | ACCEPTED | — |
220
+ | NO_SIGNATURE | 5 | Signature fields left completely blank | REJECTED | `NO_SIGNATURE_FOUND` |
221
+ | WRONG_PERSON | 10 | An impostor's signature is pasted instead | REJECTED | `IDENTITY_MISMATCH` |
222
+ | WRONG_ROLE | 10 | Correct person but fields swapped | REJECTED | `WRONG_ROLE` |
223
+ | REQUIRED_PERSON_MISSING | 5 | One required field left blank on a multi-sig doc | REJECTED | `REQUIRED_SIGNATORY_MISSING` |
224
+
225
+ ### Persons
226
+
227
+ Ten named persons are defined, each mapped to a SigNet writer ID (`001`–`010`). Each person has 2–3 reference signature images copied from their genuine SigNet folder into the case directory as `reference_1.png`, `reference_2.png`, etc.
228
+
229
+ ### Output Structure
230
+
231
+ ```
232
+ data/test_cases/
233
+ case_001/
234
+ document.png ← generated document with signatures pasted
235
+ reference_1.png ← known-good reference signature
236
+ reference_2.png
237
+ reference_3.png
238
+ ground_truth.json ← case metadata and expected result
239
+ case_002/
240
+ ...
241
+ test_cases_summary.csv ← one row per case, all cases
242
+ ```
243
+
244
+ ### ground_truth.json Format
245
+
246
+ ```json
247
+ {
248
+ "case_id": "case_003",
249
+ "type": "WRONG_PERSON",
250
+ "document_type": "board_resolution",
251
+ "expected_outcome": "REJECTED",
252
+ "expected_rejection_code": "IDENTITY_MISMATCH",
253
+ "notes": "Signed by Jane Smith instead of John Doe.",
254
+ "authorized_signatory": {
255
+ "name": "John Doe",
256
+ "role": "director",
257
+ "ref_paths": ["reference_1.png", "reference_2.png", "reference_3.png"]
258
+ },
259
+ "signed_roles": [
260
+ {
261
+ "role": "director_1",
262
+ "signed_by": "Jane Smith",
263
+ "status": "filled_wrong_person"
264
+ },
265
+ {
266
+ "role": "director_2",
267
+ "signed_by": "Jane Smith",
268
+ "status": "filled_wrong_person"
269
+ }
270
+ ]
271
+ }
272
+ ```
273
+
274
+ ### How Each Case Type is Generated
275
+
276
+ **PASS** — loads the authorized person's genuine SigNet signatures and pastes one into each required field with augmentation applied.
277
+
278
+ **NO_SIGNATURE** — loads the template but pastes nothing. All signature boxes are left as blank fields on the printed template.
279
+
280
+ **WRONG_PERSON** — loads a different (unauthorized) person's genuine signatures and pastes them into all fields. The reference signatures in the folder still belong to the authorized person, making the mismatch detectable.
281
+
282
+ **WRONG_ROLE** — loads the authorized person's genuine signatures but pastes them into the wrong fields by reversing the order of signature boxes. For example, the person who should sign the applicant box signs the officer box and vice versa.
283
+
284
+ **REQUIRED_PERSON_MISSING** — fills only the first signature box correctly and leaves all remaining required boxes blank. Only used with document types that have two or more signature boxes.
285
+
286
+ ### Summary CSV
287
+
288
+ `test_cases_summary.csv` contains one row per case with these columns:
289
+
290
+ | Column | Description |
291
+ |---|---|
292
+ | `case_id` | e.g. `case_003` |
293
+ | `type` | One of the 5 scenario types |
294
+ | `document_type` | Which template was used |
295
+ | `expected_outcome` | `ACCEPTED` or `REJECTED` |
296
+ | `expected_rejection_code` | Rejection reason, or empty if accepted |
297
+ | `authorized_name` | Name of the authorized signatory |
298
+ | `authorized_role` | Their role on the document |
299
+ | `num_ref_signatures` | How many reference images are in the folder |
300
+ | `ref_paths` | Semicolon-separated list of reference filenames |
301
+ | `notes` | Human-readable description of what is wrong |
302
+ | `case_folder` | Relative path to the case folder |
303
+
304
+ ---
305
+
306
+ ## Full Data Flow Summary
307
+
308
+ ```
309
+ Raw datasets (disk)
310
+ CEDAR full_org / full_forg
311
+ SigNet train/ test/ per-writer folders
312
+
313
+
314
+ build_signature_pool()
315
+ Combined pool: {path, writer_id, label, source}
316
+ Everything in RAM — nothing saved yet
317
+
318
+ ▼ (×200 documents)
319
+ For each document:
320
+ 1. Pick random doc type → load template PNG from disk
321
+ 2. For each signature box:
322
+ Pick random signature from pool
323
+ prepare_signature()
324
+ → remove_background() OpenCV threshold → transparent bg
325
+ → crop_to_content() tight crop around ink
326
+ → augment_signature() rotate / scale / noise
327
+ Convert BGRA → PIL RGBA
328
+ paste_signature()
329
+ → remove_white_background() PIL-based final bg removal
330
+ → thumbnail() resize to fit box
331
+ → paste() with alpha mask blend ink onto document
332
+ → GaussianBlur(0.3) soften ink into paper
333
+ 3. Label document: "forged" if any sig is forged
334
+ 4. doc_image.save() → data/synthetic/doc_NNN_…_label.png
335
+ 5. Append metadata row
336
+
337
+
338
+ write_dataset_csv()
339
+ → data/synthetic_dataset.csv
340
+ ```
project_a_output_progress/synthetic/doc_001_chinese_employee_application_forged.png ADDED

Git LFS Details

  • SHA256: 4e7fd689bc1b068ccce404242b1a703b2c18bcd89f47625765a9c3a64deb9f2f
  • Pointer size: 131 Bytes
  • Size of remote file: 153 kB
project_a_output_progress/synthetic/doc_002_chinese_service_application_genuine.png ADDED

Git LFS Details

  • SHA256: a4bf1c635c6c7a4bc396139956807de3dd5b9c12891c90f92a5fb5619d833047
  • Pointer size: 131 Bytes
  • Size of remote file: 189 kB
project_a_output_progress/synthetic/doc_003_tamil_public_service_forged.png ADDED

Git LFS Details

  • SHA256: cdcb5f433937513224f1fa05e8a5fcc1bf45eb06c11b7bf52d9092897f65b5f0
  • Pointer size: 131 Bytes
  • Size of remote file: 329 kB
project_a_output_progress/synthetic/doc_004_chinese_service_application_genuine.png ADDED

Git LFS Details

  • SHA256: a579c5d04adfc6a8f155271ea3c75346b31ba85a4ca7ee633a5568b814510c7d
  • Pointer size: 131 Bytes
  • Size of remote file: 190 kB
project_a_output_progress/synthetic/doc_005_tamil_public_service_genuine.png ADDED

Git LFS Details

  • SHA256: 1b8b0679f3a6fc8f82996bf3d1f59afad9f1cf7f32b9a8d2ec344af0d6c6dffb
  • Pointer size: 131 Bytes
  • Size of remote file: 325 kB
project_a_output_progress/synthetic/doc_006_tamil_public_service_genuine.png ADDED

Git LFS Details

  • SHA256: 60c93b3aa4bdf398b96cc9d123ee06004a396301f9763a06ab2870b4013da59d
  • Pointer size: 131 Bytes
  • Size of remote file: 319 kB
project_a_output_progress/synthetic/doc_007_corporate_account_application_genuine.png ADDED

Git LFS Details

  • SHA256: 210c963738b3ab1932d5fa5112513758c445d8d488beb792d8dee2863a8b24be
  • Pointer size: 131 Bytes
  • Size of remote file: 216 kB
project_a_output_progress/synthetic/doc_008_shareholder_resolution_forged.png ADDED

Git LFS Details

  • SHA256: 8b7bb50a3777c87fea68134afc182c9342096e5be0878d97f74f2266779e6748
  • Pointer size: 131 Bytes
  • Size of remote file: 173 kB
project_a_output_progress/synthetic/doc_009_tamil_public_service_genuine.png ADDED

Git LFS Details

  • SHA256: 7bf5402771dbb3d92f5722a3a78bc6683c9660fddb50ad7c8b617e96e2c8494b
  • Pointer size: 131 Bytes
  • Size of remote file: 320 kB
project_a_output_progress/synthetic/doc_010_wealth_management_forged.png ADDED

Git LFS Details

  • SHA256: 299b4d9ca0433bd75703cbd680fe39f16e72461be598a45824e3fe07823ffc3c
  • Pointer size: 131 Bytes
  • Size of remote file: 186 kB
project_a_output_progress/synthetic/doc_011_corporate_account_application_genuine.png ADDED

Git LFS Details

  • SHA256: c2a722e8830a70fee57a8901845f070473007f02cbfec5b7f8331ea8c6c81d4a
  • Pointer size: 131 Bytes
  • Size of remote file: 219 kB
project_a_output_progress/synthetic/doc_012_tamil_residence_assessment_forged.png ADDED

Git LFS Details

  • SHA256: ce096155d5f20ee378e7875a766d975fcd0b8506f5d36863cf676d4c4569b0f3
  • Pointer size: 131 Bytes
  • Size of remote file: 247 kB
project_a_output_progress/synthetic/doc_013_bank_account_opening_forged.png ADDED

Git LFS Details

  • SHA256: 6ccfd123024d3c364deaa8966056a61b13da36000f236e394798bb4f33f9e9db
  • Pointer size: 131 Bytes
  • Size of remote file: 262 kB
project_a_output_progress/synthetic/doc_014_chinese_service_application_genuine.png ADDED

Git LFS Details

  • SHA256: ff85e12ae40adbe8884b6439d2c8df88dac54fe866a614a8783225756bc1382f
  • Pointer size: 131 Bytes
  • Size of remote file: 198 kB
project_a_output_progress/synthetic/doc_015_tamil_trade_license_forged.png ADDED

Git LFS Details

  • SHA256: 6696c7641be6314aee06426de1bd40450df71d5c56dfca7b6a6cdfa955026f5d
  • Pointer size: 131 Bytes
  • Size of remote file: 268 kB
project_a_output_progress/synthetic/doc_016_cheque_standard_clearing_genuine.png ADDED

Git LFS Details

  • SHA256: e47421e915f0feba2636e502d245a700c47138f5983d6c5936e4182a839da257
  • Pointer size: 130 Bytes
  • Size of remote file: 76.9 kB
project_a_output_progress/synthetic/doc_017_wealth_management_genuine.png ADDED

Git LFS Details

  • SHA256: b2701242edf927a9c777387031658b282741d20137093596fef415763cb2621a
  • Pointer size: 131 Bytes
  • Size of remote file: 180 kB
project_a_output_progress/synthetic/doc_018_cheque_standard_clearing_genuine.png ADDED

Git LFS Details

  • SHA256: 126ab4d16b7e150b954fc93f6d721bf59268f6a1ca5146bf978833c79e33450e
  • Pointer size: 130 Bytes
  • Size of remote file: 77.1 kB
project_a_output_progress/synthetic/doc_019_bank_account_opening_forged.png ADDED

Git LFS Details

  • SHA256: 59ee9e4f87542693028d1837253415debf6902e40296d7d53d7b7aa825cc488c
  • Pointer size: 131 Bytes
  • Size of remote file: 251 kB
project_a_output_progress/synthetic/doc_020_wealth_management_forged.png ADDED

Git LFS Details

  • SHA256: e80e0851f813cee35cfdfa81163a574d5d9dfb192f34103fc1f6b1ee6eb12e8d
  • Pointer size: 131 Bytes
  • Size of remote file: 189 kB
project_a_output_progress/synthetic/doc_021_shareholder_resolution_forged.png ADDED

Git LFS Details

  • SHA256: 03bc0e18ee4c0fa286e043a4af89f9e5e491f9d538fd6e89fb3877b644073558
  • Pointer size: 131 Bytes
  • Size of remote file: 174 kB
project_a_output_progress/synthetic/doc_022_cheque_continental_trust_forged.png ADDED

Git LFS Details

  • SHA256: c1b468786ff3a700c87ae4c56f166353f2823c00c1dd730064da8f4e6827e7f7
  • Pointer size: 130 Bytes
  • Size of remote file: 83 kB
project_a_output_progress/synthetic/doc_023_chinese_employee_application_forged.png ADDED

Git LFS Details

  • SHA256: 9f9a68c8f84237e96921a4041ac0b48a629ee6b7981ed1bda9d0210b30b93971
  • Pointer size: 131 Bytes
  • Size of remote file: 155 kB
project_a_output_progress/synthetic/doc_024_corporate_account_application_genuine.png ADDED

Git LFS Details

  • SHA256: 93f7675fb90b201b3daec98af7c187472ac0920a89c6aba0c31aa94ad692269f
  • Pointer size: 131 Bytes
  • Size of remote file: 215 kB
project_a_output_progress/synthetic/doc_025_tamil_trade_license_genuine.png ADDED

Git LFS Details

  • SHA256: d8e56fb70b4200155c1e1929c5a627ad5c4cb7605dcfd4af6d49dbf72dba8b53
  • Pointer size: 131 Bytes
  • Size of remote file: 246 kB
project_a_output_progress/synthetic/doc_026_shareholder_resolution_genuine.png ADDED

Git LFS Details

  • SHA256: a71449eaadb0cdf85ea139f73d4ae9294c1ccadd567c969fc802496d89da4c2f
  • Pointer size: 131 Bytes
  • Size of remote file: 184 kB
project_a_output_progress/synthetic/doc_027_wealth_management_forged.png ADDED

Git LFS Details

  • SHA256: 29e1c57c4d5db091349546f786dfc9b93ffd4e287d33cd65fe09084ee8084ad9
  • Pointer size: 131 Bytes
  • Size of remote file: 187 kB
project_a_output_progress/synthetic/doc_028_corporate_account_application_forged.png ADDED

Git LFS Details

  • SHA256: 20eaebc90188d15dc795093a984f4fe17e83b22a9dd62904df99a9a2291b9275
  • Pointer size: 131 Bytes
  • Size of remote file: 218 kB
project_a_output_progress/synthetic/doc_029_corporate_account_application_genuine.png ADDED

Git LFS Details

  • SHA256: 6b8f5e4af224361cd34fe44cd7efc044cf26d440055bd8950634c89538b1d485
  • Pointer size: 131 Bytes
  • Size of remote file: 221 kB
project_a_output_progress/synthetic/doc_030_chinese_service_application_genuine.png ADDED

Git LFS Details

  • SHA256: 35d3e76f34461ec1e20ff4a397a1783fafd6659af04f15b5230661dccd4ff88d
  • Pointer size: 131 Bytes
  • Size of remote file: 189 kB
project_a_output_progress/synthetic/doc_031_banking_authorization_forged.png ADDED

Git LFS Details

  • SHA256: 141e20d695d4d2af74d03b7d509b567ef8510034606a4a9378dd4a80cefcabae
  • Pointer size: 131 Bytes
  • Size of remote file: 225 kB
project_a_output_progress/synthetic/doc_032_banking_authorization_genuine.png ADDED

Git LFS Details

  • SHA256: 414cf7db515d95df7594c13bafa791da5df69377b89f8939032d10a806865c56
  • Pointer size: 131 Bytes
  • Size of remote file: 218 kB
project_a_output_progress/synthetic/doc_033_cheque_global_merchant_forged.png ADDED

Git LFS Details

  • SHA256: b59277cdeb1aa0a7487728f90f8fe3a0f4e5d3ec78ce5b57cd0de1d11faf0032
  • Pointer size: 130 Bytes
  • Size of remote file: 84.9 kB
project_a_output_progress/synthetic/doc_034_tamil_public_service_genuine.png ADDED

Git LFS Details

  • SHA256: 34eb46b907ad8042f5ef5e1f9b96ee122874976de5447a2002a38a0f0dda1716
  • Pointer size: 131 Bytes
  • Size of remote file: 319 kB
project_a_output_progress/synthetic/doc_035_tamil_trade_license_forged.png ADDED

Git LFS Details

  • SHA256: d9a3c5d140964f353c476873502e63075b99ea9190b8904320c1a5dbd9198fcf
  • Pointer size: 131 Bytes
  • Size of remote file: 253 kB
project_a_output_progress/synthetic/doc_036_tamil_trade_license_forged.png ADDED

Git LFS Details

  • SHA256: 363d02a87bd099257ef787627dd295b8e43942d007f98485b5e0c08fbb266055
  • Pointer size: 131 Bytes
  • Size of remote file: 256 kB
project_a_output_progress/synthetic/doc_037_cheque_global_merchant_genuine.png ADDED

Git LFS Details

  • SHA256: 9ec138b05c62a575d7554f774141778a03030fa331f5ad5e6c80216f947265a9
  • Pointer size: 130 Bytes
  • Size of remote file: 87.1 kB
project_a_output_progress/synthetic/doc_038_bank_account_opening_genuine.png ADDED

Git LFS Details

  • SHA256: 9606c9a3909f176f0b8a8cb6cf3466b688436da71fd10e4720f2d66faef15cc9
  • Pointer size: 131 Bytes
  • Size of remote file: 241 kB
project_a_output_progress/synthetic/doc_039_shareholder_resolution_forged.png ADDED

Git LFS Details

  • SHA256: e93e681a31393203d323ea687413bd49ef923385ef9e5a765ea495b8dde17e3e
  • Pointer size: 131 Bytes
  • Size of remote file: 169 kB
project_a_output_progress/synthetic/doc_040_chinese_service_application_forged.png ADDED

Git LFS Details

  • SHA256: 09aa8ffa2320c60ae0b4a22395e7dadea4a559052df20f4427b307fde9af0741
  • Pointer size: 131 Bytes
  • Size of remote file: 196 kB
project_a_output_progress/synthetic/doc_041_chinese_employee_application_genuine.png ADDED

Git LFS Details

  • SHA256: 25fc2c4ed76100c27cd4502cb373ee496eaa13dae6a53c2b014b4017d94c015c
  • Pointer size: 131 Bytes
  • Size of remote file: 156 kB
project_a_output_progress/synthetic/doc_042_banking_authorization_forged.png ADDED

Git LFS Details

  • SHA256: 51ed69e8bc0bca8ade3cc0d0264abe8b97395464d437b9f55d19aa5612b3a6b4
  • Pointer size: 131 Bytes
  • Size of remote file: 232 kB
project_a_output_progress/synthetic/doc_043_chinese_employee_application_genuine.png ADDED

Git LFS Details

  • SHA256: fcc1ea58f84712492d736528efda930516e471f39363de75d509661f990f39e3
  • Pointer size: 131 Bytes
  • Size of remote file: 150 kB
project_a_output_progress/synthetic/doc_044_bank_account_opening_genuine.png ADDED

Git LFS Details

  • SHA256: 0fe3d635055256851df29e8b239a3a371ad3810d35d0ebeddb38ee720bca333a
  • Pointer size: 131 Bytes
  • Size of remote file: 243 kB
project_a_output_progress/synthetic/doc_045_cheque_continental_trust_forged.png ADDED

Git LFS Details

  • SHA256: 9b6b8a5b5bc6e2aca8d0ea2d099a7ddffc80727ee661088ca6193cb019ffb7b8
  • Pointer size: 130 Bytes
  • Size of remote file: 88.4 kB
project_a_output_progress/synthetic/doc_046_chinese_business_registration_forged.png ADDED

Git LFS Details

  • SHA256: e525b0cf5df2bda6be772f1476e03d72bb74347dae187a821aaa429782d8a80f
  • Pointer size: 131 Bytes
  • Size of remote file: 127 kB
project_a_output_progress/synthetic/doc_047_tamil_residence_assessment_forged.png ADDED

Git LFS Details

  • SHA256: 2524868a546e2d80187b9d7e23fd9a198efefcc1b5cbaa87b51d223b5863f4c6
  • Pointer size: 131 Bytes
  • Size of remote file: 249 kB
project_a_output_progress/synthetic/doc_048_tamil_public_service_genuine.png ADDED

Git LFS Details

  • SHA256: bf268c18beae176b3fde025733b1769a3979c47d63f75794954abc71ebe48188
  • Pointer size: 131 Bytes
  • Size of remote file: 318 kB