Loading

AI Blitz XIII

Face Mask Detection using Detecto Pytorch 98.1 AP

BBox and Classification of Face mask Ai-Blitz-xiii

hemanth_kollipara

Face Mask Segmentation BBox using Object Detection

!pip install detecto==1.1.6

Offical Documentation : https://detecto.readthedocs.io/en/latest/index.html

In [2]:
!pip install detecto==1.1.6
In [3]:
import os
import time
import ast
import random
import shutil
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from tqdm.notebook import tqdm
from IPython.display import clear_output

import cv2
import sklearn
from detecto import core, utils
from torchvision import transforms
from detecto.visualize import show_labeled_image
from detecto.utils import read_image
In [ ]:
print(os.mkdir('train'))
In [ ]:
base="../input/face-mask-bbox/train/"
for iname in tqdm(os.listdir(base)):
    src = base+iname
    dst = "./train/"+iname
    shutil.copy(src, dst)

Annotation processing

Importing annotations from CSV

In [4]:
train_df = pd.read_csv("../input/face-mask-bbox/train.csv")
val_df = pd.read_csv("../input/face-mask-bbox/val.csv")

print(train_df)
print()
print(val_df)
     ImageID                  bbox  masktype
0      k8o0f   [73, 197, 293, 400]       N95
1      7a0l9   [47, 364, 300, 512]  surgical
2      wfp7p  [203, 221, 380, 403]       N95
3      7qaw6   [87, 210, 322, 385]  surgical
4      i4kqj  [227, 283, 479, 475]  surgical
...      ...                   ...       ...
5595   xxjeg    [0, 374, 247, 512]      KN95
5596   04ira  [112, 325, 373, 512]  surgical
5597   3owm2   [53, 212, 238, 398]       N95
5598   wy2og  [259, 227, 445, 476]       N95
5599   xoco2  [240, 271, 499, 488]  surgical

[5600 rows x 3 columns]

     ImageID                  bbox  masktype
0      4fbch  [142, 157, 406, 364]  surgical
1      qzg77   [30, 341, 229, 512]       N95
2      xmssj   [226, 90, 510, 376]      KN95
3      y573q  [158, 324, 408, 512]  surgical
4      97v85   [26, 201, 243, 396]  surgical
...      ...                   ...       ...
2395   889mv    [9, 352, 291, 512]      KN95
2396   h7qgp   [86, 172, 366, 357]     cloth
2397   96t1r  [101, 313, 352, 483]     cloth
2398   h1soy  [137, 171, 438, 384]     cloth
2399   jr5qx  [155, 297, 407, 472]  surgical

[2400 rows x 3 columns]
In [ ]:
base = "../input/face-mask-bbox/val/"
for iname in tqdm(val_df['ImageID']):
    src = base+iname+".jpg"
    dst = "./train/"+iname+".jpg"
    shutil.copy(src, dst)
In [ ]:
train_df = train_df.append(val_df[:-10])
val_df = val_df[2000:]

print(train_df)
print()
print(val_df)
In [5]:
def df2labels(df):
    labels_lst = []
    for idx in range(len(df)):
        row = list(df.iloc[idx])
        fname = row[0]+".jpg"
        wd=512
        ht=512
        cl=row[2]
        bbox=ast.literal_eval(row[1])
        xmin,ymin, xmax,ymax = bbox[0],bbox[1], bbox[2],bbox[3]
        label=[fname,wd,ht,cl,xmin,ymin,xmax,ymax]
        labels_lst.append(label)

    labels_df = pd.DataFrame(labels_lst)
    labels_df.columns = ["filename","width","height","class","xmin","ymin","xmax","ymax"]
    return labels_df
In [6]:
train_labels = df2labels(train_df)
val_labels = df2labels(val_df)

print(train_labels.head(), "\n")
print(val_labels.head())
    filename  width  height     class  xmin  ymin  xmax  ymax
0  k8o0f.jpg    512     512       N95    73   197   293   400
1  7a0l9.jpg    512     512  surgical    47   364   300   512
2  wfp7p.jpg    512     512       N95   203   221   380   403
3  7qaw6.jpg    512     512  surgical    87   210   322   385
4  i4kqj.jpg    512     512  surgical   227   283   479   475 

    filename  width  height     class  xmin  ymin  xmax  ymax
0  4fbch.jpg    512     512  surgical   142   157   406   364
1  qzg77.jpg    512     512       N95    30   341   229   512
2  xmssj.jpg    512     512      KN95   226    90   510   376
3  y573q.jpg    512     512  surgical   158   324   408   512
4  97v85.jpg    512     512  surgical    26   201   243   396
In [7]:
classes = list(set(train_labels['class']))
print(classes)

sns.countplot(x=train_labels['class'])
plt.show()
['N95', 'cloth', 'KN95', 'surgical']

Verifying Labels

In [ ]:
train_images_path = "./train"
val_images_path = "../input/face-mask-bbox/val/"

def verify_labels(images_path,input_labels):
    df=input_labels
    drop_lst=[]
    for i in tqdm(range(len(df))):
        try:
            imgname=df['filename'].iloc[i]
            fname=images_path+"/"+imgname
            img=cv2.imread(fname)
            if len(img)<1:
                pass
        except Exception as e:
            print("Error", e)
            drop_lst.append(imgname)
            print("Error File : ", fname)
            continue
            
    if len(drop_lst)==0:
        print("\nLabels verified - None dropped")
    else:
        print("\nDiscrepancies Found -",len(drop_lst))
        print(drop_lst)
        for fname in drop_lst:
            df=df.drop(df[df['filename']==fname].index)
        print("Labels dropped :", len(drop_lst),"\n")
        
    return df


train_df=verify_labels(train_images_path,train_labels)
val_df=verify_labels(val_images_path,val_labels)
In [ ]:
# !nvidia-smi

Train-Test Split

In [8]:
#from sklearn.model_selection import train_test_split

#train_labels, valid_labels = train_test_split(labels_df, test_size=0.15, random_state=42)
train_labels.to_csv("train_labels.csv", index=False)
val_labels.to_csv("val_labels.csv", index=False)

Transforms

In [9]:
custom_transforms = transforms.Compose([
    transforms.ToPILImage(),
    transforms.Resize(324),
    transforms.RandomHorizontalFlip(),
    transforms.ColorJitter(saturation=0.2),
    transforms.ToTensor(),
    utils.normalize_transform(),
])
In [11]:
train_images_path = "../input/face-mask-bbox/train"
val_images_path = "../input/face-mask-bbox/val/"

print("Train Images Count :", len(os.listdir(train_images_path)))
print("Val Images Count   :", len(os.listdir(val_images_path)))
Train Images Count : 5600
Val Images Count   : 2400

Training Dataset Prep

In [12]:
from detecto.core import Model, Dataset, DataLoader


train_dataset = Dataset(label_data='train_labels.csv',
                         image_folder=train_images_path,
                         transform=custom_transforms)

valid_dataset = Dataset(label_data='val_labels.csv',
                         image_folder=val_images_path,
                         transform=custom_transforms)
In [14]:
samples_count=1

for _ in range(samples_count):    
    rand_idx = random.randint(0, len(train_dataset)-1)
    image, targets = train_dataset[rand_idx]
    print(rand_idx, targets)
    show_labeled_image(image, targets['boxes'], targets['labels'])
    
    time.sleep(1)
    clear_output(wait=True)
3453 {'boxes': tensor([[  0,  69, 190, 241]]), 'labels': 'KN95'}

Model Training

In [ ]:
batch_size = 16

train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
valid_loader = DataLoader(valid_dataset, batch_size=batch_size, shuffle=False)
In [ ]:
# loading model
#model_save_path='/home/advenio/Desktop/Hemanth/OD_segmentation/'
#model=Model.load(model_save_path+"OD_seg_pool_v1.pth",['od'])

# creating new model
model = core.Model(classes)

model.fit(dataset=train_loader,
                   val_dataset=valid_loader,
                   epochs=7,
                   learning_rate=0.0003,
                   verbose=True)
In [ ]:
losses = model.fit(dataset=train_loader,
          val_dataset=valid_loader,
          epochs=6,
          learning_rate=0.0001,
          verbose=True)

Inference

In [15]:
test_df = pd.read_csv("../input/face-mask-bbox/test.csv")
test_df.head()
Out[15]:
ImageID bbox masktype
0 os9el [0, 0, 0, 0] NaN
1 gksn6 [0, 0, 0, 0] NaN
2 odcws [0, 0, 0, 0] NaN
3 04qsi [0, 0, 0, 0] NaN
4 6canb [0, 0, 0, 0] NaN
In [ ]:
test_images_path = "../input/face-mask-bbox/test/"

for idx in tqdm(range(len(test_df))):
    try:
        iname = test_df.iloc[idx, 0]+".jpg"
        fname = test_images_path+iname
        image = utils.read_image(fname)
        mask_prediction = model.predict(image)
        label = mask_prediction[0][0]
        bbox = str(list(map(int, mask_prediction[1][0])))
        test_df.iloc[idx, 1]=bbox
        test_df.iloc[idx, 2]=label
    except:
        test_df.iloc[idx, 1]=bbox
        test_df.iloc[idx, 2]=label
        continue
    
    
test_df.head()
In [ ]:
test_df.to_csv("submission2.csv", index=False)
In [ ]:


Comments

You must login before you can post a comment.

Execute