├── MODEL TRAINING SCRIPTS └── FINAL_Inverted_PyTorch_Model_P&ID.ipynb ├── README.md ├── build.sh ├── main_driver ├── 3.jpg ├── 3.zip ├── Actual Output (on CPU machine) │ ├── FINAL_P&ID.jpg │ └── FINAL_RESULT.xlsx ├── Aneesh_Risav_P&ID_Detection_and_Labelling_System.ipynb └── model_Inverted └── requirements.txt /MODEL TRAINING SCRIPTS/FINAL_Inverted_PyTorch_Model_P&ID.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "id": "EOhqL0tAi5Xj" 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import torch\n", 12 | "import torch.nn as nn \n", 13 | "import torch.optim as optim \n", 14 | "import torchvision.transforms as transforms \n", 15 | "import torch.nn.functional as F\n", 16 | "import torchvision\n", 17 | "import os\n", 18 | "import pandas as pd\n", 19 | "from skimage import io\n", 20 | "from torch.utils.data import (\n", 21 | " Dataset,\n", 22 | " DataLoader,\n", 23 | ") \n" 24 | ] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": null, 29 | "metadata": { 30 | "id": "rVuCHdcFbWxG" 31 | }, 32 | "outputs": [], 33 | "source": [ 34 | "from torch.nn.modules.batchnorm import BatchNorm1d\n", 35 | "\n", 36 | "class FCN(nn.Module):\n", 37 | " def __init__(self,in_channels = 1,num_classes=7):\n", 38 | " super(FCN,self).__init__()\n", 39 | " self.conv1 = nn.Sequential(\n", 40 | " nn.Conv2d(in_channels=1, out_channels=32, kernel_size=(3,3), stride=(1,1), padding=(1,1)),\n", 41 | " nn.BatchNorm2d(32, momentum=0.01),\n", 42 | " nn.ReLU(inplace=True),\n", 43 | " nn.Conv2d(in_channels=32, out_channels=32, kernel_size=(3,3), stride=(1,1), padding=(1,1)),\n", 44 | " nn.MaxPool2d(kernel_size=2),\n", 45 | " )\n", 46 | " self.conv2 = nn.Sequential(\n", 47 | " nn.Conv2d(in_channels=32, out_channels=64, kernel_size=(3,3), stride=(1,1), padding=(1,1)),\n", 48 | " nn.BatchNorm2d(64, momentum=0.01),\n", 49 | " nn.ReLU(inplace=True),\n", 50 | " nn.Conv2d(in_channels=64, out_channels=64, kernel_size=(3,3), stride=(1,1), padding=(1,1)),\n", 51 | " nn.MaxPool2d(kernel_size=2),\n", 52 | " )\n", 53 | " self.conv3 = nn.Sequential(\n", 54 | " nn.Conv2d(in_channels=64, out_channels=64, kernel_size=(3,3), stride=(1,1), padding=(1,1)),\n", 55 | " nn.BatchNorm2d(64, momentum=0.01),\n", 56 | " nn.ReLU(inplace=True),\n", 57 | " nn.Conv2d(in_channels=64, out_channels=64, kernel_size=(3,3), stride=(1,1), padding=(1,1)),\n", 58 | " nn.MaxPool2d(kernel_size=2),\n", 59 | " )\n", 60 | " self.fc1 = nn.Sequential(\n", 61 | " nn.Linear(20736,256),\n", 62 | " nn.ReLU(inplace=True),\n", 63 | " nn.Dropout(p=0.25),\n", 64 | " nn.BatchNorm1d(256)\n", 65 | " )\n", 66 | " self.fc2 = nn.Sequential(\n", 67 | " nn.Linear(256,128),\n", 68 | " nn.ReLU(inplace=True),\n", 69 | " nn.Dropout(p=0.25),\n", 70 | " nn.BatchNorm1d(128)\n", 71 | " )\n", 72 | " self.fc3 = nn.Sequential(\n", 73 | " nn.Linear(128,64),\n", 74 | " nn.ReLU(inplace=True),\n", 75 | " nn.Dropout(p=0.25),\n", 76 | " nn.BatchNorm1d(64)\n", 77 | " )\n", 78 | " self.fc4 = nn.Linear(64,7)\n", 79 | "\n", 80 | " def forward(self,x):\n", 81 | " x = self.conv1(x)\n", 82 | " x = self.conv2(x)\n", 83 | " x = self.conv3(x)\n", 84 | " x = x.reshape(x.shape[0],-1)\n", 85 | " x = self.fc1(x)\n", 86 | " x = self.fc2(x)\n", 87 | " x = self.fc3(x)\n", 88 | " x = F.softmax(self.fc4(x),dim=1)\n", 89 | " return x" 90 | ] 91 | }, 92 | { 93 | "cell_type": "code", 94 | "execution_count": null, 95 | "metadata": { 96 | "colab": { 97 | "base_uri": "https://localhost:8080/" 98 | }, 99 | "id": "EPcyPYPenjM3", 100 | "outputId": "d885ea7f-9ff6-4299-d79e-d6c57c0b07ec" 101 | }, 102 | "outputs": [], 103 | "source": [ 104 | "model = FCN()\n", 105 | "if torch.cuda.is_available():\n", 106 | " model.cuda()" 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "execution_count": null, 112 | "metadata": { 113 | "id": "KsW08MnFpE0X" 114 | }, 115 | "outputs": [], 116 | "source": [ 117 | "device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')" 118 | ] 119 | }, 120 | { 121 | "cell_type": "code", 122 | "execution_count": null, 123 | "metadata": { 124 | "colab": { 125 | "base_uri": "https://localhost:8080/" 126 | }, 127 | "id": "hArr3J9FrVjx", 128 | "outputId": "2d281026-a742-4986-8e2f-6b756070a2b8" 129 | }, 130 | "outputs": [], 131 | "source": [ 132 | "device" 133 | ] 134 | }, 135 | { 136 | "cell_type": "code", 137 | "execution_count": null, 138 | "metadata": { 139 | "id": "dvPTGhCq5q17" 140 | }, 141 | "outputs": [], 142 | "source": [ 143 | "if torch.cuda.is_available():\n", 144 | " model.cuda()" 145 | ] 146 | }, 147 | { 148 | "cell_type": "code", 149 | "execution_count": null, 150 | "metadata": { 151 | "id": "yK5aP8r1vfPy" 152 | }, 153 | "outputs": [], 154 | "source": [ 155 | "import shutil" 156 | ] 157 | }, 158 | { 159 | "cell_type": "code", 160 | "execution_count": null, 161 | "metadata": { 162 | "id": "lkHrdlKKtIw6" 163 | }, 164 | "outputs": [], 165 | "source": [ 166 | "# Data Loading\n", 167 | "path = './Augmented_inverted.zip'\n", 168 | "shutil.unpack_archive(path,'./dataset')\n", 169 | "\n", 170 | "path = './testing_inverted.zip'\n", 171 | "shutil.unpack_archive(path,'./testing_dataset')" 172 | ] 173 | }, 174 | { 175 | "cell_type": "code", 176 | "execution_count": null, 177 | "metadata": { 178 | "id": "nSPo4d8kvquX" 179 | }, 180 | "outputs": [], 181 | "source": [ 182 | "import cv2\n", 183 | "import matplotlib.pyplot as plt" 184 | ] 185 | }, 186 | { 187 | "cell_type": "code", 188 | "execution_count": null, 189 | "metadata": { 190 | "id": "rkp2gtJewEje" 191 | }, 192 | "outputs": [], 193 | "source": [ 194 | "from torchvision.datasets import ImageFolder\n", 195 | "from torch.utils.data import DataLoader, random_split\n", 196 | "from torchvision import transforms\n", 197 | "from PIL import Image\n", 198 | "import numpy as np" 199 | ] 200 | }, 201 | { 202 | "cell_type": "code", 203 | "execution_count": null, 204 | "metadata": { 205 | "id": "I2YnULJ3wym3" 206 | }, 207 | "outputs": [], 208 | "source": [ 209 | "data_transform = transforms.Compose([\n", 210 | " transforms.Grayscale(num_output_channels=1),\n", 211 | " transforms.Lambda(lambda x:torch.from_numpy(np.expand_dims(np.array(x),axis=0)).float())\n", 212 | " ])" 213 | ] 214 | }, 215 | { 216 | "cell_type": "code", 217 | "execution_count": null, 218 | "metadata": { 219 | "id": "A2xuefiqzM79" 220 | }, 221 | "outputs": [], 222 | "source": [ 223 | "root = './dataset'\n", 224 | "train_dataset = ImageFolder(root, transform=data_transform)\n", 225 | "test_dataset = ImageFolder(\"./testing_dataset\", transform=data_transform)\n", 226 | "\n", 227 | "# Split test and train dataset \n", 228 | "\n", 229 | "train_size = int(0.9 * len(train_dataset))\n", 230 | "test_size = len(train_dataset) - train_size\n", 231 | "train_data, test_data = random_split(train_dataset, [train_size, test_size])\n", 232 | "\n", 233 | "\n", 234 | "# Set batch size of train data loader\n", 235 | "batch_size_train = 64\n", 236 | "\n", 237 | "# Set batch size of test data loader\n", 238 | "batch_size_test = 64\n", 239 | "\n", 240 | "# load the split train and test data into batches via DataLoader()\n", 241 | "train_loader = DataLoader(train_data, batch_size=batch_size_train, shuffle=True)\n", 242 | "test_loader = DataLoader(test_dataset, batch_size=batch_size_test, shuffle=True)" 243 | ] 244 | }, 245 | { 246 | "cell_type": "code", 247 | "execution_count": null, 248 | "metadata": { 249 | "colab": { 250 | "base_uri": "https://localhost:8080/" 251 | }, 252 | "id": "BV9QIBNgqbU4", 253 | "outputId": "00d82cc2-68a0-4f62-ab85-db5b0fb74e82" 254 | }, 255 | "outputs": [], 256 | "source": [ 257 | "# Train loop\n", 258 | "\n", 259 | "in_channels = 1\n", 260 | "num_classes = 8\n", 261 | "learning_rate = 0.01\n", 262 | "batch_size = 64\n", 263 | "num_epochs = 25\n", 264 | "\n", 265 | "data_transform = transforms.Compose([\n", 266 | " transforms.Grayscale(num_output_channels=1),\n", 267 | " transforms.Lambda(lambda x:torch.tensor(np.expand_dims(np.array(x),axis=0))),\n", 268 | " transforms.RandomRotation(degrees=90),\n", 269 | " ])\n", 270 | "\n", 271 | "criterion = nn.CrossEntropyLoss()\n", 272 | "optimizer = optim.Adam(model.parameters(),lr = learning_rate)\n", 273 | "\n", 274 | "model.train()\n", 275 | "for epoch in range(num_epochs):\n", 276 | " correct = 0\n", 277 | " for batch_idx, (data,targets) in enumerate(train_loader):\n", 278 | "\n", 279 | " data = data.to(device=device)\n", 280 | " targets = targets.to(device=device)\n", 281 | " score = model(data)\n", 282 | " loss = criterion(score,targets)\n", 283 | " optimizer.zero_grad() \n", 284 | " loss.backward() \n", 285 | " optimizer.step()\n", 286 | " \n", 287 | " _, predicted = torch.max(score.data, 1)\n", 288 | " correct += (predicted == targets).float().sum()\n", 289 | " accuracy = 100 * correct / len(targets)\n", 290 | " print(\"Epoch = {}, Accuracy = {}\".format(epoch,accuracy))\n", 291 | "\n", 292 | "data_transform = transforms.Compose([\n", 293 | " transforms.Grayscale(num_output_channels=1),\n", 294 | " transforms.Lambda(lambda x:torch.tensor(np.expand_dims(np.array(x),axis=0))),\n", 295 | " transforms.RandomRotation(degrees=90),\n", 296 | " ])\n", 297 | "\n", 298 | "\n", 299 | "in_channels = 1\n", 300 | "num_classes = 8\n", 301 | "learning_rate = 0.005\n", 302 | "batch_size = 64\n", 303 | "num_epochs = 25\n", 304 | "\n", 305 | "criterion = nn.CrossEntropyLoss()\n", 306 | "optimizer = optim.Adam(model.parameters(),lr = learning_rate)\n", 307 | "\n", 308 | "model.train()\n", 309 | "for epoch in range(num_epochs):\n", 310 | " correct = 0\n", 311 | " for batch_idx, (data,targets) in enumerate(train_loader):\n", 312 | "\n", 313 | " data = data.to(device=device)\n", 314 | " targets = targets.to(device=device)\n", 315 | " score = model(data)\n", 316 | " loss = criterion(score,targets)\n", 317 | " optimizer.zero_grad()\n", 318 | " loss.backward()\n", 319 | " optimizer.step()\n", 320 | "\n", 321 | " _, predicted = torch.max(score.data, 1)\n", 322 | " correct += (predicted == targets).float().sum()\n", 323 | " accuracy = 100 * correct / len(targets)\n", 324 | " print(\"Epoch = {}, Accuracy = {}\".format(epoch,accuracy))\n", 325 | "\n", 326 | "data_transform = transforms.Compose([\n", 327 | " transforms.Grayscale(num_output_channels=1),\n", 328 | " transforms.Lambda(lambda x:torch.tensor(np.expand_dims(np.array(x),axis=0))),\n", 329 | " ])\n", 330 | "\n", 331 | "in_channels = 1\n", 332 | "num_classes = 8\n", 333 | "learning_rate = 0.001\n", 334 | "batch_size = 64\n", 335 | "num_epochs = 25\n", 336 | "\n", 337 | "criterion = nn.CrossEntropyLoss()\n", 338 | "optimizer = optim.Adam(model.parameters(),lr = learning_rate)\n", 339 | "\n", 340 | "for epoch in range(num_epochs):\n", 341 | " correct = 0\n", 342 | " for batch_idx, (data,targets) in enumerate(train_loader):\n", 343 | "\n", 344 | " data = data.to(device=device)\n", 345 | " targets = targets.to(device=device)\n", 346 | " score = model(data)\n", 347 | " loss = criterion(score,targets)\n", 348 | " optimizer.zero_grad()\n", 349 | " loss.backward()\n", 350 | " optimizer.step()\n", 351 | "\n", 352 | " _, predicted = torch.max(score.data, 1)\n", 353 | " correct += (predicted == targets).float().sum()\n", 354 | " accuracy = 100 * correct / len(targets)\n", 355 | " print(\"Epoch = {}, Accuracy = {}\".format(epoch,accuracy))\n", 356 | "\n", 357 | "in_channels = 1\n", 358 | "num_classes = 8\n", 359 | "learning_rate = 0.0005\n", 360 | "batch_size = 64\n", 361 | "num_epochs = 25\n", 362 | "\n", 363 | "criterion = nn.CrossEntropyLoss()\n", 364 | "optimizer = optim.Adam(model.parameters(),lr = learning_rate)\n", 365 | "\n", 366 | "for epoch in range(num_epochs):\n", 367 | " correct = 0\n", 368 | " for batch_idx, (data,targets) in enumerate(train_loader):\n", 369 | "\n", 370 | " data = data.to(device=device)\n", 371 | " targets = targets.to(device=device)\n", 372 | " score = model(data)\n", 373 | " loss = criterion(score,targets)\n", 374 | " optimizer.zero_grad()\n", 375 | " loss.backward()\n", 376 | " optimizer.step()\n", 377 | "\n", 378 | " _, predicted = torch.max(score.data, 1)\n", 379 | " correct += (predicted == targets).float().sum()\n", 380 | " accuracy = 100 * correct / len(targets)\n", 381 | " print(\"Epoch = {}, Accuracy = {}\".format(epoch,accuracy))\n", 382 | "\n" 383 | ] 384 | }, 385 | { 386 | "cell_type": "code", 387 | "execution_count": null, 388 | "metadata": { 389 | "colab": { 390 | "base_uri": "https://localhost:8080/" 391 | }, 392 | "id": "7Q9XGRQz4X-H", 393 | "outputId": "6c61e5c8-1c78-4639-e3f5-fcee263c0893" 394 | }, 395 | "outputs": [], 396 | "source": [ 397 | "print(\"Model's state_dict:\")\n", 398 | "for param_tensor in model.state_dict():\n", 399 | " print(param_tensor, \"\\t\", model.state_dict()[param_tensor].size())" 400 | ] 401 | }, 402 | { 403 | "cell_type": "markdown", 404 | "metadata": { 405 | "id": "mm3uRQ1y8dC3" 406 | }, 407 | "source": [ 408 | "Save Model" 409 | ] 410 | }, 411 | { 412 | "cell_type": "code", 413 | "execution_count": null, 414 | "metadata": { 415 | "id": "Lv2LrD8U7vbA" 416 | }, 417 | "outputs": [], 418 | "source": [ 419 | "torch.save(model.state_dict(),\"./model_Inverted\")" 420 | ] 421 | } 422 | ], 423 | "metadata": { 424 | "accelerator": "GPU", 425 | "colab": { 426 | "collapsed_sections": [], 427 | "name": "FINAL Inverted PyTorch Model P&ID LTTS.ipynb", 428 | "provenance": [] 429 | }, 430 | "gpuClass": "standard", 431 | "kernelspec": { 432 | "display_name": "Python 3", 433 | "language": "python", 434 | "name": "python3" 435 | }, 436 | "language_info": { 437 | "codemirror_mode": { 438 | "name": "ipython", 439 | "version": 3 440 | }, 441 | "file_extension": ".py", 442 | "mimetype": "text/x-python", 443 | "name": "python", 444 | "nbconvert_exporter": "python", 445 | "pygments_lexer": "ipython3", 446 | "version": "3.8.5" 447 | } 448 | }, 449 | "nbformat": 4, 450 | "nbformat_minor": 1 451 | } 452 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Automated-PnID-Symbol-Detection-and-Labelling 2 | ## We have developed a system for detecting and labelling various P&ID symbols.
3 | The system is designed to:
4 | 13 | image 14 | 15 | ## Tech Stack 16 | PyTorch, MMOCR, EAST text detection, OpenCV, PIL, Numpy 17 | 18 | ## How it works? 19 | The system works in 2 stages: 20 |
    21 |
  1. Custom object detection step: 22 | 28 |
  2. 29 | 30 |
  3. OCR and text processing step: 31 | 37 |
  4. 38 |
39 | 40 | ## Setup 41 | The solution has been tested on Ubuntu 20.04, Mac OS Montery, Windows 10 and 11 (Git Bash) and Google Colab. 42 | ### Conda Environment: 43 | ``` 44 | conda create -n PnID python=3.7.13 45 | conda activate PnID 46 | ``` 47 | ### Installing requirements: 48 | ``` 49 | git clone https://github.com/aneeshbhattacharya/Automated-PnID-Symbol-Detection-and-Labelling.git 50 | cd Automated-PnID-Symbol-Detection-and-Labelling 51 | sudo chmod +x build.sh 52 | ./build.sh 53 | ``` 54 | ### Download EAST model: 55 | ``` 56 | https://www.dropbox.com/s/r2ingd0l3zt8hxs/frozen_east_text_detection.tar.gz?dl=1 57 | ``` 58 | Put the file in the MMOCR directory 59 | ### Run the code: 60 | ``` 61 | cd main_driver 62 | jupyter-notebook 63 | ``` 64 | Open Aneesh_Risav_P&ID_Detection_and_Labelling_System.ipynb 65 | 66 | ## Tweaking the P&ID symbol detection model 67 | 92 | 93 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | conda install notebook 2 | pip install -r requirements.txt 3 | pip install imutils 4 | pip install mmcv-full -f https://download.openmmlab.com/mmcv/dist/cu111/torch1.10.0/index.html 5 | pip install mmdet 6 | git clone https://github.com/open-mmlab/mmocr.git 7 | cd mmocr 8 | pip install -r requirements.txt 9 | pip install -v -e . 10 | cd .. 11 | pip uninstall mmcv mmcv-full 12 | git clone https://github.com/open-mmlab/mmcv.git 13 | cd mmcv 14 | MMCV_WITH_OPS=1 pip install -e . -------------------------------------------------------------------------------- /main_driver/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneeshbhattacharya/Automated-PnID-Symbol-Detection-and-Labelling/dc56e2dc43630c74ae7350286e95c248595b5e96/main_driver/3.jpg -------------------------------------------------------------------------------- /main_driver/3.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneeshbhattacharya/Automated-PnID-Symbol-Detection-and-Labelling/dc56e2dc43630c74ae7350286e95c248595b5e96/main_driver/3.zip -------------------------------------------------------------------------------- /main_driver/Actual Output (on CPU machine)/FINAL_P&ID.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneeshbhattacharya/Automated-PnID-Symbol-Detection-and-Labelling/dc56e2dc43630c74ae7350286e95c248595b5e96/main_driver/Actual Output (on CPU machine)/FINAL_P&ID.jpg -------------------------------------------------------------------------------- /main_driver/Actual Output (on CPU machine)/FINAL_RESULT.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneeshbhattacharya/Automated-PnID-Symbol-Detection-and-Labelling/dc56e2dc43630c74ae7350286e95c248595b5e96/main_driver/Actual Output (on CPU machine)/FINAL_RESULT.xlsx -------------------------------------------------------------------------------- /main_driver/Aneesh_Risav_P&ID_Detection_and_Labelling_System.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "colab": { 8 | "base_uri": "https://localhost:8080/" 9 | }, 10 | "id": "Z4axnRwO7djX", 11 | "outputId": "1e592a54-2539-41c6-e32e-e1d8d41e08c1" 12 | }, 13 | "outputs": [], 14 | "source": [ 15 | "import shutil\n", 16 | "import cv2\n", 17 | "import numpy as np\n", 18 | "import matplotlib.pyplot as plt\n", 19 | "import os\n", 20 | "from pylab import *\n", 21 | "from skimage import data\n", 22 | "from skimage.viewer.canvastools import RectangleTool\n", 23 | "from skimage.viewer import ImageViewer\n", 24 | "from tqdm import tqdm\n", 25 | "import torch\n", 26 | "import torch.nn as nn \n", 27 | "import torch.optim as optim \n", 28 | "import torchvision.transforms as transforms \n", 29 | "import torch.nn.functional as F\n", 30 | "import torchvision\n", 31 | "import pandas as pd\n", 32 | "from skimage import io\n", 33 | "from torch.utils.data import (\n", 34 | " Dataset,\n", 35 | " DataLoader,\n", 36 | ") \n", 37 | "from PIL import Image\n", 38 | "import math\n", 39 | "import json" 40 | ] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "execution_count": null, 45 | "metadata": { 46 | "id": "3IXVLZOJO-_E" 47 | }, 48 | "outputs": [], 49 | "source": [ 50 | "if os.path.exists(\"../mmocr\") == False:\n", 51 | " print(\"MMOCR not installed. Please run BASH script first\")" 52 | ] 53 | }, 54 | { 55 | "cell_type": "code", 56 | "execution_count": null, 57 | "metadata": { 58 | "colab": { 59 | "base_uri": "https://localhost:8080/" 60 | }, 61 | "id": "-tqG3xRGI5HK", 62 | "outputId": "ea44eb45-14c5-4144-e0f9-3bbf4a2543e7" 63 | }, 64 | "outputs": [], 65 | "source": [ 66 | "print(torch.__version__)" 67 | ] 68 | }, 69 | { 70 | "cell_type": "markdown", 71 | "metadata": { 72 | "id": "Q4QxGzUuH35T" 73 | }, 74 | "source": [ 75 | "Load PyTorch Model and helpers\n" 76 | ] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "execution_count": null, 81 | "metadata": { 82 | "id": "5oPmn3QBH5s8" 83 | }, 84 | "outputs": [], 85 | "source": [ 86 | "class FCN(nn.Module):\n", 87 | " def __init__(self,in_channels = 1,num_classes=7):\n", 88 | " super(FCN,self).__init__()\n", 89 | " self.conv1 = nn.Sequential(\n", 90 | " nn.Conv2d(in_channels=1, out_channels=32, kernel_size=(3,3), stride=(1,1), padding=(1,1)),\n", 91 | " nn.BatchNorm2d(32, momentum=0.01),\n", 92 | " nn.ReLU(inplace=True),\n", 93 | " nn.Conv2d(in_channels=32, out_channels=32, kernel_size=(3,3), stride=(1,1), padding=(1,1)),\n", 94 | " nn.MaxPool2d(kernel_size=2),\n", 95 | " )\n", 96 | " self.conv2 = nn.Sequential(\n", 97 | " nn.Conv2d(in_channels=32, out_channels=64, kernel_size=(3,3), stride=(1,1), padding=(1,1)),\n", 98 | " nn.BatchNorm2d(64, momentum=0.01),\n", 99 | " nn.ReLU(inplace=True),\n", 100 | " nn.Conv2d(in_channels=64, out_channels=64, kernel_size=(3,3), stride=(1,1), padding=(1,1)),\n", 101 | " nn.MaxPool2d(kernel_size=2),\n", 102 | " )\n", 103 | " self.conv3 = nn.Sequential(\n", 104 | " nn.Conv2d(in_channels=64, out_channels=64, kernel_size=(3,3), stride=(1,1), padding=(1,1)),\n", 105 | " nn.BatchNorm2d(64, momentum=0.01),\n", 106 | " nn.ReLU(inplace=True),\n", 107 | " nn.Conv2d(in_channels=64, out_channels=64, kernel_size=(3,3), stride=(1,1), padding=(1,1)),\n", 108 | " nn.MaxPool2d(kernel_size=2),\n", 109 | " )\n", 110 | " self.fc1 = nn.Sequential(\n", 111 | " nn.Linear(20736,256),\n", 112 | " nn.ReLU(inplace=True),\n", 113 | " nn.Dropout(p=0.25),\n", 114 | " nn.BatchNorm1d(256)\n", 115 | " )\n", 116 | " self.fc2 = nn.Sequential(\n", 117 | " nn.Linear(256,128),\n", 118 | " nn.ReLU(inplace=True),\n", 119 | " nn.Dropout(p=0.25),\n", 120 | " nn.BatchNorm1d(128)\n", 121 | " )\n", 122 | " self.fc3 = nn.Sequential(\n", 123 | " nn.Linear(128,64),\n", 124 | " nn.ReLU(inplace=True),\n", 125 | " nn.Dropout(p=0.25),\n", 126 | " nn.BatchNorm1d(64)\n", 127 | " )\n", 128 | " self.fc4 = nn.Linear(64,7)\n", 129 | "\n", 130 | " def forward(self,x):\n", 131 | " x = self.conv1(x)\n", 132 | " x = self.conv2(x)\n", 133 | " x = self.conv3(x)\n", 134 | " x = x.reshape(x.shape[0],-1)\n", 135 | " # print(x.shape)\n", 136 | " x = self.fc1(x)\n", 137 | " x = self.fc2(x)\n", 138 | " x = self.fc3(x)\n", 139 | " x = F.softmax(self.fc4(x),dim=1)\n", 140 | " return x" 141 | ] 142 | }, 143 | { 144 | "cell_type": "code", 145 | "execution_count": null, 146 | "metadata": { 147 | "colab": { 148 | "base_uri": "https://localhost:8080/" 149 | }, 150 | "id": "xKi9RdA2IPaZ", 151 | "outputId": "4c31bd4a-7c35-475c-cb15-708903eddd0b" 152 | }, 153 | "outputs": [], 154 | "source": [ 155 | "model_location = input(\"Enter model location: \")\n", 156 | "\n", 157 | "model = FCN()\n", 158 | "x = torch.randn(64,1,150,150)\n", 159 | "device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n", 160 | "print(\"Setting model up on\",device)\n", 161 | "if torch.cuda.is_available() == True:\n", 162 | " model.cuda()\n", 163 | " model.load_state_dict(torch.load(model_location))\n", 164 | "\n", 165 | "else:\n", 166 | " my_model = model.load_state_dict(torch.load(model_location, map_location=torch.device('cpu')))\n", 167 | "\n", 168 | "data_transform = transforms.Compose([\n", 169 | " transforms.Lambda(lambda x:torch.from_numpy(np.expand_dims(np.array(x),axis=0)).float())\n", 170 | " ])\n", 171 | "\n", 172 | "model.eval() \n", 173 | "print(\"Model ready\")" 174 | ] 175 | }, 176 | { 177 | "cell_type": "markdown", 178 | "metadata": { 179 | "id": "i5F6UlnP8IO9" 180 | }, 181 | "source": [ 182 | "Load and Display a P&ID Sheet\n" 183 | ] 184 | }, 185 | { 186 | "cell_type": "code", 187 | "execution_count": null, 188 | "metadata": { 189 | "colab": { 190 | "base_uri": "https://localhost:8080/", 191 | "height": 282 192 | }, 193 | "id": "okxJpwDE8BfS", 194 | "outputId": "9a04139a-247a-47b2-c8db-12ac0aa8c140" 195 | }, 196 | "outputs": [], 197 | "source": [ 198 | "read_location = input('Enter P&ID image file: ')\n", 199 | "img = cv2.imread(read_location,0)\n", 200 | "plt.imshow(img,cmap='gray')\n", 201 | "plt.show()" 202 | ] 203 | }, 204 | { 205 | "cell_type": "markdown", 206 | "metadata": { 207 | "id": "KU5tPPfc9TWB" 208 | }, 209 | "source": [ 210 | "Get ROI from image\n", 211 | "1. Roughly estimate the x range and y range for a valid diagram (try to exclude unecessary regions like the entire text area on the side to avoid wasting time)\n", 212 | "2. For the above x = 400 to 5600 roughly and y = 250 to 5000 roughly" 213 | ] 214 | }, 215 | { 216 | "cell_type": "code", 217 | "execution_count": null, 218 | "metadata": { 219 | "colab": { 220 | "base_uri": "https://localhost:8080/" 221 | }, 222 | "id": "iniFsWdz9g2F", 223 | "outputId": "79a44d0a-e139-43af-a145-653d466b4a27" 224 | }, 225 | "outputs": [], 226 | "source": [ 227 | "x_start = int(input(\"x start: \"))\n", 228 | "x_end = int(input(\"x_end: \"))\n", 229 | "y_start = int(input(\"y_start: \"))\n", 230 | "y_end = int(input(\"y_end: \"))" 231 | ] 232 | }, 233 | { 234 | "cell_type": "code", 235 | "execution_count": null, 236 | "metadata": { 237 | "colab": { 238 | "base_uri": "https://localhost:8080/", 239 | "height": 286 240 | }, 241 | "id": "Ym0d51sd-nGM", 242 | "outputId": "3fdc1144-e76b-4026-c5a1-2337e6033105" 243 | }, 244 | "outputs": [], 245 | "source": [ 246 | "ready_img = img[y_start:y_end,x_start:x_end]\n", 247 | "print(\"Image to work on:\")\n", 248 | "plt.imshow(ready_img,cmap='gray')\n", 249 | "plt.show()" 250 | ] 251 | }, 252 | { 253 | "cell_type": "markdown", 254 | "metadata": { 255 | "id": "fVjW958s8Uzz" 256 | }, 257 | "source": [ 258 | "Re-Color image into black and white" 259 | ] 260 | }, 261 | { 262 | "cell_type": "code", 263 | "execution_count": null, 264 | "metadata": { 265 | "id": "crFOXuWf8SZm" 266 | }, 267 | "outputs": [], 268 | "source": [ 269 | "def recolor_crop(crop):\n", 270 | " for i in tqdm(range(len(crop))):\n", 271 | " for j in range(len(crop[0])):\n", 272 | " if crop[i][j] >=120:\n", 273 | " crop[i][j] = 225\n", 274 | " else:\n", 275 | " crop[i][j]=0\n", 276 | "\n", 277 | " return crop" 278 | ] 279 | }, 280 | { 281 | "cell_type": "code", 282 | "execution_count": null, 283 | "metadata": { 284 | "colab": { 285 | "base_uri": "https://localhost:8080/" 286 | }, 287 | "id": "XA3rCvj08Xuk", 288 | "outputId": "a4b5c4ee-7a51-480c-e082-e09af46eb86b" 289 | }, 290 | "outputs": [], 291 | "source": [ 292 | "colorized = recolor_crop(ready_img)" 293 | ] 294 | }, 295 | { 296 | "cell_type": "code", 297 | "execution_count": null, 298 | "metadata": { 299 | "id": "zOnU16bAYlxo" 300 | }, 301 | "outputs": [], 302 | "source": [ 303 | "main_img = colorized.copy()" 304 | ] 305 | }, 306 | { 307 | "cell_type": "code", 308 | "execution_count": null, 309 | "metadata": { 310 | "id": "gfbM4DY9Et3t" 311 | }, 312 | "outputs": [], 313 | "source": [ 314 | "def invert(x):\n", 315 | " for i in range(len(x)):\n", 316 | " for j in range(len(x[0])):\n", 317 | " if x[i][j] > 200:\n", 318 | " x[i][j] = 0\n", 319 | " else:\n", 320 | " x[i][j] = 1\n", 321 | " return x" 322 | ] 323 | }, 324 | { 325 | "cell_type": "markdown", 326 | "metadata": { 327 | "id": "_CLIhZfu8Lr-" 328 | }, 329 | "source": [ 330 | "Loop to traverse the sheet and obtain regions with information present" 331 | ] 332 | }, 333 | { 334 | "cell_type": "code", 335 | "execution_count": null, 336 | "metadata": { 337 | "id": "1k6mXm4t8LG9" 338 | }, 339 | "outputs": [], 340 | "source": [ 341 | "m,n = img.shape" 342 | ] 343 | }, 344 | { 345 | "cell_type": "code", 346 | "execution_count": null, 347 | "metadata": { 348 | "colab": { 349 | "base_uri": "https://localhost:8080/" 350 | }, 351 | "id": "_20RAkcUAjAR", 352 | "outputId": "d33205b2-fbcb-4491-bfa7-f789a3acf2a6" 353 | }, 354 | "outputs": [], 355 | "source": [ 356 | "objects_info = {}\n", 357 | "object_id = 0\n", 358 | "'''\n", 359 | "format:\n", 360 | " oject_info[1] : {\n", 361 | " class_id: int\n", 362 | " bounding_box = [xmin,xmax,ymin,ymax]\n", 363 | " }\n", 364 | "'''\n", 365 | "\n", 366 | "for i in tqdm(range(0,m-150,75)):\n", 367 | " for j in range(0,n-150,75):\n", 368 | " x_min = j\n", 369 | " x_max = j+150\n", 370 | " y_min = i\n", 371 | " y_max = i+150\n", 372 | "\n", 373 | " bounding_box = [x_min,x_max,y_min,y_max]\n", 374 | " \n", 375 | " xmid = x_min + ((x_max-x_min)//2)\n", 376 | " ymid = y_min + ((y_max-y_min)//2)\n", 377 | "\n", 378 | " centroid = [xmid,ymid]\n", 379 | "\n", 380 | " temp = main_img[y_min:y_max,x_min:x_max]\n", 381 | " window = temp.copy()\n", 382 | "\n", 383 | " black = np.count_nonzero(window == 0)\n", 384 | " total = 150 * 150\n", 385 | "\n", 386 | " percentage_black = (black/total)*100\n", 387 | "\n", 388 | " if percentage_black>10:\n", 389 | " window = invert(window)\n", 390 | " im_pil = Image.fromarray(window)\n", 391 | " im = data_transform(im_pil)\n", 392 | " im_a = im.numpy()\n", 393 | " im_a = np.expand_dims(im_a, axis=0)\n", 394 | " t = torch.tensor(im_a)\n", 395 | " with torch.no_grad(): \n", 396 | " t = t.to(device) \n", 397 | " score = model(t)\n", 398 | "\n", 399 | " _, predictions = torch.max(score, 1)\n", 400 | "\n", 401 | " class_id = predictions.item()\n", 402 | " if class_id != 6:\n", 403 | "\n", 404 | " temp_dict = {\n", 405 | " \"class_id\":int(class_id),\n", 406 | " \"bounding_box\":bounding_box,\n", 407 | " \"centroid\":centroid\n", 408 | " }\n", 409 | "\n", 410 | " objects_info[object_id] = temp_dict\n", 411 | " object_id+=1\n", 412 | "\n", 413 | "\n", 414 | "\n", 415 | "\n" 416 | ] 417 | }, 418 | { 419 | "cell_type": "code", 420 | "execution_count": null, 421 | "metadata": { 422 | "id": "ABES5uxWpaYw" 423 | }, 424 | "outputs": [], 425 | "source": [ 426 | "def get_distance(x,y):\n", 427 | " xmid1 = x[0]\n", 428 | " ymid1 = x[1]\n", 429 | "\n", 430 | " xmid2 = y[0]\n", 431 | " ymid2 = y[1]\n", 432 | "\n", 433 | " return math.sqrt((ymid2-ymid1)**2 + (xmid2-xmid1)**2)\n", 434 | "\n" 435 | ] 436 | }, 437 | { 438 | "cell_type": "markdown", 439 | "metadata": { 440 | "id": "mAfAQNDSu_mA" 441 | }, 442 | "source": [ 443 | "Group bounding boxes" 444 | ] 445 | }, 446 | { 447 | "cell_type": "code", 448 | "execution_count": null, 449 | "metadata": { 450 | "id": "qMrO6cU8y2bs" 451 | }, 452 | "outputs": [], 453 | "source": [ 454 | "list_of_objects = list(objects_info.keys())\n", 455 | "groups = []\n", 456 | "\n", 457 | "for i in range(len(objects_info)):\n", 458 | " curr_object = objects_info[list_of_objects[i]]\n", 459 | " curr_centroid = curr_object['centroid']\n", 460 | " curr_class = curr_object['class_id']\n", 461 | "\n", 462 | " temp_grp = [i]\n", 463 | "\n", 464 | " for j in range(len(objects_info)):\n", 465 | " compare_object = objects_info[list_of_objects[j]]\n", 466 | " compare_centroid = compare_object['centroid']\n", 467 | " compare_class = compare_object['class_id']\n", 468 | "\n", 469 | " #Group using centroid and class preds\n", 470 | "\n", 471 | " if get_distance(curr_centroid,compare_centroid) < 80 and curr_class == compare_class:\n", 472 | " temp_grp.append(j)\n", 473 | "\n", 474 | " temp_grp.sort()\n", 475 | "\n", 476 | " groups.append(temp_grp)\n", 477 | "\n", 478 | "groups_dict = {}\n", 479 | "been_done = {}\n", 480 | "\n", 481 | "for i in groups:\n", 482 | " temp = i\n", 483 | "\n", 484 | " if temp[0] not in been_done.keys():\n", 485 | " been_done[temp[0]] = temp[0]\n", 486 | "\n", 487 | " main_key = been_done[temp[0]]\n", 488 | "\n", 489 | " if main_key not in groups_dict.keys():\n", 490 | " groups_dict[main_key] = []\n", 491 | "\n", 492 | " for j in temp:\n", 493 | " been_done[j] = main_key\n", 494 | "\n", 495 | "\n", 496 | " groups_dict[main_key].extend(temp)\n", 497 | "\n", 498 | "\n", 499 | " groups_dict[main_key] = list(set(groups_dict[main_key]))\n", 500 | " groups_dict[main_key].sort()\n" 501 | ] 502 | }, 503 | { 504 | "cell_type": "code", 505 | "execution_count": null, 506 | "metadata": { 507 | "id": "E6_7WV_FGXpr" 508 | }, 509 | "outputs": [], 510 | "source": [ 511 | "final_info = {}\n", 512 | "\n", 513 | "draw_img = colorized.copy()\n", 514 | "for i in groups_dict.keys():\n", 515 | " object_id = i\n", 516 | "\n", 517 | " x_min_list = []\n", 518 | " y_min_list = []\n", 519 | " x_max_list = []\n", 520 | " y_max_list = []\n", 521 | "\n", 522 | " for j in groups_dict[i]:\n", 523 | "\n", 524 | " xmin,xmax,ymin,ymax = objects_info[j]['bounding_box']\n", 525 | "\n", 526 | " x_min_list.append(xmin)\n", 527 | " x_max_list.append(xmax)\n", 528 | " y_min_list.append(ymin)\n", 529 | " y_max_list.append(ymax)\n", 530 | "\n", 531 | " xmin = min(x_min_list)\n", 532 | " ymin = min(y_min_list)\n", 533 | " xmax = max(x_max_list)\n", 534 | " ymax = max(y_max_list)\n", 535 | "\n", 536 | " xmid = xmin + ((xmax-xmin)//2)\n", 537 | " ymid = ymin + ((ymax-ymin)//2)\n", 538 | "\n", 539 | " xmin = xmid-80\n", 540 | " ymin = ymid-80\n", 541 | " xmax = xmid+80\n", 542 | " ymax = ymid+80\n", 543 | "\n", 544 | "\n", 545 | "\n", 546 | " class_id = objects_info[i]['class_id']\n", 547 | "\n", 548 | " temp = {}\n", 549 | " temp = {\n", 550 | " \"class_id\":class_id,\n", 551 | " \"bbox\": [xmin,xmax,ymin,ymax],\n", 552 | " \"centroid\": [xmid,ymid]\n", 553 | " }\n", 554 | "\n", 555 | " draw_img = cv2.rectangle(draw_img, (xmin,ymin), (xmax,ymax), (0,225,0), 5)\n", 556 | "\n", 557 | " final_info[i] = temp\n", 558 | "\n", 559 | "\n", 560 | "\n" 561 | ] 562 | }, 563 | { 564 | "cell_type": "markdown", 565 | "metadata": { 566 | "id": "dLs7YgyPvvYR" 567 | }, 568 | "source": [ 569 | "Group similar BBOXES and take only region of max area" 570 | ] 571 | }, 572 | { 573 | "cell_type": "code", 574 | "execution_count": null, 575 | "metadata": { 576 | "colab": { 577 | "base_uri": "https://localhost:8080/", 578 | "height": 680 579 | }, 580 | "id": "HV-SG9QutNKk", 581 | "outputId": "b99edf2b-e540-4338-85e5-244d4c45be4d" 582 | }, 583 | "outputs": [], 584 | "source": [ 585 | "modif_info = final_info.copy()\n", 586 | "for i in list(modif_info.keys()):\n", 587 | "\n", 588 | " if i not in modif_info.keys():\n", 589 | " continue\n", 590 | "\n", 591 | " curr_object = modif_info[i]\n", 592 | " x_min,x_max,y_min,y_max = curr_object['bbox']\n", 593 | " curr_class = curr_object['class_id']\n", 594 | "\n", 595 | " curr_centroid = curr_object['centroid']\n", 596 | "\n", 597 | " temp = main_img[y_min:y_max,x_min:x_max]\n", 598 | " window = temp.copy()\n", 599 | "\n", 600 | " black = np.count_nonzero(window == 0)\n", 601 | " total = 150 * 150\n", 602 | "\n", 603 | " curr_percentage_black = (black/total)*100\n", 604 | "\n", 605 | " for j in list(modif_info.keys()):\n", 606 | " \n", 607 | " if j not in modif_info.keys():\n", 608 | " continue\n", 609 | "\n", 610 | " if i!=j:\n", 611 | " compare_object = modif_info[j]\n", 612 | " x_min,x_max,y_min,y_max = compare_object['bbox']\n", 613 | " compare_class = compare_object['class_id']\n", 614 | "\n", 615 | " compare_centroid = compare_object['centroid']\n", 616 | "\n", 617 | " distance = get_distance(curr_centroid,compare_centroid)\n", 618 | " # print(distance)\n", 619 | "\n", 620 | " if distance < 150:\n", 621 | "\n", 622 | " temp = main_img[y_min:y_max,x_min:x_max]\n", 623 | " window = temp.copy()\n", 624 | "\n", 625 | " black = np.count_nonzero(window == 0)\n", 626 | " total = 150 * 150\n", 627 | "\n", 628 | " compare_percentage_black = (black/total)*100\n", 629 | "\n", 630 | " if compare_percentage_black + 1 <= curr_percentage_black:\n", 631 | " \n", 632 | " del modif_info[j]\n", 633 | "\n", 634 | "draw_img = colorized.copy()\n", 635 | "\n", 636 | "for i in modif_info.keys():\n", 637 | " obj = modif_info[i]\n", 638 | "\n", 639 | " xmin,xmax,ymin,ymax = obj['bbox']\n", 640 | "\n", 641 | " draw_img = cv2.rectangle(draw_img, (xmin,ymin), (xmax,ymax), (0,225,0), 5)\n", 642 | " cv2.putText(draw_img, str(i), (xmin, ymin-7), cv2.FONT_HERSHEY_SIMPLEX, 1.5, (0,225,0), 3)\n", 643 | "\n", 644 | "\n", 645 | "plt.figure(figsize=(15,30))\n", 646 | "plt.imshow(draw_img)\n", 647 | "plt.show()" 648 | ] 649 | }, 650 | { 651 | "cell_type": "code", 652 | "execution_count": null, 653 | "metadata": { 654 | "colab": { 655 | "base_uri": "https://localhost:8080/" 656 | }, 657 | "id": "uI4CUQDEzzQu", 658 | "outputId": "4c987b1a-c239-4e14-9f34-db0bdab8d406" 659 | }, 660 | "outputs": [], 661 | "source": [ 662 | "cv2.imwrite(\"./FINAL_P&ID.jpg\",draw_img)" 663 | ] 664 | }, 665 | { 666 | "cell_type": "markdown", 667 | "metadata": { 668 | "id": "CI7kPFOz5T9x" 669 | }, 670 | "source": [ 671 | "Text Processing" 672 | ] 673 | }, 674 | { 675 | "cell_type": "markdown", 676 | "metadata": { 677 | "id": "9jZnTxIJbtBk" 678 | }, 679 | "source": [ 680 | "MMOCR" 681 | ] 682 | }, 683 | { 684 | "cell_type": "code", 685 | "execution_count": null, 686 | "metadata": { 687 | "colab": { 688 | "base_uri": "https://localhost:8080/" 689 | }, 690 | "id": "uHOlbID5gBP1", 691 | "outputId": "b32dd509-7c6b-47af-fc83-13b464b9303f" 692 | }, 693 | "outputs": [], 694 | "source": [ 695 | "%cd .." 696 | ] 697 | }, 698 | { 699 | "cell_type": "code", 700 | "execution_count": null, 701 | "metadata": { 702 | "colab": { 703 | "base_uri": "https://localhost:8080/" 704 | }, 705 | "id": "8hyz5cm0gK0P", 706 | "outputId": "6063103e-8000-4ff5-d313-282b08e48822" 707 | }, 708 | "outputs": [], 709 | "source": [ 710 | "%cd ./mmocr/" 711 | ] 712 | }, 713 | { 714 | "cell_type": "code", 715 | "execution_count": null, 716 | "metadata": { 717 | "id": "s9wAVip3gWXy" 718 | }, 719 | "outputs": [], 720 | "source": [ 721 | "from mmocr.utils.ocr import MMOCR" 722 | ] 723 | }, 724 | { 725 | "cell_type": "code", 726 | "execution_count": null, 727 | "metadata": { 728 | "colab": { 729 | "base_uri": "https://localhost:8080/", 730 | "height": 220, 731 | "referenced_widgets": [ 732 | "2b7ab6742f214db994a391d183b6db64", 733 | "b428f0a7ed98414a8e2056458fd24810", 734 | "245efa2e37cf4196bcbd7f0f86825505", 735 | "c2a92fb28dee42298509ef573f7cf8ce", 736 | "8c59aa2e9a394c5980fdd8d6c018e14d", 737 | "5ff4b7fabddf45af8be5e5dd2228e888", 738 | "140d7c568911441897951cf6f24c2f34", 739 | "85065ddb50b14e25af406dbf86c33dff", 740 | "0e53a2a2ff1e4348bfe18a388fc941a6", 741 | "93ce3bbaaf644b539728d267499963af", 742 | "8334c219e72f46a6a9029b508821c27e", 743 | "b9113e42d57a4133a952f6add9cf5e0c", 744 | "8ba589bd271e4f27b220b351aa224822", 745 | "d77b3913be7042a2a106217562b25f02", 746 | "c8b257087c294218a2b98e977ebf0510", 747 | "f154739aa0224993a4882a360137735a", 748 | "43177202ba5248319babbe9cb59172ad", 749 | "0a9920a4fda541978d7437d084841ce4", 750 | "8179c511bdb24e04b5f5cf8ed62d3f6d", 751 | "13687fe7ef8044c2864934379f45735f", 752 | "c5b0f3ac08d14f8ab5c7d73590bcfa99", 753 | "b5955acf28aa4d17817e91d0c375ca5b" 754 | ] 755 | }, 756 | "id": "SurvemXdcJ3I", 757 | "outputId": "cfded080-975e-4193-aba7-67b2f50d089b" 758 | }, 759 | "outputs": [], 760 | "source": [ 761 | "ocr = MMOCR(det='PS_CTW', recog='SAR')" 762 | ] 763 | }, 764 | { 765 | "cell_type": "code", 766 | "execution_count": null, 767 | "metadata": {}, 768 | "outputs": [], 769 | "source": [ 770 | "!pip install imutils" 771 | ] 772 | }, 773 | { 774 | "cell_type": "code", 775 | "execution_count": null, 776 | "metadata": { 777 | "id": "LPBd07OMWCeV" 778 | }, 779 | "outputs": [], 780 | "source": [ 781 | "from imutils.object_detection import non_max_suppression" 782 | ] 783 | }, 784 | { 785 | "cell_type": "code", 786 | "execution_count": null, 787 | "metadata": { 788 | "colab": { 789 | "base_uri": "https://localhost:8080/" 790 | }, 791 | "id": "Ib7axzOyVJ-_", 792 | "outputId": "47dc77de-a211-4145-c875-849828318bde" 793 | }, 794 | "outputs": [], 795 | "source": [ 796 | "def east_detect(image):\n", 797 | " texts = [\"None\"]\n", 798 | " layerNames = [\n", 799 | " \t\"feature_fusion/Conv_7/Sigmoid\",\n", 800 | " \t\"feature_fusion/concat_3\"]\n", 801 | " \n", 802 | " image = np.pad(image, ((30,30),(30,30)),\"constant\", constant_values=(225,225))\n", 803 | "\n", 804 | " orig = image.copy()\n", 805 | " \n", 806 | " if len(image.shape) == 2:\n", 807 | " image = cv2.cvtColor(image, cv2.COLOR_GRAY2RGB)\n", 808 | " \n", 809 | " (H, W) = image.shape[:2]\n", 810 | "\n", 811 | " (newW, newH) = (160, 160)\n", 812 | " \n", 813 | " rW = W / float(newW)\n", 814 | " rH = H / float(newH)\n", 815 | "\n", 816 | " image = cv2.resize(image, (newW, newH))\n", 817 | " \n", 818 | " (H, W) = image.shape[:2]\n", 819 | " \n", 820 | " net = cv2.dnn.readNet(\"frozen_east_text_detection.pb\")\n", 821 | " \n", 822 | " blob = cv2.dnn.blobFromImage(image, 1.0, (W, H),\n", 823 | " \t(123.68, 116.78, 103.94), swapRB=True, crop=False)\n", 824 | " \n", 825 | " start = time.time()\n", 826 | " \n", 827 | " net.setInput(blob)\n", 828 | " \n", 829 | " (scores, geometry) = net.forward(layerNames)\n", 830 | " \n", 831 | " (numRows, numCols) = scores.shape[2:4]\n", 832 | " rects = []\n", 833 | " confidences = []\n", 834 | "\n", 835 | " for y in range(0, numRows):\n", 836 | " scoresData = scores[0, 0, y]\n", 837 | " xData0 = geometry[0, 0, y]\n", 838 | " xData1 = geometry[0, 1, y]\n", 839 | " xData2 = geometry[0, 2, y]\n", 840 | " xData3 = geometry[0, 3, y]\n", 841 | " anglesData = geometry[0, 4, y]\n", 842 | " \n", 843 | " for x in range(0, numCols):\n", 844 | " if scoresData[x] < 0.5:\n", 845 | " continue\n", 846 | "\n", 847 | " (offsetX, offsetY) = (x * 4.0, y * 4.0)\n", 848 | " angle = anglesData[x]\n", 849 | " cos = np.cos(angle)\n", 850 | " sin = np.sin(angle)\n", 851 | " h = xData0[x] + xData2[x]\n", 852 | " w = xData1[x] + xData3[x]\n", 853 | " endX = int(offsetX + (cos * xData1[x]) + (sin * xData2[x]))\n", 854 | " endY = int(offsetY - (sin * xData1[x]) + (cos * xData2[x]))\n", 855 | " startX = int(endX - w)\n", 856 | " startY = int(endY - h)\n", 857 | " rects.append((startX, startY, endX, endY))\n", 858 | " confidences.append(scoresData[x])\n", 859 | " \n", 860 | " boxes = non_max_suppression(np.array(rects), probs=confidences)\n", 861 | "\n", 862 | " if len(boxes) > 0: \n", 863 | " text_list = []\n", 864 | " for (startX, startY, endX, endY) in boxes:\n", 865 | " startX = int(startX * rW)\n", 866 | " startY = int(startY * rH)\n", 867 | " endX = int(endX * rW)\n", 868 | " endY = int(endY * rH)\n", 869 | "\n", 870 | " if startX-20 > 0:\n", 871 | " startX = startX-20\n", 872 | " if endX+20 < orig.shape[1]:\n", 873 | " endX = endX+20\n", 874 | " if startY-10 > 0:\n", 875 | " startY = startY-10\n", 876 | " if endY+10 < orig.shape[0]:\n", 877 | " endY = endY+10\n", 878 | "\n", 879 | " crop = orig[startY:endY, startX:endX]\n", 880 | "\n", 881 | " # plt.imshow(crop)\n", 882 | " # plt.show()\n", 883 | "\n", 884 | " if (endX - startX) < (endY - startY):\n", 885 | " crop = cv2.rotate(crop, cv2.ROTATE_90_CLOCKWISE)\n", 886 | " crop = np.pad(crop, ((20,20),(20,20)),\"constant\", constant_values=(225,225))\n", 887 | "\n", 888 | " region = cv2.cvtColor(crop,cv2.COLOR_GRAY2RGB)\n", 889 | " cv2.imwrite('temp.jpg',region)\n", 890 | "\n", 891 | " results = ocr.readtext('temp.jpg',print_result=False)\n", 892 | "\n", 893 | " temp_dict = results[0]\n", 894 | " texts = temp_dict['text']\n", 895 | "\n", 896 | " break\n", 897 | "\n", 898 | " else:\n", 899 | " crop = np.pad(crop, ((20,20),(20,20)),\"constant\", constant_values=(225,225))\n", 900 | " region = cv2.cvtColor(crop,cv2.COLOR_GRAY2RGB)\n", 901 | "\n", 902 | " cv2.imwrite('temp.jpg',orig)\n", 903 | "\n", 904 | " results = ocr.readtext('temp.jpg',print_result=False)\n", 905 | "\n", 906 | " temp_dict = results[0]\n", 907 | " texts = temp_dict['text']\n", 908 | " break\n", 909 | "\n", 910 | " return texts" 911 | ] 912 | }, 913 | { 914 | "cell_type": "code", 915 | "execution_count": null, 916 | "metadata": { 917 | "colab": { 918 | "base_uri": "https://localhost:8080/" 919 | }, 920 | "id": "HhuI4q0FWYVd", 921 | "outputId": "99626e6a-d5f2-4313-f4e2-b1b85992b861" 922 | }, 923 | "outputs": [], 924 | "source": [ 925 | "final_dict = {}\n", 926 | "counter = 0\n", 927 | "\n", 928 | "text_img = colorized.copy()\n", 929 | "for i in modif_info.keys():\n", 930 | "\n", 931 | " temp_dict = {}\n", 932 | "\n", 933 | " obj = modif_info[i]\n", 934 | " class_id = obj['class_id']\n", 935 | " xmin,xmax,ymin,ymax = obj[\"bbox\"]\n", 936 | "\n", 937 | " temp_dict['bounding_box'] = [xmin,xmax,ymin,ymax]\n", 938 | " temp_dict['text'] = []\n", 939 | " temp_dict['class_id'] = class_id\n", 940 | " temp_dict['centroid'] = obj['centroid']\n", 941 | "\n", 942 | " xmin,xmax,ymin,ymax = xmin-20,xmax+20,ymin-20,ymax+20\n", 943 | "\n", 944 | " t = text_img[ymin:ymax,xmin:xmax]\n", 945 | "\n", 946 | " if class_id == 3:\n", 947 | "\n", 948 | "\n", 949 | " temp_dict['text'] = [\"Spectacle blind\"]\n", 950 | "\n", 951 | " elif class_id == 5:\n", 952 | "\n", 953 | " region = cv2.cvtColor(t,cv2.COLOR_GRAY2RGB)\n", 954 | " \n", 955 | " cv2.imwrite('temp.jpg',region)\n", 956 | "\n", 957 | " results = ocr.readtext('temp.jpg',print_result=False)\n", 958 | "\n", 959 | " temp_dict['text'] = results[0]['text']\n", 960 | "\n", 961 | "\n", 962 | " else:\n", 963 | " xmin,xmax,ymin,ymax = xmin-20,xmax+20,ymin-20,ymax+20\n", 964 | "\n", 965 | " r = text_img[ymin:ymax,xmin:xmax]\n", 966 | " text = east_detect(r)\n", 967 | "\n", 968 | " temp_dict['text'] = text\n", 969 | "\n", 970 | "\n", 971 | " final_dict[i] = temp_dict\n", 972 | " counter+=1\n" 973 | ] 974 | }, 975 | { 976 | "cell_type": "code", 977 | "execution_count": null, 978 | "metadata": { 979 | "id": "WwMNER7Virep" 980 | }, 981 | "outputs": [], 982 | "source": [ 983 | "final_temp = final_dict.copy()\n", 984 | "for i in list(final_temp.keys()):\n", 985 | "\n", 986 | " if i not in final_temp.keys():\n", 987 | " continue\n", 988 | "\n", 989 | " curr_object = final_temp[i]\n", 990 | " curr_centroid = curr_object['centroid']\n", 991 | "\n", 992 | " for j in list(final_temp.keys()):\n", 993 | " \n", 994 | " if j not in final_temp.keys():\n", 995 | " continue\n", 996 | "\n", 997 | " if i!=j:\n", 998 | " compare_object = final_temp[j]\n", 999 | " compare_centroid = compare_object['centroid']\n", 1000 | "\n", 1001 | " distance = get_distance(curr_centroid,compare_centroid)\n", 1002 | "\n", 1003 | " if distance < 50:\n", 1004 | " del final_temp[j]\n" 1005 | ] 1006 | }, 1007 | { 1008 | "cell_type": "markdown", 1009 | "metadata": { 1010 | "id": "80smDiO24Yex" 1011 | }, 1012 | "source": [ 1013 | "Post Processing of Outputs" 1014 | ] 1015 | }, 1016 | { 1017 | "cell_type": "code", 1018 | "execution_count": null, 1019 | "metadata": { 1020 | "id": "dgtbCzzP5XtC" 1021 | }, 1022 | "outputs": [], 1023 | "source": [ 1024 | "def getAlphabetCount(x):\n", 1025 | " counter = 0\n", 1026 | "\n", 1027 | " for i in x:\n", 1028 | " if i.isalpha() == True:\n", 1029 | " counter+=1\n", 1030 | " return counter" 1031 | ] 1032 | }, 1033 | { 1034 | "cell_type": "code", 1035 | "execution_count": null, 1036 | "metadata": { 1037 | "id": "4RxDl-RZ4X87" 1038 | }, 1039 | "outputs": [], 1040 | "source": [ 1041 | "out_dict = {}\n", 1042 | "\n", 1043 | "for i in final_temp.keys():\n", 1044 | "\n", 1045 | " obj = final_temp[i]\n", 1046 | " class_id = obj['class_id']\n", 1047 | " text_list = obj['text']\n", 1048 | "\n", 1049 | " \n", 1050 | "\n", 1051 | " item_label = \"Undefined\" # text ID of component\n", 1052 | " component_name = \"Undefined\" #Valve, instrument\n", 1053 | "\n", 1054 | " if class_id == 0:\n", 1055 | " component_name = \"Valve\"\n", 1056 | " if text_list[0] != \"None\":\n", 1057 | "\n", 1058 | " for j in text_list:\n", 1059 | "\n", 1060 | " count = getAlphabetCount(j)\n", 1061 | "\n", 1062 | " if len(j)>2 and count<4:\n", 1063 | " item_label = j.upper()\n", 1064 | " break\n", 1065 | " \n", 1066 | "\n", 1067 | " if class_id == 1:\n", 1068 | " component_name = \"Control Valve\"\n", 1069 | " item_label = \"CV\"\n", 1070 | " if text_list[0] != \"None\":\n", 1071 | "\n", 1072 | " for j in text_list:\n", 1073 | "\n", 1074 | " count = getAlphabetCount(j)\n", 1075 | "\n", 1076 | " if len(j)>2 and count<4:\n", 1077 | " item_label = j.upper()\n", 1078 | " break\n", 1079 | "\n", 1080 | " if class_id == 2:\n", 1081 | " component_name = \"Circular looking\"\n", 1082 | "\n", 1083 | " if text_list[0] != \"None\":\n", 1084 | "\n", 1085 | " for j in text_list:\n", 1086 | "\n", 1087 | " count = getAlphabetCount(j)\n", 1088 | "\n", 1089 | " if len(j)>2 and count<4:\n", 1090 | " item_label = j.upper()\n", 1091 | " break\n", 1092 | "\n", 1093 | " \n", 1094 | " if class_id == 3:\n", 1095 | " component_name = \"Spectacle Blind\"\n", 1096 | "\n", 1097 | " if text_list[0] != \"None\":\n", 1098 | "\n", 1099 | " for j in text_list:\n", 1100 | "\n", 1101 | " count = getAlphabetCount(j)\n", 1102 | "\n", 1103 | " if len(j)>2 and count<4:\n", 1104 | " item_label = j.upper()\n", 1105 | " break\n", 1106 | "\n", 1107 | " if class_id ==4:\n", 1108 | " \n", 1109 | " if text_list[0] != \"None\":\n", 1110 | " \n", 1111 | " search = \"INS\"\n", 1112 | " for j in text_list:\n", 1113 | " if search in j:\n", 1114 | " item_label = j.upper()\n", 1115 | " break\n", 1116 | "\n", 1117 | " if item_label == \"Undefined\":\n", 1118 | " item_label = \"CS\"\n", 1119 | " component_name = \"Inline Mixer/Filter\"\n", 1120 | "\n", 1121 | " if class_id ==5:\n", 1122 | "\n", 1123 | " component_name = \"Instrument\"\n", 1124 | "\n", 1125 | " if text_list[0] != None:\n", 1126 | " \n", 1127 | " if len(text_list) > 1:\n", 1128 | "\n", 1129 | " for x in range(len(text_list)-1):\n", 1130 | " curr = text_list[x]\n", 1131 | " next = text_list[x+1]\n", 1132 | "\n", 1133 | " count = getAlphabetCount(curr)\n", 1134 | "\n", 1135 | " if count>0:\n", 1136 | " if next.isnumeric():\n", 1137 | " item_label = curr+\";\"+next\n", 1138 | " break\n", 1139 | "\n", 1140 | " \n", 1141 | " temp_dict = {}\n", 1142 | "\n", 1143 | " temp_dict['class_id'] = class_id\n", 1144 | " temp_dict['bounding_box'] = obj['bounding_box']\n", 1145 | " temp_dict['component_name'] = component_name\n", 1146 | " temp_dict['item_name'] = item_label\n", 1147 | "\n", 1148 | " out_dict[i] = temp_dict\n" 1149 | ] 1150 | }, 1151 | { 1152 | "cell_type": "code", 1153 | "execution_count": null, 1154 | "metadata": { 1155 | "id": "sHuofk3c_K82" 1156 | }, 1157 | "outputs": [], 1158 | "source": [ 1159 | "pd_dict = {\n", 1160 | "\n", 1161 | " \"Object-ID\":[],\n", 1162 | " \"Class-ID\":[],\n", 1163 | " \"Component Name\":[],\n", 1164 | " \"Item Label\":[],\n", 1165 | " \"Location (xmin,xmax,ymin,ymax)\":[]\n", 1166 | "\n", 1167 | "}\n", 1168 | "for i in out_dict.keys():\n", 1169 | " object_id = i\n", 1170 | " class_id = out_dict[i]['class_id']\n", 1171 | " component_name = out_dict[i]['component_name']\n", 1172 | " item_name = out_dict[i]['item_name']\n", 1173 | " bbox = out_dict[i]['bounding_box']\n", 1174 | " location = \"\".join(str(x)+\",\" for x in bbox)\n", 1175 | "\n", 1176 | " pd_dict[\"Object-ID\"].append(object_id)\n", 1177 | " pd_dict[\"Class-ID\"].append(class_id)\n", 1178 | " pd_dict[\"Component Name\"].append(component_name)\n", 1179 | " pd_dict[\"Item Label\"].append(item_name)\n", 1180 | " pd_dict[\"Location (xmin,xmax,ymin,ymax)\"].append(location)" 1181 | ] 1182 | }, 1183 | { 1184 | "cell_type": "code", 1185 | "execution_count": null, 1186 | "metadata": {}, 1187 | "outputs": [], 1188 | "source": [ 1189 | "%cd ..\n", 1190 | "%cd main_driver" 1191 | ] 1192 | }, 1193 | { 1194 | "cell_type": "code", 1195 | "execution_count": null, 1196 | "metadata": { 1197 | "id": "1Y0ffmghAMLv" 1198 | }, 1199 | "outputs": [], 1200 | "source": [ 1201 | "import pandas as pd" 1202 | ] 1203 | }, 1204 | { 1205 | "cell_type": "code", 1206 | "execution_count": null, 1207 | "metadata": { 1208 | "id": "ctzH6EC7AOk3" 1209 | }, 1210 | "outputs": [], 1211 | "source": [ 1212 | "df = pd.DataFrame(pd_dict) " 1213 | ] 1214 | }, 1215 | { 1216 | "cell_type": "code", 1217 | "execution_count": null, 1218 | "metadata": { 1219 | "id": "KTuhRykSAmwc" 1220 | }, 1221 | "outputs": [], 1222 | "source": [ 1223 | "df.to_excel('./FINAL_RESULT.xlsx')" 1224 | ] 1225 | }, 1226 | { 1227 | "cell_type": "code", 1228 | "execution_count": null, 1229 | "metadata": { 1230 | "colab": { 1231 | "base_uri": "https://localhost:8080/", 1232 | "height": 35 1233 | }, 1234 | "id": "_A3ZnErYMfkc", 1235 | "outputId": "5546ff3d-caa0-4598-e5f3-06b139a6a437" 1236 | }, 1237 | "outputs": [], 1238 | "source": [ 1239 | "name = os.path.basename(read_location)\n", 1240 | "name = name.split(\".\")[0]\n", 1241 | "folder = os.path.dirname(read_location)\n", 1242 | "folder_name = folder+\"/\"+name\n", 1243 | "\n", 1244 | "if os.path.exists(folder+\"/temp\") == False:\n", 1245 | " os.makedirs(folder+\"/temp\")\n", 1246 | "\n", 1247 | "dst = folder+\"/temp\"\n", 1248 | "source1 = folder+\"/FINAL_P&ID.jpg\"\n", 1249 | "source2 = folder+\"/FINAL_RESULT.xlsx\"\n", 1250 | "shutil.copy(source1, dst)\n", 1251 | "shutil.copy(source2,dst)\n", 1252 | "\n", 1253 | "shutil.make_archive(folder_name,'zip',dst)" 1254 | ] 1255 | } 1256 | ], 1257 | "metadata": { 1258 | "accelerator": "GPU", 1259 | "colab": { 1260 | "collapsed_sections": [], 1261 | "name": "Testing Inverted LTTS P&ID Detection and Labelling System.ipynb", 1262 | "provenance": [] 1263 | }, 1264 | "gpuClass": "standard", 1265 | "kernelspec": { 1266 | "display_name": "Python 3", 1267 | "language": "python", 1268 | "name": "python3" 1269 | }, 1270 | "language_info": { 1271 | "codemirror_mode": { 1272 | "name": "ipython", 1273 | "version": 3 1274 | }, 1275 | "file_extension": ".py", 1276 | "mimetype": "text/x-python", 1277 | "name": "python", 1278 | "nbconvert_exporter": "python", 1279 | "pygments_lexer": "ipython3", 1280 | "version": "3.8.5" 1281 | }, 1282 | "widgets": { 1283 | "application/vnd.jupyter.widget-state+json": { 1284 | "0a9920a4fda541978d7437d084841ce4": { 1285 | "model_module": "@jupyter-widgets/controls", 1286 | "model_module_version": "1.5.0", 1287 | "model_name": "DescriptionStyleModel", 1288 | "state": { 1289 | "_model_module": "@jupyter-widgets/controls", 1290 | "_model_module_version": "1.5.0", 1291 | "_model_name": "DescriptionStyleModel", 1292 | "_view_count": null, 1293 | "_view_module": "@jupyter-widgets/base", 1294 | "_view_module_version": "1.2.0", 1295 | "_view_name": "StyleView", 1296 | "description_width": "" 1297 | } 1298 | }, 1299 | "0e53a2a2ff1e4348bfe18a388fc941a6": { 1300 | "model_module": "@jupyter-widgets/controls", 1301 | "model_module_version": "1.5.0", 1302 | "model_name": "ProgressStyleModel", 1303 | "state": { 1304 | "_model_module": "@jupyter-widgets/controls", 1305 | "_model_module_version": "1.5.0", 1306 | "_model_name": "ProgressStyleModel", 1307 | "_view_count": null, 1308 | "_view_module": "@jupyter-widgets/base", 1309 | "_view_module_version": "1.2.0", 1310 | "_view_name": "StyleView", 1311 | "bar_color": null, 1312 | "description_width": "" 1313 | } 1314 | }, 1315 | "13687fe7ef8044c2864934379f45735f": { 1316 | "model_module": "@jupyter-widgets/controls", 1317 | "model_module_version": "1.5.0", 1318 | "model_name": "ProgressStyleModel", 1319 | "state": { 1320 | "_model_module": "@jupyter-widgets/controls", 1321 | "_model_module_version": "1.5.0", 1322 | "_model_name": "ProgressStyleModel", 1323 | "_view_count": null, 1324 | "_view_module": "@jupyter-widgets/base", 1325 | "_view_module_version": "1.2.0", 1326 | "_view_name": "StyleView", 1327 | "bar_color": null, 1328 | "description_width": "" 1329 | } 1330 | }, 1331 | "140d7c568911441897951cf6f24c2f34": { 1332 | "model_module": "@jupyter-widgets/controls", 1333 | "model_module_version": "1.5.0", 1334 | "model_name": "DescriptionStyleModel", 1335 | "state": { 1336 | "_model_module": "@jupyter-widgets/controls", 1337 | "_model_module_version": "1.5.0", 1338 | "_model_name": "DescriptionStyleModel", 1339 | "_view_count": null, 1340 | "_view_module": "@jupyter-widgets/base", 1341 | "_view_module_version": "1.2.0", 1342 | "_view_name": "StyleView", 1343 | "description_width": "" 1344 | } 1345 | }, 1346 | "245efa2e37cf4196bcbd7f0f86825505": { 1347 | "model_module": "@jupyter-widgets/controls", 1348 | "model_module_version": "1.5.0", 1349 | "model_name": "FloatProgressModel", 1350 | "state": { 1351 | "_dom_classes": [], 1352 | "_model_module": "@jupyter-widgets/controls", 1353 | "_model_module_version": "1.5.0", 1354 | "_model_name": "FloatProgressModel", 1355 | "_view_count": null, 1356 | "_view_module": "@jupyter-widgets/controls", 1357 | "_view_module_version": "1.5.0", 1358 | "_view_name": "ProgressView", 1359 | "bar_style": "success", 1360 | "description": "", 1361 | "description_tooltip": null, 1362 | "layout": "IPY_MODEL_85065ddb50b14e25af406dbf86c33dff", 1363 | "max": 114790078, 1364 | "min": 0, 1365 | "orientation": "horizontal", 1366 | "style": "IPY_MODEL_0e53a2a2ff1e4348bfe18a388fc941a6", 1367 | "value": 114790078 1368 | } 1369 | }, 1370 | "2b7ab6742f214db994a391d183b6db64": { 1371 | "model_module": "@jupyter-widgets/controls", 1372 | "model_module_version": "1.5.0", 1373 | "model_name": "HBoxModel", 1374 | "state": { 1375 | "_dom_classes": [], 1376 | "_model_module": "@jupyter-widgets/controls", 1377 | "_model_module_version": "1.5.0", 1378 | "_model_name": "HBoxModel", 1379 | "_view_count": null, 1380 | "_view_module": "@jupyter-widgets/controls", 1381 | "_view_module_version": "1.5.0", 1382 | "_view_name": "HBoxView", 1383 | "box_style": "", 1384 | "children": [ 1385 | "IPY_MODEL_b428f0a7ed98414a8e2056458fd24810", 1386 | "IPY_MODEL_245efa2e37cf4196bcbd7f0f86825505", 1387 | "IPY_MODEL_c2a92fb28dee42298509ef573f7cf8ce" 1388 | ], 1389 | "layout": "IPY_MODEL_8c59aa2e9a394c5980fdd8d6c018e14d" 1390 | } 1391 | }, 1392 | "43177202ba5248319babbe9cb59172ad": { 1393 | "model_module": "@jupyter-widgets/base", 1394 | "model_module_version": "1.2.0", 1395 | "model_name": "LayoutModel", 1396 | "state": { 1397 | "_model_module": "@jupyter-widgets/base", 1398 | "_model_module_version": "1.2.0", 1399 | "_model_name": "LayoutModel", 1400 | "_view_count": null, 1401 | "_view_module": "@jupyter-widgets/base", 1402 | "_view_module_version": "1.2.0", 1403 | "_view_name": "LayoutView", 1404 | "align_content": null, 1405 | "align_items": null, 1406 | "align_self": null, 1407 | "border": null, 1408 | "bottom": null, 1409 | "display": null, 1410 | "flex": null, 1411 | "flex_flow": null, 1412 | "grid_area": null, 1413 | "grid_auto_columns": null, 1414 | "grid_auto_flow": null, 1415 | "grid_auto_rows": null, 1416 | "grid_column": null, 1417 | "grid_gap": null, 1418 | "grid_row": null, 1419 | "grid_template_areas": null, 1420 | "grid_template_columns": null, 1421 | "grid_template_rows": null, 1422 | "height": null, 1423 | "justify_content": null, 1424 | "justify_items": null, 1425 | "left": null, 1426 | "margin": null, 1427 | "max_height": null, 1428 | "max_width": null, 1429 | "min_height": null, 1430 | "min_width": null, 1431 | "object_fit": null, 1432 | "object_position": null, 1433 | "order": null, 1434 | "overflow": null, 1435 | "overflow_x": null, 1436 | "overflow_y": null, 1437 | "padding": null, 1438 | "right": null, 1439 | "top": null, 1440 | "visibility": null, 1441 | "width": null 1442 | } 1443 | }, 1444 | "5ff4b7fabddf45af8be5e5dd2228e888": { 1445 | "model_module": "@jupyter-widgets/base", 1446 | "model_module_version": "1.2.0", 1447 | "model_name": "LayoutModel", 1448 | "state": { 1449 | "_model_module": "@jupyter-widgets/base", 1450 | "_model_module_version": "1.2.0", 1451 | "_model_name": "LayoutModel", 1452 | "_view_count": null, 1453 | "_view_module": "@jupyter-widgets/base", 1454 | "_view_module_version": "1.2.0", 1455 | "_view_name": "LayoutView", 1456 | "align_content": null, 1457 | "align_items": null, 1458 | "align_self": null, 1459 | "border": null, 1460 | "bottom": null, 1461 | "display": null, 1462 | "flex": null, 1463 | "flex_flow": null, 1464 | "grid_area": null, 1465 | "grid_auto_columns": null, 1466 | "grid_auto_flow": null, 1467 | "grid_auto_rows": null, 1468 | "grid_column": null, 1469 | "grid_gap": null, 1470 | "grid_row": null, 1471 | "grid_template_areas": null, 1472 | "grid_template_columns": null, 1473 | "grid_template_rows": null, 1474 | "height": null, 1475 | "justify_content": null, 1476 | "justify_items": null, 1477 | "left": null, 1478 | "margin": null, 1479 | "max_height": null, 1480 | "max_width": null, 1481 | "min_height": null, 1482 | "min_width": null, 1483 | "object_fit": null, 1484 | "object_position": null, 1485 | "order": null, 1486 | "overflow": null, 1487 | "overflow_x": null, 1488 | "overflow_y": null, 1489 | "padding": null, 1490 | "right": null, 1491 | "top": null, 1492 | "visibility": null, 1493 | "width": null 1494 | } 1495 | }, 1496 | "8179c511bdb24e04b5f5cf8ed62d3f6d": { 1497 | "model_module": "@jupyter-widgets/base", 1498 | "model_module_version": "1.2.0", 1499 | "model_name": "LayoutModel", 1500 | "state": { 1501 | "_model_module": "@jupyter-widgets/base", 1502 | "_model_module_version": "1.2.0", 1503 | "_model_name": "LayoutModel", 1504 | "_view_count": null, 1505 | "_view_module": "@jupyter-widgets/base", 1506 | "_view_module_version": "1.2.0", 1507 | "_view_name": "LayoutView", 1508 | "align_content": null, 1509 | "align_items": null, 1510 | "align_self": null, 1511 | "border": null, 1512 | "bottom": null, 1513 | "display": null, 1514 | "flex": null, 1515 | "flex_flow": null, 1516 | "grid_area": null, 1517 | "grid_auto_columns": null, 1518 | "grid_auto_flow": null, 1519 | "grid_auto_rows": null, 1520 | "grid_column": null, 1521 | "grid_gap": null, 1522 | "grid_row": null, 1523 | "grid_template_areas": null, 1524 | "grid_template_columns": null, 1525 | "grid_template_rows": null, 1526 | "height": null, 1527 | "justify_content": null, 1528 | "justify_items": null, 1529 | "left": null, 1530 | "margin": null, 1531 | "max_height": null, 1532 | "max_width": null, 1533 | "min_height": null, 1534 | "min_width": null, 1535 | "object_fit": null, 1536 | "object_position": null, 1537 | "order": null, 1538 | "overflow": null, 1539 | "overflow_x": null, 1540 | "overflow_y": null, 1541 | "padding": null, 1542 | "right": null, 1543 | "top": null, 1544 | "visibility": null, 1545 | "width": null 1546 | } 1547 | }, 1548 | "8334c219e72f46a6a9029b508821c27e": { 1549 | "model_module": "@jupyter-widgets/controls", 1550 | "model_module_version": "1.5.0", 1551 | "model_name": "DescriptionStyleModel", 1552 | "state": { 1553 | "_model_module": "@jupyter-widgets/controls", 1554 | "_model_module_version": "1.5.0", 1555 | "_model_name": "DescriptionStyleModel", 1556 | "_view_count": null, 1557 | "_view_module": "@jupyter-widgets/base", 1558 | "_view_module_version": "1.2.0", 1559 | "_view_name": "StyleView", 1560 | "description_width": "" 1561 | } 1562 | }, 1563 | "85065ddb50b14e25af406dbf86c33dff": { 1564 | "model_module": "@jupyter-widgets/base", 1565 | "model_module_version": "1.2.0", 1566 | "model_name": "LayoutModel", 1567 | "state": { 1568 | "_model_module": "@jupyter-widgets/base", 1569 | "_model_module_version": "1.2.0", 1570 | "_model_name": "LayoutModel", 1571 | "_view_count": null, 1572 | "_view_module": "@jupyter-widgets/base", 1573 | "_view_module_version": "1.2.0", 1574 | "_view_name": "LayoutView", 1575 | "align_content": null, 1576 | "align_items": null, 1577 | "align_self": null, 1578 | "border": null, 1579 | "bottom": null, 1580 | "display": null, 1581 | "flex": null, 1582 | "flex_flow": null, 1583 | "grid_area": null, 1584 | "grid_auto_columns": null, 1585 | "grid_auto_flow": null, 1586 | "grid_auto_rows": null, 1587 | "grid_column": null, 1588 | "grid_gap": null, 1589 | "grid_row": null, 1590 | "grid_template_areas": null, 1591 | "grid_template_columns": null, 1592 | "grid_template_rows": null, 1593 | "height": null, 1594 | "justify_content": null, 1595 | "justify_items": null, 1596 | "left": null, 1597 | "margin": null, 1598 | "max_height": null, 1599 | "max_width": null, 1600 | "min_height": null, 1601 | "min_width": null, 1602 | "object_fit": null, 1603 | "object_position": null, 1604 | "order": null, 1605 | "overflow": null, 1606 | "overflow_x": null, 1607 | "overflow_y": null, 1608 | "padding": null, 1609 | "right": null, 1610 | "top": null, 1611 | "visibility": null, 1612 | "width": null 1613 | } 1614 | }, 1615 | "8ba589bd271e4f27b220b351aa224822": { 1616 | "model_module": "@jupyter-widgets/controls", 1617 | "model_module_version": "1.5.0", 1618 | "model_name": "HTMLModel", 1619 | "state": { 1620 | "_dom_classes": [], 1621 | "_model_module": "@jupyter-widgets/controls", 1622 | "_model_module_version": "1.5.0", 1623 | "_model_name": "HTMLModel", 1624 | "_view_count": null, 1625 | "_view_module": "@jupyter-widgets/controls", 1626 | "_view_module_version": "1.5.0", 1627 | "_view_name": "HTMLView", 1628 | "description": "", 1629 | "description_tooltip": null, 1630 | "layout": "IPY_MODEL_43177202ba5248319babbe9cb59172ad", 1631 | "placeholder": "​", 1632 | "style": "IPY_MODEL_0a9920a4fda541978d7437d084841ce4", 1633 | "value": "100%" 1634 | } 1635 | }, 1636 | "8c59aa2e9a394c5980fdd8d6c018e14d": { 1637 | "model_module": "@jupyter-widgets/base", 1638 | "model_module_version": "1.2.0", 1639 | "model_name": "LayoutModel", 1640 | "state": { 1641 | "_model_module": "@jupyter-widgets/base", 1642 | "_model_module_version": "1.2.0", 1643 | "_model_name": "LayoutModel", 1644 | "_view_count": null, 1645 | "_view_module": "@jupyter-widgets/base", 1646 | "_view_module_version": "1.2.0", 1647 | "_view_name": "LayoutView", 1648 | "align_content": null, 1649 | "align_items": null, 1650 | "align_self": null, 1651 | "border": null, 1652 | "bottom": null, 1653 | "display": null, 1654 | "flex": null, 1655 | "flex_flow": null, 1656 | "grid_area": null, 1657 | "grid_auto_columns": null, 1658 | "grid_auto_flow": null, 1659 | "grid_auto_rows": null, 1660 | "grid_column": null, 1661 | "grid_gap": null, 1662 | "grid_row": null, 1663 | "grid_template_areas": null, 1664 | "grid_template_columns": null, 1665 | "grid_template_rows": null, 1666 | "height": null, 1667 | "justify_content": null, 1668 | "justify_items": null, 1669 | "left": null, 1670 | "margin": null, 1671 | "max_height": null, 1672 | "max_width": null, 1673 | "min_height": null, 1674 | "min_width": null, 1675 | "object_fit": null, 1676 | "object_position": null, 1677 | "order": null, 1678 | "overflow": null, 1679 | "overflow_x": null, 1680 | "overflow_y": null, 1681 | "padding": null, 1682 | "right": null, 1683 | "top": null, 1684 | "visibility": null, 1685 | "width": null 1686 | } 1687 | }, 1688 | "93ce3bbaaf644b539728d267499963af": { 1689 | "model_module": "@jupyter-widgets/base", 1690 | "model_module_version": "1.2.0", 1691 | "model_name": "LayoutModel", 1692 | "state": { 1693 | "_model_module": "@jupyter-widgets/base", 1694 | "_model_module_version": "1.2.0", 1695 | "_model_name": "LayoutModel", 1696 | "_view_count": null, 1697 | "_view_module": "@jupyter-widgets/base", 1698 | "_view_module_version": "1.2.0", 1699 | "_view_name": "LayoutView", 1700 | "align_content": null, 1701 | "align_items": null, 1702 | "align_self": null, 1703 | "border": null, 1704 | "bottom": null, 1705 | "display": null, 1706 | "flex": null, 1707 | "flex_flow": null, 1708 | "grid_area": null, 1709 | "grid_auto_columns": null, 1710 | "grid_auto_flow": null, 1711 | "grid_auto_rows": null, 1712 | "grid_column": null, 1713 | "grid_gap": null, 1714 | "grid_row": null, 1715 | "grid_template_areas": null, 1716 | "grid_template_columns": null, 1717 | "grid_template_rows": null, 1718 | "height": null, 1719 | "justify_content": null, 1720 | "justify_items": null, 1721 | "left": null, 1722 | "margin": null, 1723 | "max_height": null, 1724 | "max_width": null, 1725 | "min_height": null, 1726 | "min_width": null, 1727 | "object_fit": null, 1728 | "object_position": null, 1729 | "order": null, 1730 | "overflow": null, 1731 | "overflow_x": null, 1732 | "overflow_y": null, 1733 | "padding": null, 1734 | "right": null, 1735 | "top": null, 1736 | "visibility": null, 1737 | "width": null 1738 | } 1739 | }, 1740 | "b428f0a7ed98414a8e2056458fd24810": { 1741 | "model_module": "@jupyter-widgets/controls", 1742 | "model_module_version": "1.5.0", 1743 | "model_name": "HTMLModel", 1744 | "state": { 1745 | "_dom_classes": [], 1746 | "_model_module": "@jupyter-widgets/controls", 1747 | "_model_module_version": "1.5.0", 1748 | "_model_name": "HTMLModel", 1749 | "_view_count": null, 1750 | "_view_module": "@jupyter-widgets/controls", 1751 | "_view_module_version": "1.5.0", 1752 | "_view_name": "HTMLView", 1753 | "description": "", 1754 | "description_tooltip": null, 1755 | "layout": "IPY_MODEL_5ff4b7fabddf45af8be5e5dd2228e888", 1756 | "placeholder": "​", 1757 | "style": "IPY_MODEL_140d7c568911441897951cf6f24c2f34", 1758 | "value": "100%" 1759 | } 1760 | }, 1761 | "b5955acf28aa4d17817e91d0c375ca5b": { 1762 | "model_module": "@jupyter-widgets/controls", 1763 | "model_module_version": "1.5.0", 1764 | "model_name": "DescriptionStyleModel", 1765 | "state": { 1766 | "_model_module": "@jupyter-widgets/controls", 1767 | "_model_module_version": "1.5.0", 1768 | "_model_name": "DescriptionStyleModel", 1769 | "_view_count": null, 1770 | "_view_module": "@jupyter-widgets/base", 1771 | "_view_module_version": "1.2.0", 1772 | "_view_name": "StyleView", 1773 | "description_width": "" 1774 | } 1775 | }, 1776 | "b9113e42d57a4133a952f6add9cf5e0c": { 1777 | "model_module": "@jupyter-widgets/controls", 1778 | "model_module_version": "1.5.0", 1779 | "model_name": "HBoxModel", 1780 | "state": { 1781 | "_dom_classes": [], 1782 | "_model_module": "@jupyter-widgets/controls", 1783 | "_model_module_version": "1.5.0", 1784 | "_model_name": "HBoxModel", 1785 | "_view_count": null, 1786 | "_view_module": "@jupyter-widgets/controls", 1787 | "_view_module_version": "1.5.0", 1788 | "_view_name": "HBoxView", 1789 | "box_style": "", 1790 | "children": [ 1791 | "IPY_MODEL_8ba589bd271e4f27b220b351aa224822", 1792 | "IPY_MODEL_d77b3913be7042a2a106217562b25f02", 1793 | "IPY_MODEL_c8b257087c294218a2b98e977ebf0510" 1794 | ], 1795 | "layout": "IPY_MODEL_f154739aa0224993a4882a360137735a" 1796 | } 1797 | }, 1798 | "c2a92fb28dee42298509ef573f7cf8ce": { 1799 | "model_module": "@jupyter-widgets/controls", 1800 | "model_module_version": "1.5.0", 1801 | "model_name": "HTMLModel", 1802 | "state": { 1803 | "_dom_classes": [], 1804 | "_model_module": "@jupyter-widgets/controls", 1805 | "_model_module_version": "1.5.0", 1806 | "_model_name": "HTMLModel", 1807 | "_view_count": null, 1808 | "_view_module": "@jupyter-widgets/controls", 1809 | "_view_module_version": "1.5.0", 1810 | "_view_name": "HTMLView", 1811 | "description": "", 1812 | "description_tooltip": null, 1813 | "layout": "IPY_MODEL_93ce3bbaaf644b539728d267499963af", 1814 | "placeholder": "​", 1815 | "style": "IPY_MODEL_8334c219e72f46a6a9029b508821c27e", 1816 | "value": " 109M/109M [00:11<00:00, 9.53MB/s]" 1817 | } 1818 | }, 1819 | "c5b0f3ac08d14f8ab5c7d73590bcfa99": { 1820 | "model_module": "@jupyter-widgets/base", 1821 | "model_module_version": "1.2.0", 1822 | "model_name": "LayoutModel", 1823 | "state": { 1824 | "_model_module": "@jupyter-widgets/base", 1825 | "_model_module_version": "1.2.0", 1826 | "_model_name": "LayoutModel", 1827 | "_view_count": null, 1828 | "_view_module": "@jupyter-widgets/base", 1829 | "_view_module_version": "1.2.0", 1830 | "_view_name": "LayoutView", 1831 | "align_content": null, 1832 | "align_items": null, 1833 | "align_self": null, 1834 | "border": null, 1835 | "bottom": null, 1836 | "display": null, 1837 | "flex": null, 1838 | "flex_flow": null, 1839 | "grid_area": null, 1840 | "grid_auto_columns": null, 1841 | "grid_auto_flow": null, 1842 | "grid_auto_rows": null, 1843 | "grid_column": null, 1844 | "grid_gap": null, 1845 | "grid_row": null, 1846 | "grid_template_areas": null, 1847 | "grid_template_columns": null, 1848 | "grid_template_rows": null, 1849 | "height": null, 1850 | "justify_content": null, 1851 | "justify_items": null, 1852 | "left": null, 1853 | "margin": null, 1854 | "max_height": null, 1855 | "max_width": null, 1856 | "min_height": null, 1857 | "min_width": null, 1858 | "object_fit": null, 1859 | "object_position": null, 1860 | "order": null, 1861 | "overflow": null, 1862 | "overflow_x": null, 1863 | "overflow_y": null, 1864 | "padding": null, 1865 | "right": null, 1866 | "top": null, 1867 | "visibility": null, 1868 | "width": null 1869 | } 1870 | }, 1871 | "c8b257087c294218a2b98e977ebf0510": { 1872 | "model_module": "@jupyter-widgets/controls", 1873 | "model_module_version": "1.5.0", 1874 | "model_name": "HTMLModel", 1875 | "state": { 1876 | "_dom_classes": [], 1877 | "_model_module": "@jupyter-widgets/controls", 1878 | "_model_module_version": "1.5.0", 1879 | "_model_name": "HTMLModel", 1880 | "_view_count": null, 1881 | "_view_module": "@jupyter-widgets/controls", 1882 | "_view_module_version": "1.5.0", 1883 | "_view_name": "HTMLView", 1884 | "description": "", 1885 | "description_tooltip": null, 1886 | "layout": "IPY_MODEL_c5b0f3ac08d14f8ab5c7d73590bcfa99", 1887 | "placeholder": "​", 1888 | "style": "IPY_MODEL_b5955acf28aa4d17817e91d0c375ca5b", 1889 | "value": " 219M/219M [00:18<00:00, 8.51MB/s]" 1890 | } 1891 | }, 1892 | "d77b3913be7042a2a106217562b25f02": { 1893 | "model_module": "@jupyter-widgets/controls", 1894 | "model_module_version": "1.5.0", 1895 | "model_name": "FloatProgressModel", 1896 | "state": { 1897 | "_dom_classes": [], 1898 | "_model_module": "@jupyter-widgets/controls", 1899 | "_model_module_version": "1.5.0", 1900 | "_model_name": "FloatProgressModel", 1901 | "_view_count": null, 1902 | "_view_module": "@jupyter-widgets/controls", 1903 | "_view_module_version": "1.5.0", 1904 | "_view_name": "ProgressView", 1905 | "bar_style": "success", 1906 | "description": "", 1907 | "description_tooltip": null, 1908 | "layout": "IPY_MODEL_8179c511bdb24e04b5f5cf8ed62d3f6d", 1909 | "max": 229956710, 1910 | "min": 0, 1911 | "orientation": "horizontal", 1912 | "style": "IPY_MODEL_13687fe7ef8044c2864934379f45735f", 1913 | "value": 229956710 1914 | } 1915 | }, 1916 | "f154739aa0224993a4882a360137735a": { 1917 | "model_module": "@jupyter-widgets/base", 1918 | "model_module_version": "1.2.0", 1919 | "model_name": "LayoutModel", 1920 | "state": { 1921 | "_model_module": "@jupyter-widgets/base", 1922 | "_model_module_version": "1.2.0", 1923 | "_model_name": "LayoutModel", 1924 | "_view_count": null, 1925 | "_view_module": "@jupyter-widgets/base", 1926 | "_view_module_version": "1.2.0", 1927 | "_view_name": "LayoutView", 1928 | "align_content": null, 1929 | "align_items": null, 1930 | "align_self": null, 1931 | "border": null, 1932 | "bottom": null, 1933 | "display": null, 1934 | "flex": null, 1935 | "flex_flow": null, 1936 | "grid_area": null, 1937 | "grid_auto_columns": null, 1938 | "grid_auto_flow": null, 1939 | "grid_auto_rows": null, 1940 | "grid_column": null, 1941 | "grid_gap": null, 1942 | "grid_row": null, 1943 | "grid_template_areas": null, 1944 | "grid_template_columns": null, 1945 | "grid_template_rows": null, 1946 | "height": null, 1947 | "justify_content": null, 1948 | "justify_items": null, 1949 | "left": null, 1950 | "margin": null, 1951 | "max_height": null, 1952 | "max_width": null, 1953 | "min_height": null, 1954 | "min_width": null, 1955 | "object_fit": null, 1956 | "object_position": null, 1957 | "order": null, 1958 | "overflow": null, 1959 | "overflow_x": null, 1960 | "overflow_y": null, 1961 | "padding": null, 1962 | "right": null, 1963 | "top": null, 1964 | "visibility": null, 1965 | "width": null 1966 | } 1967 | } 1968 | } 1969 | } 1970 | }, 1971 | "nbformat": 4, 1972 | "nbformat_minor": 1 1973 | } 1974 | -------------------------------------------------------------------------------- /main_driver/model_Inverted: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneeshbhattacharya/Automated-PnID-Symbol-Detection-and-Labelling/dc56e2dc43630c74ae7350286e95c248595b5e96/main_driver/model_Inverted -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | certifi==2022.6.15 2 | charset-normalizer==2.1.0 3 | cycler==0.11.0 4 | fonttools==4.33.3 5 | idna==3.3 6 | imageio==2.19.3 7 | kiwisolver==1.4.3 8 | matplotlib==3.5.2 9 | networkx==2.6.3 10 | numpy==1.21.6 11 | opencv-contrib-python 12 | opencv-python==4.6.0.66 13 | packaging==21.3 14 | pandas==1.3.5 15 | Pillow==9.2.0 16 | pip==21.2.2 17 | pyparsing==3.0.9 18 | python-dateutil==2.8.2 19 | pytz==2022.1 20 | PyWavelets==1.3.0 21 | requests==2.28.1 22 | scikit-image==0.19.3 23 | scipy==1.7.3 24 | setuptools==61.2.0 25 | six==1.16.0 26 | tifffile==2021.11.2 27 | torch==1.12.0 28 | torchvision==0.13.0 29 | tqdm==4.64.0 30 | typing_extensions==4.3.0 31 | urllib3==1.26.9 32 | wheel==0.37.1 33 | openpyxl 34 | --------------------------------------------------------------------------------