ABAO77 commited on
Commit
28b686e
·
1 Parent(s): 3c0c074

test code

Browse files
.vscode/PythonImportHelper-v2-Completion.json ADDED
@@ -0,0 +1,554 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "label": "GoogleGenerativeAI",
4
+ "importPath": "langchain_google_genai",
5
+ "description": "langchain_google_genai",
6
+ "isExtraImport": true,
7
+ "detail": "langchain_google_genai",
8
+ "documentation": {}
9
+ },
10
+ {
11
+ "label": "onnxruntime",
12
+ "kind": 6,
13
+ "isExtraImport": true,
14
+ "importPath": "onnxruntime",
15
+ "description": "onnxruntime",
16
+ "detail": "onnxruntime",
17
+ "documentation": {}
18
+ },
19
+ {
20
+ "label": "preprocess",
21
+ "importPath": "src.utils.utils_segment",
22
+ "description": "src.utils.utils_segment",
23
+ "isExtraImport": true,
24
+ "detail": "src.utils.utils_segment",
25
+ "documentation": {}
26
+ },
27
+ {
28
+ "label": "postprocess",
29
+ "importPath": "src.utils.utils_segment",
30
+ "description": "src.utils.utils_segment",
31
+ "isExtraImport": true,
32
+ "detail": "src.utils.utils_segment",
33
+ "documentation": {}
34
+ },
35
+ {
36
+ "label": "extract_text",
37
+ "importPath": "src.utils.utils_segment",
38
+ "description": "src.utils.utils_segment",
39
+ "isExtraImport": true,
40
+ "detail": "src.utils.utils_segment",
41
+ "documentation": {}
42
+ },
43
+ {
44
+ "label": "draw_bounding_boxes",
45
+ "importPath": "src.utils.utils_segment",
46
+ "description": "src.utils.utils_segment",
47
+ "isExtraImport": true,
48
+ "detail": "src.utils.utils_segment",
49
+ "documentation": {}
50
+ },
51
+ {
52
+ "label": "numpy",
53
+ "kind": 6,
54
+ "isExtraImport": true,
55
+ "importPath": "numpy",
56
+ "description": "numpy",
57
+ "detail": "numpy",
58
+ "documentation": {}
59
+ },
60
+ {
61
+ "label": "Image",
62
+ "importPath": "PIL",
63
+ "description": "PIL",
64
+ "isExtraImport": true,
65
+ "detail": "PIL",
66
+ "documentation": {}
67
+ },
68
+ {
69
+ "label": "cv2",
70
+ "kind": 6,
71
+ "isExtraImport": true,
72
+ "importPath": "cv2",
73
+ "description": "cv2",
74
+ "detail": "cv2",
75
+ "documentation": {}
76
+ },
77
+ {
78
+ "label": "Tuple",
79
+ "importPath": "typing",
80
+ "description": "typing",
81
+ "isExtraImport": true,
82
+ "detail": "typing",
83
+ "documentation": {}
84
+ },
85
+ {
86
+ "label": "pytesseract",
87
+ "importPath": "pytesseract",
88
+ "description": "pytesseract",
89
+ "isExtraImport": true,
90
+ "detail": "pytesseract",
91
+ "documentation": {}
92
+ },
93
+ {
94
+ "label": "load_dotenv",
95
+ "importPath": "dotenv",
96
+ "description": "dotenv",
97
+ "isExtraImport": true,
98
+ "detail": "dotenv",
99
+ "documentation": {}
100
+ },
101
+ {
102
+ "label": "FastAPI",
103
+ "importPath": "fastapi",
104
+ "description": "fastapi",
105
+ "isExtraImport": true,
106
+ "detail": "fastapi",
107
+ "documentation": {}
108
+ },
109
+ {
110
+ "label": "UploadFile",
111
+ "importPath": "fastapi",
112
+ "description": "fastapi",
113
+ "isExtraImport": true,
114
+ "detail": "fastapi",
115
+ "documentation": {}
116
+ },
117
+ {
118
+ "label": "status",
119
+ "importPath": "fastapi",
120
+ "description": "fastapi",
121
+ "isExtraImport": true,
122
+ "detail": "fastapi",
123
+ "documentation": {}
124
+ },
125
+ {
126
+ "label": "Form",
127
+ "importPath": "fastapi",
128
+ "description": "fastapi",
129
+ "isExtraImport": true,
130
+ "detail": "fastapi",
131
+ "documentation": {}
132
+ },
133
+ {
134
+ "label": "File",
135
+ "importPath": "fastapi",
136
+ "description": "fastapi",
137
+ "isExtraImport": true,
138
+ "detail": "fastapi",
139
+ "documentation": {}
140
+ },
141
+ {
142
+ "label": "JSONResponse",
143
+ "importPath": "fastapi.responses",
144
+ "description": "fastapi.responses",
145
+ "isExtraImport": true,
146
+ "detail": "fastapi.responses",
147
+ "documentation": {}
148
+ },
149
+ {
150
+ "label": "CORSMiddleware",
151
+ "importPath": "fastapi.middleware.cors",
152
+ "description": "fastapi.middleware.cors",
153
+ "isExtraImport": true,
154
+ "detail": "fastapi.middleware.cors",
155
+ "documentation": {}
156
+ },
157
+ {
158
+ "label": "llm",
159
+ "importPath": "src.config.llm",
160
+ "description": "src.config.llm",
161
+ "isExtraImport": true,
162
+ "detail": "src.config.llm",
163
+ "documentation": {}
164
+ },
165
+ {
166
+ "label": "format_prompt",
167
+ "importPath": "src.prompt.promt",
168
+ "description": "src.prompt.promt",
169
+ "isExtraImport": true,
170
+ "detail": "src.prompt.promt",
171
+ "documentation": {}
172
+ },
173
+ {
174
+ "label": "JsonOutputParser",
175
+ "importPath": "langchain_core.output_parsers",
176
+ "description": "langchain_core.output_parsers",
177
+ "isExtraImport": true,
178
+ "detail": "langchain_core.output_parsers",
179
+ "documentation": {}
180
+ },
181
+ {
182
+ "label": "uvicorn",
183
+ "kind": 6,
184
+ "isExtraImport": true,
185
+ "importPath": "uvicorn",
186
+ "description": "uvicorn",
187
+ "detail": "uvicorn",
188
+ "documentation": {}
189
+ },
190
+ {
191
+ "label": "BytesIO",
192
+ "importPath": "io",
193
+ "description": "io",
194
+ "isExtraImport": true,
195
+ "detail": "io",
196
+ "documentation": {}
197
+ },
198
+ {
199
+ "label": "base64",
200
+ "kind": 6,
201
+ "isExtraImport": true,
202
+ "importPath": "base64",
203
+ "description": "base64",
204
+ "detail": "base64",
205
+ "documentation": {}
206
+ },
207
+ {
208
+ "label": "Field",
209
+ "importPath": "pydantic",
210
+ "description": "pydantic",
211
+ "isExtraImport": true,
212
+ "detail": "pydantic",
213
+ "documentation": {}
214
+ },
215
+ {
216
+ "label": "BaseModel",
217
+ "importPath": "pydantic",
218
+ "description": "pydantic",
219
+ "isExtraImport": true,
220
+ "detail": "pydantic",
221
+ "documentation": {}
222
+ },
223
+ {
224
+ "label": "ThreadPoolExecutor",
225
+ "importPath": "concurrent.futures",
226
+ "description": "concurrent.futures",
227
+ "isExtraImport": true,
228
+ "detail": "concurrent.futures",
229
+ "documentation": {}
230
+ },
231
+ {
232
+ "label": "asyncio",
233
+ "kind": 6,
234
+ "isExtraImport": true,
235
+ "importPath": "asyncio",
236
+ "description": "asyncio",
237
+ "detail": "asyncio",
238
+ "documentation": {}
239
+ },
240
+ {
241
+ "label": "os",
242
+ "kind": 6,
243
+ "isExtraImport": true,
244
+ "importPath": "os",
245
+ "description": "os",
246
+ "detail": "os",
247
+ "documentation": {}
248
+ },
249
+ {
250
+ "label": "functools",
251
+ "kind": 6,
252
+ "isExtraImport": true,
253
+ "importPath": "functools",
254
+ "description": "functools",
255
+ "detail": "functools",
256
+ "documentation": {}
257
+ },
258
+ {
259
+ "label": "threading",
260
+ "kind": 6,
261
+ "isExtraImport": true,
262
+ "importPath": "threading",
263
+ "description": "threading",
264
+ "detail": "threading",
265
+ "documentation": {}
266
+ },
267
+ {
268
+ "label": "inference",
269
+ "importPath": "src.inference.segment_inference",
270
+ "description": "src.inference.segment_inference",
271
+ "isExtraImport": true,
272
+ "detail": "src.inference.segment_inference",
273
+ "documentation": {}
274
+ },
275
+ {
276
+ "label": "llm",
277
+ "kind": 5,
278
+ "importPath": "src.config.llm",
279
+ "description": "src.config.llm",
280
+ "peekOfCode": "llm = GoogleGenerativeAI(\n model=\"gemini-1.5-flash\",\n temperature=0,\n)",
281
+ "detail": "src.config.llm",
282
+ "documentation": {}
283
+ },
284
+ {
285
+ "label": "inference",
286
+ "kind": 2,
287
+ "importPath": "src.inference.segment_inference",
288
+ "description": "src.inference.segment_inference",
289
+ "peekOfCode": "def inference(image: np.array, threshold_confidence=0.5, threshold_iou=0.7):\n input = preprocess(image)\n outputs = postprocess(\n model.run(None, {\"images\": input}),\n threshold_confidence=threshold_confidence,\n threshold_iou=threshold_iou,\n )\n return outputs",
290
+ "detail": "src.inference.segment_inference",
291
+ "documentation": {}
292
+ },
293
+ {
294
+ "label": "model_path",
295
+ "kind": 5,
296
+ "importPath": "src.inference.segment_inference",
297
+ "description": "src.inference.segment_inference",
298
+ "peekOfCode": "model_path = \"./src/model/segment.onnx\"\nmodel = ort.InferenceSession(\n model_path,\n)\ndef inference(image: np.array, threshold_confidence=0.5, threshold_iou=0.7):\n input = preprocess(image)\n outputs = postprocess(\n model.run(None, {\"images\": input}),\n threshold_confidence=threshold_confidence,\n threshold_iou=threshold_iou,",
299
+ "detail": "src.inference.segment_inference",
300
+ "documentation": {}
301
+ },
302
+ {
303
+ "label": "model",
304
+ "kind": 5,
305
+ "importPath": "src.inference.segment_inference",
306
+ "description": "src.inference.segment_inference",
307
+ "peekOfCode": "model = ort.InferenceSession(\n model_path,\n)\ndef inference(image: np.array, threshold_confidence=0.5, threshold_iou=0.7):\n input = preprocess(image)\n outputs = postprocess(\n model.run(None, {\"images\": input}),\n threshold_confidence=threshold_confidence,\n threshold_iou=threshold_iou,\n )",
308
+ "detail": "src.inference.segment_inference",
309
+ "documentation": {}
310
+ },
311
+ {
312
+ "label": "format_prompt",
313
+ "kind": 5,
314
+ "importPath": "src.prompt.promt",
315
+ "description": "src.prompt.promt",
316
+ "peekOfCode": "format_prompt = \"\"\"\n#Role: You are an expert at correcting spelling errors from interviewee's resume information.\n#Instruction:\nYou are provided with a dictionary containing information from the user's resume by an OCR model. It may have misspellings or wrong entries.\nPlease correct the spelling of each field.\nMove the content of the fields to more appropriate fields if necessary.\nYou must not fabricate information and create new information.\nYou must return JSON containing the same format as the original format:\n#Input:\nMy resume is as follows: {input}",
317
+ "detail": "src.prompt.promt",
318
+ "documentation": {}
319
+ },
320
+ {
321
+ "label": "preprocess",
322
+ "kind": 2,
323
+ "importPath": "src.utils.utils_segment",
324
+ "description": "src.utils.utils_segment",
325
+ "peekOfCode": "def preprocess(img: np.array, shape=(640, 640)) -> np.array:\n global img_width, img_height, left, top, ratio\n img, ratio, (left, top) = resize_and_pad(img, new_shape=shape)\n img_height, img_width, _ = img.shape\n img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n img = img.transpose(2, 0, 1)\n img = img.reshape(1, 3, 640, 640).astype(\"float32\")\n img = img / 255.0\n return img\ndef extract_box(outputs):",
326
+ "detail": "src.utils.utils_segment",
327
+ "documentation": {}
328
+ },
329
+ {
330
+ "label": "extract_box",
331
+ "kind": 2,
332
+ "importPath": "src.utils.utils_segment",
333
+ "description": "src.utils.utils_segment",
334
+ "peekOfCode": "def extract_box(outputs):\n output0 = outputs[0]\n output1 = outputs[1]\n output0 = output0[0].transpose()\n output1 = output1[0]\n boxes = output0[:, 0:number_class_custom]\n masks = output0[:, number_class_custom:]\n output1 = output1.reshape(32, 160 * 160)\n output1 = output1.reshape(32, 160 * 160)\n masks = masks @ output1",
335
+ "detail": "src.utils.utils_segment",
336
+ "documentation": {}
337
+ },
338
+ {
339
+ "label": "intersection",
340
+ "kind": 2,
341
+ "importPath": "src.utils.utils_segment",
342
+ "description": "src.utils.utils_segment",
343
+ "peekOfCode": "def intersection(box1, box2):\n box1_x1, box1_y1, box1_x2, box1_y2 = box1[:4]\n box2_x1, box2_y1, box2_x2, box2_y2 = box2[:4]\n x1 = max(box1_x1, box2_x1)\n y1 = max(box1_y1, box2_y1)\n x2 = min(box1_x2, box2_x2)\n y2 = min(box1_y2, box2_y2)\n return (x2 - x1) * (y2 - y1)\ndef union(box1, box2):\n box1_x1, box1_y1, box1_x2, box1_y2 = box1[:4]",
344
+ "detail": "src.utils.utils_segment",
345
+ "documentation": {}
346
+ },
347
+ {
348
+ "label": "union",
349
+ "kind": 2,
350
+ "importPath": "src.utils.utils_segment",
351
+ "description": "src.utils.utils_segment",
352
+ "peekOfCode": "def union(box1, box2):\n box1_x1, box1_y1, box1_x2, box1_y2 = box1[:4]\n box2_x1, box2_y1, box2_x2, box2_y2 = box2[:4]\n box1_area = (box1_x2 - box1_x1) * (box1_y2 - box1_y1)\n box2_area = (box2_x2 - box2_x1) * (box2_y2 - box2_y1)\n return box1_area + box2_area - intersection(box1, box2)\ndef iou(box1, box2):\n return intersection(box1, box2) / union(box1, box2)\ndef sigmoid(z):\n return 1 / (1 + np.exp(-z))",
353
+ "detail": "src.utils.utils_segment",
354
+ "documentation": {}
355
+ },
356
+ {
357
+ "label": "iou",
358
+ "kind": 2,
359
+ "importPath": "src.utils.utils_segment",
360
+ "description": "src.utils.utils_segment",
361
+ "peekOfCode": "def iou(box1, box2):\n return intersection(box1, box2) / union(box1, box2)\ndef sigmoid(z):\n return 1 / (1 + np.exp(-z))\ndef get_mask(row, box, img_width, img_height, threshold):\n mask = row.reshape(160, 160)\n mask = sigmoid(mask)\n mask = (mask > threshold).astype(\"uint8\") * 255\n x1, y1, x2, y2 = box\n mask_x1 = round(x1 / img_width * 160)",
362
+ "detail": "src.utils.utils_segment",
363
+ "documentation": {}
364
+ },
365
+ {
366
+ "label": "sigmoid",
367
+ "kind": 2,
368
+ "importPath": "src.utils.utils_segment",
369
+ "description": "src.utils.utils_segment",
370
+ "peekOfCode": "def sigmoid(z):\n return 1 / (1 + np.exp(-z))\ndef get_mask(row, box, img_width, img_height, threshold):\n mask = row.reshape(160, 160)\n mask = sigmoid(mask)\n mask = (mask > threshold).astype(\"uint8\") * 255\n x1, y1, x2, y2 = box\n mask_x1 = round(x1 / img_width * 160)\n mask_y1 = round(y1 / img_height * 160)\n mask_x2 = round(x2 / img_width * 160)",
371
+ "detail": "src.utils.utils_segment",
372
+ "documentation": {}
373
+ },
374
+ {
375
+ "label": "get_mask",
376
+ "kind": 2,
377
+ "importPath": "src.utils.utils_segment",
378
+ "description": "src.utils.utils_segment",
379
+ "peekOfCode": "def get_mask(row, box, img_width, img_height, threshold):\n mask = row.reshape(160, 160)\n mask = sigmoid(mask)\n mask = (mask > threshold).astype(\"uint8\") * 255\n x1, y1, x2, y2 = box\n mask_x1 = round(x1 / img_width * 160)\n mask_y1 = round(y1 / img_height * 160)\n mask_x2 = round(x2 / img_width * 160)\n mask_y2 = round(y2 / img_height * 160)\n mask = mask[mask_y1:mask_y2, mask_x1:mask_x2]",
380
+ "detail": "src.utils.utils_segment",
381
+ "documentation": {}
382
+ },
383
+ {
384
+ "label": "get_polygon",
385
+ "kind": 2,
386
+ "importPath": "src.utils.utils_segment",
387
+ "description": "src.utils.utils_segment",
388
+ "peekOfCode": "def get_polygon(mask):\n contours = cv2.findContours(mask, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)\n polygon = [[contour[0][0], contour[0][1]] for contour in contours[0][0]]\n return polygon\ndef postprocess(outputs, threshold_confidence, threshold_iou):\n objects = []\n for row in extract_box(outputs):\n xc, yc, w, h = row[:4]\n x1 = (xc - w / 2) / 640 * img_width\n y1 = (yc - h / 2) / 640 * img_height",
389
+ "detail": "src.utils.utils_segment",
390
+ "documentation": {}
391
+ },
392
+ {
393
+ "label": "postprocess",
394
+ "kind": 2,
395
+ "importPath": "src.utils.utils_segment",
396
+ "description": "src.utils.utils_segment",
397
+ "peekOfCode": "def postprocess(outputs, threshold_confidence, threshold_iou):\n objects = []\n for row in extract_box(outputs):\n xc, yc, w, h = row[:4]\n x1 = (xc - w / 2) / 640 * img_width\n y1 = (yc - h / 2) / 640 * img_height\n x2 = (xc + w / 2) / 640 * img_width\n y2 = (yc + h / 2) / 640 * img_height\n prob = row[4:number_class_custom].max()\n if prob < threshold_confidence:",
398
+ "detail": "src.utils.utils_segment",
399
+ "documentation": {}
400
+ },
401
+ {
402
+ "label": "extract_text_dict",
403
+ "kind": 2,
404
+ "importPath": "src.utils.utils_segment",
405
+ "description": "src.utils.utils_segment",
406
+ "peekOfCode": "def extract_text_dict(outputs):\n result_dict = {}\n for output in outputs:\n label = output.get(\"label\").lower()\n text = output.get(\"text\")\n if label in result_dict:\n result_dict[label] += \" \" + text\n else:\n result_dict[label] = text\n return result_dict",
407
+ "detail": "src.utils.utils_segment",
408
+ "documentation": {}
409
+ },
410
+ {
411
+ "label": "extract_text",
412
+ "kind": 2,
413
+ "importPath": "src.utils.utils_segment",
414
+ "description": "src.utils.utils_segment",
415
+ "peekOfCode": "def extract_text(outputs, image_origin):\n for i in range(len(outputs)):\n image = crop_image(image_origin, outputs[i].get(\"box\"))\n text = pytesseract.image_to_string(image)\n outputs[i].update({\"text\": text})\n if \"text\" in outputs[i]:\n outputs[i][\"text\"] += text\n else:\n outputs[i].update({\"text\": text})\n return extract_text_dict(outputs)",
416
+ "detail": "src.utils.utils_segment",
417
+ "documentation": {}
418
+ },
419
+ {
420
+ "label": "crop_image",
421
+ "kind": 2,
422
+ "importPath": "src.utils.utils_segment",
423
+ "description": "src.utils.utils_segment",
424
+ "peekOfCode": "def crop_image(image, box):\n x1, y1, x2, y2 = map(int, box)\n cropped_image = image[y1:y2, x1:x2]\n return cropped_image\ndef resize_and_pad(\n image: np.array,\n new_shape: Tuple[int, int],\n padding_color: Tuple[int] = (144, 144, 144),\n) -> np.array:\n h_org, w_org = image.shape[:2]",
425
+ "detail": "src.utils.utils_segment",
426
+ "documentation": {}
427
+ },
428
+ {
429
+ "label": "resize_and_pad",
430
+ "kind": 2,
431
+ "importPath": "src.utils.utils_segment",
432
+ "description": "src.utils.utils_segment",
433
+ "peekOfCode": "def resize_and_pad(\n image: np.array,\n new_shape: Tuple[int, int],\n padding_color: Tuple[int] = (144, 144, 144),\n) -> np.array:\n h_org, w_org = image.shape[:2]\n w_new, h_new = new_shape\n padd_left, padd_right, padd_top, padd_bottom = 0, 0, 0, 0\n # Padding left to right\n if h_org >= w_org:",
434
+ "detail": "src.utils.utils_segment",
435
+ "documentation": {}
436
+ },
437
+ {
438
+ "label": "unpad_and_resize_boxes",
439
+ "kind": 2,
440
+ "importPath": "src.utils.utils_segment",
441
+ "description": "src.utils.utils_segment",
442
+ "peekOfCode": "def unpad_and_resize_boxes(boxes, ratio, left, top):\n if len(boxes) == 0:\n return boxes\n boxes = np.array(boxes)\n if boxes.ndim == 1:\n boxes = boxes.reshape(-1, 4)\n boxes[:, [0, 2]] -= left\n boxes[:, [1, 3]] -= top\n boxes[:, :4] /= ratio\n if len(boxes) == 1:",
443
+ "detail": "src.utils.utils_segment",
444
+ "documentation": {}
445
+ },
446
+ {
447
+ "label": "draw_bounding_boxes",
448
+ "kind": 2,
449
+ "importPath": "src.utils.utils_segment",
450
+ "description": "src.utils.utils_segment",
451
+ "peekOfCode": "def draw_bounding_boxes(image, outputs):\n # Create a copy of the image to draw on\n image_with_boxes = image.copy()\n # Define a list of colors for the bounding boxes\n label_colors = {\n \"Certifications\": (255, 0, 0),\n \"Community\": (0, 255, 0),\n \"Contact\": (0, 0, 255),\n \"Education\": (255, 128, 0),\n \"Experience\": (255, 0, 255),",
452
+ "detail": "src.utils.utils_segment",
453
+ "documentation": {}
454
+ },
455
+ {
456
+ "label": "class_names",
457
+ "kind": 5,
458
+ "importPath": "src.utils.utils_segment",
459
+ "description": "src.utils.utils_segment",
460
+ "peekOfCode": "class_names = [\n \"Certifications\",\n \"Community\",\n \"Contact\",\n \"Education\",\n \"Experience\",\n \"Interests\",\n \"Languages\",\n \"Name\",\n \"Profile\",",
461
+ "detail": "src.utils.utils_segment",
462
+ "documentation": {}
463
+ },
464
+ {
465
+ "label": "number_class_custom",
466
+ "kind": 5,
467
+ "importPath": "src.utils.utils_segment",
468
+ "description": "src.utils.utils_segment",
469
+ "peekOfCode": "number_class_custom = int(len(class_names) + 4)\nimg_width, img_height = None, None\nleft = None\ntop = None\nratio = None\ndef preprocess(img: np.array, shape=(640, 640)) -> np.array:\n global img_width, img_height, left, top, ratio\n img, ratio, (left, top) = resize_and_pad(img, new_shape=shape)\n img_height, img_width, _ = img.shape\n img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)",
470
+ "detail": "src.utils.utils_segment",
471
+ "documentation": {}
472
+ },
473
+ {
474
+ "label": "left",
475
+ "kind": 5,
476
+ "importPath": "src.utils.utils_segment",
477
+ "description": "src.utils.utils_segment",
478
+ "peekOfCode": "left = None\ntop = None\nratio = None\ndef preprocess(img: np.array, shape=(640, 640)) -> np.array:\n global img_width, img_height, left, top, ratio\n img, ratio, (left, top) = resize_and_pad(img, new_shape=shape)\n img_height, img_width, _ = img.shape\n img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n img = img.transpose(2, 0, 1)\n img = img.reshape(1, 3, 640, 640).astype(\"float32\")",
479
+ "detail": "src.utils.utils_segment",
480
+ "documentation": {}
481
+ },
482
+ {
483
+ "label": "top",
484
+ "kind": 5,
485
+ "importPath": "src.utils.utils_segment",
486
+ "description": "src.utils.utils_segment",
487
+ "peekOfCode": "top = None\nratio = None\ndef preprocess(img: np.array, shape=(640, 640)) -> np.array:\n global img_width, img_height, left, top, ratio\n img, ratio, (left, top) = resize_and_pad(img, new_shape=shape)\n img_height, img_width, _ = img.shape\n img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n img = img.transpose(2, 0, 1)\n img = img.reshape(1, 3, 640, 640).astype(\"float32\")\n img = img / 255.0",
488
+ "detail": "src.utils.utils_segment",
489
+ "documentation": {}
490
+ },
491
+ {
492
+ "label": "ratio",
493
+ "kind": 5,
494
+ "importPath": "src.utils.utils_segment",
495
+ "description": "src.utils.utils_segment",
496
+ "peekOfCode": "ratio = None\ndef preprocess(img: np.array, shape=(640, 640)) -> np.array:\n global img_width, img_height, left, top, ratio\n img, ratio, (left, top) = resize_and_pad(img, new_shape=shape)\n img_height, img_width, _ = img.shape\n img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n img = img.transpose(2, 0, 1)\n img = img.reshape(1, 3, 640, 640).astype(\"float32\")\n img = img / 255.0\n return img",
497
+ "detail": "src.utils.utils_segment",
498
+ "documentation": {}
499
+ },
500
+ {
501
+ "label": "LLMRequest",
502
+ "kind": 6,
503
+ "importPath": "app",
504
+ "description": "app",
505
+ "peekOfCode": "class LLMRequest(BaseModel):\n text: str = Field(..., title=\"Text to generate completion\")\ndef call_llm(data):\n input = format_prompt.format(input=data)\n response = llm.invoke(input)\n response = JsonOutputParser().parse(response)\n return response\n@app.post(\"/llm\", status_code=status.HTTP_200_OK)\nasync def llm_predict(data: LLMRequest):\n try:",
506
+ "detail": "app",
507
+ "documentation": {}
508
+ },
509
+ {
510
+ "label": "run_in_thread",
511
+ "kind": 2,
512
+ "importPath": "app",
513
+ "description": "app",
514
+ "peekOfCode": "def run_in_thread(func, *args, **kwargs):\n loop = asyncio.get_event_loop()\n func_name = func.__name__\n def wrapper(*args, **kwargs):\n thread_id = threading.get_ident()\n print(f\"[Running function '{func_name}' in thread ID: {thread_id}]\")\n return func(*args, **kwargs)\n return loop.run_in_executor(executor, functools.partial(wrapper, *args, **kwargs))\ndef predict_func(threshold_confidence, threshold_iou, image):\n image = np.frombuffer(image, np.uint8)",
515
+ "detail": "app",
516
+ "documentation": {}
517
+ },
518
+ {
519
+ "label": "predict_func",
520
+ "kind": 2,
521
+ "importPath": "app",
522
+ "description": "app",
523
+ "peekOfCode": "def predict_func(threshold_confidence, threshold_iou, image):\n image = np.frombuffer(image, np.uint8)\n image = cv2.imdecode(image, cv2.IMREAD_COLOR)\n outputs = inference(\n image,\n threshold_confidence=threshold_confidence,\n threshold_iou=threshold_iou,\n )\n text = extract_text(outputs=outputs, image_origin=image)\n image = draw_bounding_boxes(image, outputs)",
524
+ "detail": "app",
525
+ "documentation": {}
526
+ },
527
+ {
528
+ "label": "call_llm",
529
+ "kind": 2,
530
+ "importPath": "app",
531
+ "description": "app",
532
+ "peekOfCode": "def call_llm(data):\n input = format_prompt.format(input=data)\n response = llm.invoke(input)\n response = JsonOutputParser().parse(response)\n return response\n@app.post(\"/llm\", status_code=status.HTTP_200_OK)\nasync def llm_predict(data: LLMRequest):\n try:\n response = await run_in_thread(call_llm, data.text)\n return JSONResponse(content=response, status_code=status.HTTP_200_OK)",
533
+ "detail": "app",
534
+ "documentation": {}
535
+ },
536
+ {
537
+ "label": "app",
538
+ "kind": 5,
539
+ "importPath": "app",
540
+ "description": "app",
541
+ "peekOfCode": "app = FastAPI(docs_url=\"/\")\napp.add_middleware(\n CORSMiddleware,\n allow_origins=[\"*\"],\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\nexecutor = ThreadPoolExecutor(max_workers=int(os.cpu_count() + 4))\ndef run_in_thread(func, *args, **kwargs):",
542
+ "detail": "app",
543
+ "documentation": {}
544
+ },
545
+ {
546
+ "label": "executor",
547
+ "kind": 5,
548
+ "importPath": "app",
549
+ "description": "app",
550
+ "peekOfCode": "executor = ThreadPoolExecutor(max_workers=int(os.cpu_count() + 4))\ndef run_in_thread(func, *args, **kwargs):\n loop = asyncio.get_event_loop()\n func_name = func.__name__\n def wrapper(*args, **kwargs):\n thread_id = threading.get_ident()\n print(f\"[Running function '{func_name}' in thread ID: {thread_id}]\")\n return func(*args, **kwargs)\n return loop.run_in_executor(executor, functools.partial(wrapper, *args, **kwargs))\ndef predict_func(threshold_confidence, threshold_iou, image):",
551
+ "detail": "app",
552
+ "documentation": {}
553
+ }
554
+ ]
requirements.txt CHANGED
@@ -6,4 +6,6 @@ langchain-google-genai
6
  uvicorn
7
  python-multipart
8
  asyncio
9
- onnxruntime
 
 
 
6
  uvicorn
7
  python-multipart
8
  asyncio
9
+ onnxruntime
10
+ langgraph
11
+ langchain_community
src/config/llm.py CHANGED
@@ -1,5 +1,6 @@
1
- from langchain_google_genai import GoogleGenerativeAI
2
- llm = GoogleGenerativeAI(
 
3
  model="gemini-1.5-flash",
4
  temperature=0,
5
  )
 
1
+ from langchain_google_genai import ChatGoogleGenerativeAI
2
+
3
+ llm = ChatGoogleGenerativeAI(
4
  model="gemini-1.5-flash",
5
  temperature=0,
6
  )
src/graph.py ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langgraph.graph import StateGraph, END, START, add_messages
2
+ from typing import TypedDict, Any, Annotated
3
+ from PIL import Image
4
+ from src.utils.utils_segment import (
5
+ preprocess,
6
+ postprocess,
7
+ extract_text,
8
+ draw_bounding_boxes,
9
+ )
10
+ from src.inference.segment_inference import model
11
+ from src.config.llm import llm
12
+ from src.prompt.promt import format_prompt
13
+ from langchain_core.output_parsers import JsonOutputParser
14
+
15
+ parser = JsonOutputParser()
16
+
17
+
18
+ class State(TypedDict):
19
+ image: Any
20
+ image_origin: Any
21
+ outputs_from_inference: Any
22
+ text_extracted_from_ocr: Any
23
+ threshold_confidence: float
24
+ threshold_iou: float
25
+ cropped_images: Any
26
+ parser_output: bool
27
+ image_with_bounding_boxes: Any
28
+ _image: Annotated[Any, add_messages]
29
+ crop_image: Any
30
+
31
+
32
+ class N:
33
+ PRE_PROCESS = "PRE_PROCESS"
34
+ POST_PROCESS = "POST_PROCESS"
35
+ INFERENCE = "INFERENCE"
36
+ EXTRACT_TEXT_FROM_OCR = "EXTRACT_TEXT_FROM_OCR"
37
+ PARSER_WITH_LLM = "PARSER_WITH_LLM"
38
+ IMAGE_WITH_BOUNDING_BOXES = "IMAGE_WITH_BOUNDING_BOXES"
39
+
40
+
41
+ workflow = StateGraph(State)
42
+
43
+
44
+ def pre_process_fn(state: State):
45
+ preprocess_img = preprocess(state["image_origin"])
46
+ print("preprocess_img", preprocess_img.shape)
47
+ image_for_display = (preprocess_img[0] * 255).astype("uint8")
48
+ image_for_display = image_for_display.transpose(1, 2, 0)
49
+ image_show = Image.fromarray(image_for_display)
50
+ return {"image": preprocess_img, "_image": image_show}
51
+
52
+
53
+ def inference_fn(state: State):
54
+ image = state["image"]
55
+ outputs = model.run(None, {"images": image})
56
+ return {"outputs_from_inference": outputs}
57
+
58
+
59
+ def post_process_fn(state: State):
60
+ outputs = state["outputs_from_inference"]
61
+ threshold_confidence = state["threshold_confidence"]
62
+ threshold_iou = state["threshold_iou"]
63
+ post_process_output = postprocess(outputs, threshold_confidence, threshold_iou)
64
+
65
+ return {
66
+ "outputs_from_inference": post_process_output,
67
+ }
68
+
69
+
70
+ def extract_text_from_ocr_fn(state: State):
71
+ image_origin = state["image_origin"]
72
+ output_from_inference = state["outputs_from_inference"]
73
+
74
+ text = extract_text(output_from_inference, image_origin)
75
+ return {"text_extracted_from_ocr": text}
76
+
77
+
78
+ def draw_bounding_boxes_fn(state: State):
79
+ image = state["image_origin"]
80
+ outputs = state["outputs_from_inference"]
81
+ image_with_bounding_boxes = draw_bounding_boxes(image, outputs)
82
+ return {"image_with_bounding_boxes": image_with_bounding_boxes}
83
+
84
+
85
+ def parser_output_fn(state: State):
86
+ text_extracted_from_ocr = state["text_extracted_from_ocr"]
87
+ chain = format_prompt | llm | parser
88
+ response = chain.invoke({"user_input": text_extracted_from_ocr})
89
+ print(response)
90
+ return {"parser_output": response}
91
+
92
+ #NODE
93
+ workflow.add_node(N.PRE_PROCESS, pre_process_fn)
94
+ workflow.add_node(N.INFERENCE, inference_fn)
95
+ workflow.add_node(N.POST_PROCESS, post_process_fn)
96
+ workflow.add_node(N.EXTRACT_TEXT_FROM_OCR, extract_text_from_ocr_fn)
97
+ workflow.add_node(N.IMAGE_WITH_BOUNDING_BOXES, draw_bounding_boxes_fn)
98
+ workflow.add_node(N.PARSER_WITH_LLM, parser_output_fn)
99
+
100
+ #EDGE
101
+ workflow.add_edge(START, N.PRE_PROCESS)
102
+ workflow.add_edge(N.PRE_PROCESS, N.INFERENCE)
103
+ workflow.add_edge(N.INFERENCE, N.POST_PROCESS)
104
+ workflow.add_edge(N.POST_PROCESS, N.IMAGE_WITH_BOUNDING_BOXES)
105
+ workflow.add_edge(N.IMAGE_WITH_BOUNDING_BOXES, N.EXTRACT_TEXT_FROM_OCR)
106
+ workflow.add_conditional_edges(
107
+ N.EXTRACT_TEXT_FROM_OCR,
108
+ lambda state: N.PARSER_WITH_LLM if state["parser_output"] else END,
109
+ {
110
+ N.PARSER_WITH_LLM: N.PARSER_WITH_LLM,
111
+ END: END,
112
+ },
113
+ )
114
+ workflow.add_edge(N.PARSER_WITH_LLM, END)
115
+
116
+
117
+ app = workflow.compile()
src/inference/segment_inference.py CHANGED
@@ -2,7 +2,7 @@ import onnxruntime as ort
2
  from src.utils.utils_segment import preprocess, postprocess
3
  import numpy as np
4
 
5
- model_path = "./src/model/segment.onnx"
6
  model = ort.InferenceSession(
7
  model_path,
8
  )
 
2
  from src.utils.utils_segment import preprocess, postprocess
3
  import numpy as np
4
 
5
+ model_path = "./src/model/best.onnx"
6
  model = ort.InferenceSession(
7
  model_path,
8
  )
src/model/{segment.onnx → best.onnx} RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:e38660d6cb501bc21d33249f1e1dffd9038d57a82f27bd089746e1aa8eca53a9
3
- size 109150130
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d1fe98385269d978abe302212d7eb38d0acd584eaa3af6e45ddfbe082a307f7e
3
+ size 109140800
src/notebook/notebook.ipynb CHANGED
@@ -2,22 +2,65 @@
2
  "cells": [
3
  {
4
  "cell_type": "code",
5
- "execution_count": 12,
6
  "metadata": {},
7
  "outputs": [
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  {
9
  "name": "stdout",
10
  "output_type": "stream",
11
  "text": [
12
  "loading Roboflow workspace...\n",
13
- "loading Roboflow project...\n"
 
14
  ]
15
  },
16
  {
17
  "name": "stderr",
18
  "output_type": "stream",
19
  "text": [
20
- "Downloading Dataset Version Zip in cvparsing-2 to yolov9:: 100%|██████████| 63864/63864 [00:04<00:00, 15236.33it/s]"
21
  ]
22
  },
23
  {
@@ -32,7 +75,7 @@
32
  "output_type": "stream",
33
  "text": [
34
  "\n",
35
- "Extracting Dataset Version Zip to cvparsing-2 in yolov9:: 100%|██████████| 2344/2344 [00:00<00:00, 5118.00it/s]\n"
36
  ]
37
  }
38
  ],
@@ -104,7 +147,7 @@
104
  },
105
  {
106
  "cell_type": "code",
107
- "execution_count": 6,
108
  "metadata": {},
109
  "outputs": [],
110
  "source": [
@@ -115,6 +158,10 @@
115
  "nc: 14\n",
116
  "names: ['Achievement', 'Certifications', 'Community', 'Contact', 'Education', 'Experience', 'Interests', 'Languages', 'Name', 'Profil', 'Projects', 'image', 'resume', 'skills']\"\"\"\n",
117
  "\n",
 
 
 
 
118
  "with open(\"./data.yaml\", 'w') as file:\n",
119
  " file.write(yaml_text),\n",
120
  "\n",
@@ -122,6 +169,77 @@
122
  "# %cat /kaggle/working/data.yaml\n"
123
  ]
124
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
  {
126
  "cell_type": "code",
127
  "execution_count": 20,
@@ -433,7 +551,7 @@
433
  ],
434
  "metadata": {
435
  "kernelspec": {
436
- "display_name": ".venv",
437
  "language": "python",
438
  "name": "python3"
439
  },
 
2
  "cells": [
3
  {
4
  "cell_type": "code",
5
+ "execution_count": 1,
6
  "metadata": {},
7
  "outputs": [
8
+ {
9
+ "name": "stdout",
10
+ "output_type": "stream",
11
+ "text": [
12
+ "Requirement already satisfied: roboflow in c:\\users\\htbqn\\appdata\\local\\programs\\python\\python311\\lib\\site-packages (1.1.44)\n",
13
+ "Requirement already satisfied: certifi in c:\\users\\htbqn\\appdata\\local\\programs\\python\\python311\\lib\\site-packages (from roboflow) (2024.7.4)\n",
14
+ "Requirement already satisfied: idna==3.7 in c:\\users\\htbqn\\appdata\\local\\programs\\python\\python311\\lib\\site-packages (from roboflow) (3.7)\n",
15
+ "Requirement already satisfied: cycler in c:\\users\\htbqn\\appdata\\local\\programs\\python\\python311\\lib\\site-packages (from roboflow) (0.12.1)\n",
16
+ "Requirement already satisfied: kiwisolver>=1.3.1 in c:\\users\\htbqn\\appdata\\local\\programs\\python\\python311\\lib\\site-packages (from roboflow) (1.4.5)\n",
17
+ "Requirement already satisfied: matplotlib in c:\\users\\htbqn\\appdata\\local\\programs\\python\\python311\\lib\\site-packages (from roboflow) (3.9.2)\n",
18
+ "Requirement already satisfied: numpy>=1.18.5 in c:\\users\\htbqn\\appdata\\local\\programs\\python\\python311\\lib\\site-packages (from roboflow) (1.26.4)\n",
19
+ "Requirement already satisfied: opencv-python-headless==4.10.0.84 in c:\\users\\htbqn\\appdata\\local\\programs\\python\\python311\\lib\\site-packages (from roboflow) (4.10.0.84)\n",
20
+ "Requirement already satisfied: Pillow>=7.1.2 in c:\\users\\htbqn\\appdata\\local\\programs\\python\\python311\\lib\\site-packages (from roboflow) (10.4.0)\n",
21
+ "Requirement already satisfied: python-dateutil in c:\\users\\htbqn\\appdata\\local\\programs\\python\\python311\\lib\\site-packages (from roboflow) (2.9.0.post0)\n",
22
+ "Requirement already satisfied: python-dotenv in c:\\users\\htbqn\\appdata\\local\\programs\\python\\python311\\lib\\site-packages (from roboflow) (1.0.1)\n",
23
+ "Requirement already satisfied: requests in c:\\users\\htbqn\\appdata\\local\\programs\\python\\python311\\lib\\site-packages (from roboflow) (2.31.0)\n",
24
+ "Requirement already satisfied: six in c:\\users\\htbqn\\appdata\\local\\programs\\python\\python311\\lib\\site-packages (from roboflow) (1.16.0)\n",
25
+ "Requirement already satisfied: urllib3>=1.26.6 in c:\\users\\htbqn\\appdata\\local\\programs\\python\\python311\\lib\\site-packages (from roboflow) (2.2.3)\n",
26
+ "Requirement already satisfied: tqdm>=4.41.0 in c:\\users\\htbqn\\appdata\\local\\programs\\python\\python311\\lib\\site-packages (from roboflow) (4.66.4)\n",
27
+ "Requirement already satisfied: PyYAML>=5.3.1 in c:\\users\\htbqn\\appdata\\local\\programs\\python\\python311\\lib\\site-packages (from roboflow) (6.0.1)\n",
28
+ "Requirement already satisfied: requests-toolbelt in c:\\users\\htbqn\\appdata\\local\\programs\\python\\python311\\lib\\site-packages (from roboflow) (1.0.0)\n",
29
+ "Requirement already satisfied: filetype in c:\\users\\htbqn\\appdata\\local\\programs\\python\\python311\\lib\\site-packages (from roboflow) (1.2.0)\n",
30
+ "Requirement already satisfied: colorama in c:\\users\\htbqn\\appdata\\local\\programs\\python\\python311\\lib\\site-packages (from tqdm>=4.41.0->roboflow) (0.4.4)\n",
31
+ "Requirement already satisfied: contourpy>=1.0.1 in c:\\users\\htbqn\\appdata\\local\\programs\\python\\python311\\lib\\site-packages (from matplotlib->roboflow) (1.2.1)\n",
32
+ "Requirement already satisfied: fonttools>=4.22.0 in c:\\users\\htbqn\\appdata\\local\\programs\\python\\python311\\lib\\site-packages (from matplotlib->roboflow) (4.53.1)\n",
33
+ "Requirement already satisfied: packaging>=20.0 in c:\\users\\htbqn\\appdata\\local\\programs\\python\\python311\\lib\\site-packages (from matplotlib->roboflow) (24.1)\n",
34
+ "Requirement already satisfied: pyparsing>=2.3.1 in c:\\users\\htbqn\\appdata\\local\\programs\\python\\python311\\lib\\site-packages (from matplotlib->roboflow) (3.1.2)\n",
35
+ "Requirement already satisfied: charset-normalizer<4,>=2 in c:\\users\\htbqn\\appdata\\local\\programs\\python\\python311\\lib\\site-packages (from requests->roboflow) (3.3.2)\n"
36
+ ]
37
+ },
38
+ {
39
+ "name": "stderr",
40
+ "output_type": "stream",
41
+ "text": [
42
+ "WARNING: Ignoring invalid distribution ~angchain (C:\\Users\\htbqn\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages)\n",
43
+ "WARNING: Ignoring invalid distribution ~ip (C:\\Users\\htbqn\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages)\n",
44
+ "WARNING: Ignoring invalid distribution ~angchain (C:\\Users\\htbqn\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages)\n",
45
+ "WARNING: Ignoring invalid distribution ~ip (C:\\Users\\htbqn\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages)\n",
46
+ "WARNING: Ignoring invalid distribution ~angchain (C:\\Users\\htbqn\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages)\n",
47
+ "WARNING: Ignoring invalid distribution ~ip (C:\\Users\\htbqn\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages)\n"
48
+ ]
49
+ },
50
  {
51
  "name": "stdout",
52
  "output_type": "stream",
53
  "text": [
54
  "loading Roboflow workspace...\n",
55
+ "loading Roboflow project...\n",
56
+ "Dependency ultralytics==8.0.196 is required but found version=8.2.90, to fix: `pip install ultralytics==8.0.196`\n"
57
  ]
58
  },
59
  {
60
  "name": "stderr",
61
  "output_type": "stream",
62
  "text": [
63
+ "Downloading Dataset Version Zip in annotation-2 to yolov8:: 100%|██████████| 92659/92659 [00:06<00:00, 14429.98it/s]"
64
  ]
65
  },
66
  {
 
75
  "output_type": "stream",
76
  "text": [
77
  "\n",
78
+ "Extracting Dataset Version Zip to annotation-2 in yolov8:: 100%|██████████| 3376/3376 [00:00<00:00, 3563.34it/s]\n"
79
  ]
80
  }
81
  ],
 
147
  },
148
  {
149
  "cell_type": "code",
150
+ "execution_count": null,
151
  "metadata": {},
152
  "outputs": [],
153
  "source": [
 
158
  "nc: 14\n",
159
  "names: ['Achievement', 'Certifications', 'Community', 'Contact', 'Education', 'Experience', 'Interests', 'Languages', 'Name', 'Profil', 'Projects', 'image', 'resume', 'skills']\"\"\"\n",
160
  "\n",
161
+ "# 3 + 8 -> 3\n",
162
+ "# 5 + 10 + 1 -> 5\n",
163
+ "# 13 + 7 -> 13\n",
164
+ "\n",
165
  "with open(\"./data.yaml\", 'w') as file:\n",
166
  " file.write(yaml_text),\n",
167
  "\n",
 
169
  "# %cat /kaggle/working/data.yaml\n"
170
  ]
171
  },
172
+ {
173
+ "cell_type": "code",
174
+ "execution_count": 7,
175
+ "metadata": {},
176
+ "outputs": [
177
+ {
178
+ "name": "stdout",
179
+ "output_type": "stream",
180
+ "text": [
181
+ "Labels mapped and saved to ./test.txt\n"
182
+ ]
183
+ }
184
+ ],
185
+ "source": [
186
+ "import os\n",
187
+ "\n",
188
+ "def map_yolo_labels(file_path, label_mapping, output_file=None):\n",
189
+ " \"\"\"\n",
190
+ " Remaps the class labels in a YOLOv8 label file and saves the updated labels.\n",
191
+ " \n",
192
+ " Parameters:\n",
193
+ " - file_path: Path to the YOLOv8 label file.\n",
194
+ " - label_mapping: Dictionary for remapping labels (e.g., {3: 3, 8: 3, 5: 5, 10: 5, 1: 5, 13: 13, 7: 13}).\n",
195
+ " - output_file: Path to save the remapped labels (optional). If not provided, it overwrites the original file.\n",
196
+ " \n",
197
+ " Returns:\n",
198
+ " - None\n",
199
+ " \"\"\"\n",
200
+ " with open(file_path, 'r') as file:\n",
201
+ " lines = file.readlines()\n",
202
+ "\n",
203
+ " # Process each line and remap the class label\n",
204
+ " updated_lines = []\n",
205
+ " for line in lines:\n",
206
+ " parts = line.strip().split()\n",
207
+ " class_id = int(parts[0]) # The first part is the class label\n",
208
+ " \n",
209
+ " # Remap the class label using the mapping\n",
210
+ " new_class_id = label_mapping.get(class_id, class_id)\n",
211
+ " \n",
212
+ " # Reconstruct the line with the new class label\n",
213
+ " updated_line = f\"{new_class_id} {' '.join(parts[1:])}\\n\"\n",
214
+ " updated_lines.append(updated_line)\n",
215
+ " \n",
216
+ " # Write to the output file (overwrite original file if output_file is not provided)\n",
217
+ " if output_file is None:\n",
218
+ " output_file = file_path\n",
219
+ "\n",
220
+ " with open(output_file, 'w') as file:\n",
221
+ " file.writelines(updated_lines)\n",
222
+ " \n",
223
+ " print(f\"Labels mapped and saved to {output_file}\")\n",
224
+ "\n",
225
+ "# Example usage:\n",
226
+ "label_mapping = {\n",
227
+ " 3: 3, # Map 3 -> 3\n",
228
+ " 8: 3, # Map 8 -> 3\n",
229
+ " 5: 5, # Map 5 -> 5\n",
230
+ " 10: 5, # Map 10 -> 5\n",
231
+ " 1: 5, # Map 1 -> 5\n",
232
+ " 13: 13, # Map 13 -> 13\n",
233
+ " 7: 13 # Map 7 -> 13\n",
234
+ "}\n",
235
+ "\n",
236
+ "# Path to your YOLOv8 label file\n",
237
+ "label_file = \"./test.txt\"\n",
238
+ "\n",
239
+ "# Call the function to remap labels\n",
240
+ "map_yolo_labels(label_file, label_mapping)\n"
241
+ ]
242
+ },
243
  {
244
  "cell_type": "code",
245
  "execution_count": 20,
 
551
  ],
552
  "metadata": {
553
  "kernelspec": {
554
+ "display_name": "Python 3",
555
  "language": "python",
556
  "name": "python3"
557
  },
src/prompt/promt.py CHANGED
@@ -1,13 +1,56 @@
1
- format_prompt = """
2
- #Role: You are an expert at correcting spelling errors from interviewee's resume information.
3
- #Instruction:
 
 
 
 
 
 
 
4
  You are provided with a dictionary containing information from the user's resume by an OCR model. It may have misspellings or wrong entries.
5
  Please correct the spelling of each field.
6
  Move the content of the fields to more appropriate fields if necessary.
7
  You must not fabricate information and create new information.
8
 
9
- You must return JSON containing the same format as the original format:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
- #Input:
12
- My resume is as follows: {input}
13
- """
 
 
 
1
+ from langchain_core.prompts import ChatPromptTemplate
2
+
3
+ format_prompt = ChatPromptTemplate.from_messages(
4
+ [
5
+ (
6
+ "system",
7
+ """
8
+ Role: You are an expert at extracting key information about projects from the "experience" section of an OCR'd resume.
9
+
10
+ Instruction:
11
  You are provided with a dictionary containing information from the user's resume by an OCR model. It may have misspellings or wrong entries.
12
  Please correct the spelling of each field.
13
  Move the content of the fields to more appropriate fields if necessary.
14
  You must not fabricate information and create new information.
15
 
16
+ Output must be in JSON format following the same structure as the input.
17
+ """,
18
+ ),
19
+ ("human", "{user_input}"),
20
+ ]
21
+ )
22
+
23
+
24
+ prompt_experience = ChatPromptTemplate.from_messages(
25
+ [
26
+ (
27
+ "system",
28
+ """
29
+ # Role: You are an expert at extracting key information about projects from the "experience" section of an OCR'd resume.
30
+
31
+ # Instruction:
32
+ You are given a JSON object containing extracted resume data from an OCR model. This data likely contains errors like misspellings, merged words, and extracted noise. Your task is to:
33
+
34
+ 1. **Pre-process the "experience" field:**
35
+ * Correct misspellings using your knowledge of common resume terms and English vocabulary.
36
+ * Separate merged words and remove any obvious OCR noise.
37
+
38
+ 2. **Identify the "experience" field:** Locate the field labeled "experience" (or a similar label) within the JSON object.
39
+
40
+ 3. **Extract project information:**
41
+ * Identify project mentions: Look for keywords and phrases that indicate a project, such as "project," "developed," "implemented," "designed," "contributed to," etc.
42
+ * Extract project details: For each project mentioned:
43
+ * Project name or description
44
+ * Role and contributions
45
+ * Technologies used
46
+ * Outcomes and achievements
47
+
48
+ 4. **Structure the output:** Return a JSON object with a "projects" field containing an array of extracted project details. The exact format can be flexible to accommodate variations in the input data.
49
+
50
+
51
 
52
+ """,
53
+ ),
54
+ ("human", "{user_input}"),
55
+ ]
56
+ )
src/utils/utils_segment.py CHANGED
@@ -4,19 +4,15 @@ import cv2
4
  from typing import Tuple
5
  from pytesseract import pytesseract
6
 
7
- # path_to_tesseract = r"C:\Program Files\Tesseract-OCR\tesseract.exe"
8
- # pytesseract.tesseract_cmd = path_to_tesseract
9
  class_names = [
10
- "Certifications",
11
  "Community",
12
  "Contact",
13
  "Education",
14
  "Experience",
15
  "Interests",
16
- "Languages",
17
- "Name",
18
  "Profile",
19
- "Projects",
20
  "Skills",
21
  ]
22
  number_class_custom = int(len(class_names) + 4)
@@ -232,22 +228,18 @@ def unpad_and_resize_boxes(boxes, ratio, left, top):
232
  return boxes.tolist()
233
 
234
 
235
- def draw_bounding_boxes(image, outputs):
236
  # Create a copy of the image to draw on
237
  image_with_boxes = image.copy()
238
 
239
  # Define a list of colors for the bounding boxes
240
  label_colors = {
241
- "Certifications": (255, 0, 0),
242
  "Community": (0, 255, 0),
243
  "Contact": (0, 0, 255),
244
  "Education": (255, 128, 0),
245
  "Experience": (255, 0, 255),
246
  "Interests": (128, 128, 128),
247
- "Languages": (128, 0, 0),
248
- "Name": (0, 128, 0),
249
  "Profile": (0, 0, 128),
250
- "Projects": (128, 128, 0),
251
  "Skills": (128, 0, 128),
252
  }
253
 
@@ -255,7 +247,6 @@ def draw_bounding_boxes(image, outputs):
255
  for output in outputs:
256
  box = output["box"]
257
  label = output["label"]
258
- text = output.get("text", "")
259
 
260
  # Get the color for the label
261
  color = label_colors.get(
@@ -279,5 +270,5 @@ def draw_bounding_boxes(image, outputs):
279
 
280
  # Convert the OpenCV image (numpy array) to a PIL image
281
  image_pil = Image.fromarray(image_with_boxes_rgb)
282
-
283
  return image_pil
 
4
  from typing import Tuple
5
  from pytesseract import pytesseract
6
 
7
+ path_to_tesseract = r"C:\Program Files\Tesseract-OCR\tesseract.exe"
8
+ pytesseract.tesseract_cmd = path_to_tesseract
9
  class_names = [
 
10
  "Community",
11
  "Contact",
12
  "Education",
13
  "Experience",
14
  "Interests",
 
 
15
  "Profile",
 
16
  "Skills",
17
  ]
18
  number_class_custom = int(len(class_names) + 4)
 
228
  return boxes.tolist()
229
 
230
 
231
+ def draw_bounding_boxes(image, outputs, save_path="output_image.jpg"):
232
  # Create a copy of the image to draw on
233
  image_with_boxes = image.copy()
234
 
235
  # Define a list of colors for the bounding boxes
236
  label_colors = {
 
237
  "Community": (0, 255, 0),
238
  "Contact": (0, 0, 255),
239
  "Education": (255, 128, 0),
240
  "Experience": (255, 0, 255),
241
  "Interests": (128, 128, 128),
 
 
242
  "Profile": (0, 0, 128),
 
243
  "Skills": (128, 0, 128),
244
  }
245
 
 
247
  for output in outputs:
248
  box = output["box"]
249
  label = output["label"]
 
250
 
251
  # Get the color for the label
252
  color = label_colors.get(
 
270
 
271
  # Convert the OpenCV image (numpy array) to a PIL image
272
  image_pil = Image.fromarray(image_with_boxes_rgb)
273
+ image_pil.save(save_path, format="JPEG")
274
  return image_pil