├── 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 |
5 | - Take a raw P&ID diagram sheet as input
6 | - Output the following:
7 |
8 | - A JPG image with bounding boxes drawn around each detected symbol with their object ID
9 | - A PDF file containing the object ID, class ID, Component Name, Item Label and bounding box regions
10 |
11 |
12 |
13 |
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 | - Custom object detection step:
22 |
23 | - We traverse the entire P&ID sheet and process crops of size 150 x 150. (50% overlap of crops is considered).
24 | - Our custom trained model provides 6 symbol classes 1 background class as inference.
25 | - We reject background classes and save only the regions which contain the symbols.
26 | - Several overlapping bounding boxes are detected, which are processed to provide a single bounding box and inference.
27 |
28 |
29 |
30 | - OCR and text processing step:
31 |
32 | - The regions containing symbols are passed through EAST text detection model (pretrained) to determine the orientation of the text i.e vertical or horizontal.
33 | - The vertical text is roatated 90° right and brought into a horizontal format.
34 | - The processed text regions are cropped and passes through the MMOCR mode (pretrained) for performing OCR.
35 | - Rubbish inferences are rejected and replaced with defaut values.
36 |
37 |
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 |
68 | - Invert the images to create greyscale and normalized images (symbols are active pixels) and create a dataset (use invert function from Aneesh_Risav_P&ID_Detection_and_Labelling_System.ipynb)
69 | - 2. Save different images of different classes as follows:
70 | |--main folder
71 | |----0 <- this is class ID
72 | |------1.jpg
73 | |------2.jpg
74 | |------3.jpg
75 | |------...
76 | |----1
77 | |------1.jpg
78 | |------2.jpg
79 | |------3.jpg
80 | |------...
81 | |----.
82 | |----.
83 | |----n <- For upto N classes
84 |
85 |
86 |
87 | - Place this folder with name 'dataset' in the same directory as FINAL_Inverted_PyTorch_Model_P&ID.ipynb
88 | - Set the number of classes output required by the model as "n" (last softmax layer of model)
89 | - Run FINAL_Inverted_PyTorch_Model_P&ID.ipynb
90 |
91 |
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 |
--------------------------------------------------------------------------------