Spaces:
Sleeping
Sleeping
test code
Browse files- .vscode/PythonImportHelper-v2-Completion.json +554 -0
- requirements.txt +3 -1
- src/config/llm.py +3 -2
- src/graph.py +117 -0
- src/inference/segment_inference.py +1 -1
- src/model/{segment.onnx → best.onnx} +2 -2
- src/notebook/notebook.ipynb +124 -6
- src/prompt/promt.py +50 -7
- src/utils/utils_segment.py +4 -13
.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
|
| 2 |
-
|
|
|
|
| 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/
|
| 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:
|
| 3 |
-
size
|
|
|
|
| 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":
|
| 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
|
| 21 |
]
|
| 22 |
},
|
| 23 |
{
|
|
@@ -32,7 +75,7 @@
|
|
| 32 |
"output_type": "stream",
|
| 33 |
"text": [
|
| 34 |
"\n",
|
| 35 |
-
"Extracting Dataset Version Zip to
|
| 36 |
]
|
| 37 |
}
|
| 38 |
],
|
|
@@ -104,7 +147,7 @@
|
|
| 104 |
},
|
| 105 |
{
|
| 106 |
"cell_type": "code",
|
| 107 |
-
"execution_count":
|
| 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": "
|
| 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 |
-
|
| 2 |
-
|
| 3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
|
| 11 |
-
|
| 12 |
-
|
| 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 |
-
|
| 8 |
-
|
| 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
|