|
22 | 22 | "import logging\n",
|
23 | 23 | "import matplotlib.pyplot as plt\n",
|
24 | 24 | "from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score\n",
|
| 25 | + "from tqdm import tqdm\n", |
25 | 26 | "\n",
|
26 | 27 | "# Import the required packages directly\n",
|
27 | 28 | "import treedisksegmentation\n",
|
|
49 | 50 | "YOLO_PITH_MODEL_PATH = \"../models/yolo11s-det-pith.pt\"\n",
|
50 | 51 | "YOLO_SEG_MODEL_PATH = \"../models/yolo11s-seg-tree.pt\"\n",
|
51 | 52 | "DEBUG = False\n",
|
52 |
| - "SAVE_RESULTS = False" |
| 53 | + "SAVE_RESULTS = False\n", |
| 54 | + "\n", |
| 55 | + "# evluation folder\n", |
| 56 | + "EVALUATION_RESULTS = \"./results/\"" |
53 | 57 | ]
|
54 | 58 | },
|
55 | 59 | {
|
|
140 | 144 | " output_dir=OUTPUT_DIR,\n",
|
141 | 145 | " cx=int(pith[0]),\n",
|
142 | 146 | " cy=int(pith[1]),\n",
|
143 |
| - " sigma=1.0,\n", |
| 147 | + " sigma=4.0,\n", |
144 | 148 | " th_low=5.0,\n",
|
145 | 149 | " th_high=15.0,\n",
|
146 | 150 | " save_results=SAVE_RESULTS,\n",
|
|
239 | 243 | " plt.tight_layout()\n",
|
240 | 244 | " \n",
|
241 | 245 | " # Save the combined figure with Titles (set transparent background)\n",
|
242 |
| - " plt.savefig('evaluation_plots.png', dpi=300, transparent=True)\n", |
243 |
| - " plt.savefig('evaluation_plots.pdf', transparent=True)\n", |
| 246 | + " plt.savefig(os.path.join(EVALUATION_RESULTS, 'evaluation_plots.png'), dpi=300, transparent=True)\n", |
| 247 | + " plt.savefig(os.path.join(EVALUATION_RESULTS, 'evaluation_plots.pdf'), transparent=True)\n", |
244 | 248 | " \n",
|
245 | 249 | " # Save each subplot individually WITHOUT Title\n",
|
246 | 250 | " fig.canvas.draw() # Update the renderer\n",
|
247 | 251 | " for i, ax in enumerate([ax1, ax2, ax3, ax4], start=1):\n",
|
248 | 252 | " original_title = ax.get_title()\n",
|
249 | 253 | " ax.set_title('') # Remove title\n",
|
250 | 254 | " extent = ax.get_tightbbox(fig.canvas.get_renderer()).transformed(fig.dpi_scale_trans.inverted())\n",
|
251 |
| - " plt.savefig(f'evaluation_plot_{i}.png', dpi=300, bbox_inches=extent, transparent=True)\n", |
252 |
| - " plt.savefig(f'evaluation_plot_{i}.pdf', bbox_inches=extent, transparent=True)\n", |
| 255 | + " plt.savefig(os.path.join(EVALUATION_RESULTS, f'evaluation_plot_{i}.png'), dpi=300, bbox_inches=extent, transparent=True)\n", |
| 256 | + " plt.savefig(os.path.join(EVALUATION_RESULTS, f'evaluation_plot_{i}.pdf'), bbox_inches=extent, transparent=True)\n", |
253 | 257 | " ax.set_title(original_title) # Optionally restore the title\n",
|
254 | 258 | " \n",
|
255 |
| - " logger.info(f\"Evaluation plots saved to {OUTPUT_DIR}\")\n" |
| 259 | + " logger.info(f\"Evaluation plots saved to {EVALUATION_RESULTS}\")" |
256 | 260 | ]
|
257 | 261 | },
|
258 | 262 | {
|
|
338 | 342 | " basic_results = []\n",
|
339 | 343 | " \n",
|
340 | 344 | " # Process each image\n",
|
341 |
| - " for img_data in ground_truth_json:\n", |
342 |
| - " logger.info(f\"Processing {img_data['path']}...\")\n", |
| 345 | + " for img_data in tqdm(ground_truth_json, desc=\"Processing images\", unit=\"image\"):\n", |
| 346 | + " tqdm.write(f\"Processing {img_data['path']}...\")\n", |
343 | 347 | " predicted_age, visualization = process_image(img_data)\n",
|
344 | 348 | " \n",
|
345 | 349 | " # Store the basic result\n",
|
|
357 | 361 | " # logger.info(f\" Result: True age = {img_data['age']}, Predicted age = {predicted_age}\")\n",
|
358 | 362 | " else:\n",
|
359 | 363 | " result[\"predicted_age\"] = None\n",
|
360 |
| - " logger.error(f\" Failed to process {img_data['path']}\")\n", |
| 364 | + " tqdm.write(f\" Failed to process {img_data['path']}\")\n", |
361 | 365 | " \n",
|
362 | 366 | " basic_results.append(result)\n",
|
363 | 367 | " \n",
|
|
370 | 374 | "metadata": {},
|
371 | 375 | "outputs": [],
|
372 | 376 | "source": [
|
| 377 | + "basic_results_file = os.path.join(EVALUATION_RESULTS, \"basic_results.json\")\n", |
| 378 | + "\n", |
373 | 379 | "# Run the evaluation\n",
|
374 | 380 | "logger.info(\"Starting evaluation of the tree disk analysis pipeline...\")\n",
|
375 | 381 | "basic_results = evaluate_pipeline()\n",
|
376 | 382 | "\n",
|
377 | 383 | "# Save basic results first\n",
|
378 |
| - "basic_results_file = \"basic_results.json\"\n", |
379 | 384 | "with open(basic_results_file, \"w\") as f:\n",
|
380 | 385 | " json.dump(basic_results, f, indent=2)\n",
|
381 | 386 | " \n",
|
|
388 | 393 | "metadata": {},
|
389 | 394 | "outputs": [],
|
390 | 395 | "source": [
|
391 |
| - "basic_results_file = \"basic_results.json\"\n", |
392 | 396 | "basic_results = json.load(open(basic_results_file))\n",
|
393 | 397 | "\n",
|
394 | 398 | "# calculate metrics on top of the basic results\n",
|
395 | 399 | "metrics = calculate_metrics(basic_results)\n",
|
396 | 400 | "\n",
|
397 | 401 | "# Save metrics to a separate file\n",
|
398 |
| - "metrics_file = \"metrics.json\"\n", |
| 402 | + "metrics_file = os.path.join(EVALUATION_RESULTS, \"metrics.json\")\n", |
399 | 403 | "with open(metrics_file, \"w\") as f:\n",
|
400 | 404 | " json.dump(metrics, f, indent=2)\n",
|
401 | 405 | " \n",
|
402 | 406 | "logger.info(f\"Metrics saved to {metrics_file}\")"
|
403 | 407 | ]
|
404 |
| - }, |
405 |
| - { |
406 |
| - "cell_type": "code", |
407 |
| - "execution_count": null, |
408 |
| - "metadata": {}, |
409 |
| - "outputs": [], |
410 |
| - "source": [ |
411 |
| - "images_data = \"/Volumes/Tony SSD/Projekte/Studienarbeit/Datasets/uruDendro/images\"\n", |
412 |
| - "annotations_data = \"/Volumes/Tony SSD/Projekte/Studienarbeit/Datasets/uruDendro/annotations\"\n", |
413 |
| - "\n", |
414 |
| - "# retrieve all .png files in the folder\n", |
415 |
| - "files = [f for f in os.listdir(images_data) if f.endswith('.png')]\n", |
416 |
| - "\n", |
417 |
| - "# delete macosx files\n", |
418 |
| - "files = [f for f in files if not f.startswith('._')]\n", |
419 |
| - "files = [f for f in files if not f.startswith('.')]\n", |
420 |
| - "\n", |
421 |
| - "print(files)\n", |
422 |
| - "\n", |
423 |
| - "# go trough annotations_data and retrieve the json files mathcing the image files, the image name must be exactly the same\n", |
424 |
| - "annotations = []\n", |
425 |
| - "for f in files:\n", |
426 |
| - " for a in os.listdir(annotations_data):\n", |
427 |
| - " if f.split('.')[0] in a:\n", |
428 |
| - " annotations.append(a)\n", |
429 |
| - "\n", |
430 |
| - "annotations = [f for f in annotations if not f.startswith('._')]\n", |
431 |
| - "annotations = [f for f in annotations if not f.startswith('.')]\n", |
432 |
| - "annotations = [f for f in annotations if not '-M' in f]\n", |
433 |
| - "annotations = [f for f in annotations if not '-V' in f]\n", |
434 |
| - "annotations = [f for f in annotations if not '-S' in f]\n", |
435 |
| - "annotations = [f for f in annotations if not '-C' in f]\n", |
436 |
| - "\n", |
437 |
| - "print(annotations)\n", |
438 |
| - "\n", |
439 |
| - "print(len(files))\n", |
440 |
| - "print(len(annotations))\n", |
441 |
| - "\n", |
442 |
| - "# read the json files and save the lenght (number of times) of the shapes key\n", |
443 |
| - "shapes = []\n", |
444 |
| - "for a in annotations:\n", |
445 |
| - " with open(os.path.join(annotations_data, a)) as f:\n", |
446 |
| - " data = json.load(f)\n", |
447 |
| - " shapes.append(len(data['shapes']))\n", |
448 |
| - "\n", |
449 |
| - "print(shapes)\n", |
450 |
| - "\n", |
451 |
| - "# create a json array with the image name and the number of shapes\n", |
452 |
| - "data = []\n", |
453 |
| - "for i in range(len(files)):\n", |
454 |
| - " data.append({\n", |
455 |
| - " \"path\": files[i],\n", |
456 |
| - " \"age\": shapes[i]\n", |
457 |
| - " })\n", |
458 |
| - "\n", |
459 |
| - "print(data)" |
460 |
| - ] |
461 | 408 | }
|
462 | 409 | ],
|
463 | 410 | "metadata": {
|
|
0 commit comments