{"cells":[{"metadata":{},"cell_type":"markdown","source":"# VinBigData Chest X-ray Abnormalities Detection usig YOLO5"},{"metadata":{},"cell_type":"markdown","source":"![](https://www.verywellhealth.com/thmb/eUG48c__vQ0Se3So4-msAHwoqB8=/1500x0/filters:no_upscale():max_bytes(150000):strip_icc():format(webp)/iStock_22401848_MEDIUM-58262cb63df78c6f6adebb27.jpg)","attachments":{}},{"metadata":{},"cell_type":"markdown","source":"Helpful kernel:\n* [https://www.kaggle.com/sreevishnudamodaran/vinbigdata-fusing-bboxes-coco-dataset](http://)\n* [https://www.kaggle.com/raddar/vinbigdata-competition-jpg-data-3x-downsampled](http://)"},{"metadata":{},"cell_type":"markdown","source":"The Github repo \nhttps://github.com/ZFTurbo/Weighted-Boxes-Fusion[](http://)"},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install ensemble-boxes","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport pydicom\nimport cv2\nimport os\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut\nimport matplotlib.pyplot as plt\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_img_list = os.listdir('/kaggle/input/vinbigdata-chest-xray-abnormalities-detection/train/')\ntest_img_list  = os.listdir('/kaggle/input/vinbigdata-chest-xray-abnormalities-detection/test/')\n\ntest_dir='/kaggle/input/vinbigdata-chest-xray-abnormalities-detection/test/'\ntrain_dir='/kaggle/input/vinbigdata-chest-xray-abnormalities-detection/train/'\ntrain_df=pd.read_csv('/kaggle/input/vinbigdata-chest-xray-abnormalities-detection/train.csv')\nsample_submission_df=pd.read_csv('/kaggle/input/vinbigdata-chest-xray-abnormalities-detection/sample_submission.csv')\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"number of images in the trainig dataset = \",len(set(train_df['image_id'])))\nimages_ids=list(set(train_df['image_id']))\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"number of images in the test dataset = \",len(set(sample_submission_df['image_id'])))\ntest_images_ids=list(set(sample_submission_df['image_id']))\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_annotated_df=train_df[(train_df.class_name !='No finding')]\nimages_id_with_annotations=set(train_annotated_df['image_id'])\nprint(\"The number of images with annotations = \",len(images_id_with_annotations))\nprint(\"The number of annotations in the training dataset = \",len(train_annotated_df))\nprint(\"the average annotations per image = \",len(train_annotated_df)/len(images_id_with_annotations))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\nimage_id_to_annotation_num_dict={}\nfor i,image_id in enumerate(set(train_annotated_df['image_id'])):\n    annotation_num=len(train_annotated_df[(train_df.image_id==image_id)])\n    image_id_to_annotation_num_dict[image_id] = annotation_num\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\nimport seaborn as sns\n\nlens = list(image_id_to_annotation_num_dict.values())\n\nplt.figure(figsize=(15,6))\nsns.countplot(lens);\nplt.xlabel('Number of Bounding Boxes in Images');","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import cv2\n\n\nlabels =  [\n            \"Aortic_enlargement\",\n            \"Atelectasis\",\n            \"Calcification\",\n            \"Cardiomegaly\",\n            \"Consolidation\",\n            \"ILD\",\n            \"Infiltration\",\n            \"Lung_Opacity\",\n            \"Nodule/Mass\",\n            \"Other_lesion\",\n            \"Pleural_effusion\",\n            \"Pleural_thickening\",\n            \"Pneumothorax\",\n            \"Pulmonary_fibrosis\"\n            ]\n\nlabel2color = [[59 ,238,119], [222,21 ,229], [94 , 49,164], \n               [206,221,133], [117, 75, 3 ], [210,224,119],\n               [211,176,166], [63 , 7 ,197], [102, 65, 77],\n               [194,134,175], [209,219,50 ], [255, 44, 47], \n               [89 ,125,149], [110,27 ,100]]\nthickness=5\n\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\nfrom ensemble_boxes import *\nfrom collections import Counter\n\niou_thr = 0.5\nskip_box_thr = 0.0001\nsigma = 0.1\n###############################################################################################\n'''\nFunction name :read_xray\n\nInputs:\n       path:path to the dicom file(xray file)\n       voi_lut ,\n       fix_monochrome,\n       downscale_factor : the factor to downscale the xray image \n\nOutput: numpy array of the xray image after preprocessing and downscaling\n\nResponsibility:\n     -reads dicom file (xray file) \n     -transforms it to numpy array image \n     -make some preprocessing\n     -downscale the image\n'''\ndef read_xray(path, voi_lut = True, fix_monochrome = True, downscale_factor = 3):\n    dicom = pydicom.read_file(path)\n\n    # VOI LUT (if available by DICOM device) is used to transform raw DICOM data to \"human-friendly\" view\n    if voi_lut:\n        data = apply_voi_lut(dicom.pixel_array, dicom)\n    else:\n        data = dicom.pixel_array\n\n    # depending on this value, X-ray may look inverted - fix that:\n    if fix_monochrome and dicom.PhotometricInterpretation == \"MONOCHROME1\":\n        data = np.amax(data) - data\n\n    data = data - np.min(data)\n    data = data / np.max(data)\n    data = (data * 255.0).astype(np.uint8)\n    new_shape = tuple([int(x / downscale_factor) for x in data.shape])\n    data = cv2.resize(data, (new_shape[1], new_shape[0]))\n\n    return data\n###############################################################################################\n'''\nFunction name :draw_bbox\n\nInputs:\n       img: image array \n       bbox: [xmin,ymin,xmax,ymax] ,\n       color: [r,g,b] for the bounding box color,\n       class_name : the class name of the bounding box \n\nOutput: the image after drawing the bounding box\n\nResponsibility: draw bounding box \n     \n'''\n\ndef draw_bbox(img,bbox,color,class_name):\n    #print(bbox)\n    cv2.rectangle(img,(int(bbox[0]), int(bbox[1])), (int(bbox[2]),int(bbox[3])),color, thickness)\n    cv2.putText(img, class_name, (int(bbox[0]),int(bbox[1])-10),cv2.FONT_HERSHEY_SIMPLEX, 1.5, color,thickness=3)\n    \n    return img\n    \n###############################################################################################\n'''\nFunction name :bounding_box_filtering\n\nInputs:\n       train_annotated_df: the dataframe of the annotated images  \n       image_basename:  ,\n       filtering_function: the filtering function options: \n                                     Non-maximum Suppression (NMS)\n                                     Soft-NMS\n                                     Non-maximum weighted (NMW) \n                                     Weighted boxes fusion (WBF)\n       \n       downscale_factor : the downscale factor of image\n\nOutput: img_before : image with bounding boxes before filtering  ,\n        img_afterimage :image with bounding boxes after filtering\n        \nResponsibility: Bounding box filtering\n     \n'''\ndef bounding_box_filtering(train_annotated_df,image_basename,filtering_function,downscale_factor):\n\n    img_path=train_dir+image_basename+'.dicom'\n    img=read_xray(img_path, voi_lut = True, fix_monochrome = True, downscale_factor = downscale_factor)\n    img=cv2.cvtColor(img,cv2.COLOR_GRAY2RGB)\n    img_annotations = train_annotated_df[train_annotated_df.image_id==image_basename]\n\n    boxes_viz = (img_annotations[['x_min', 'y_min', 'x_max', 'y_max']].to_numpy()/(1.0*downscale_factor)).tolist()\n    labels_viz = img_annotations['class_id'].to_numpy().tolist()\n    \n    \n    ## Visualize Original Bboxes\n    img_before = img.copy()\n    for box, label in zip(boxes_viz, labels_viz):\n        color = tuple(label2color[int(label)])\n        img_before = draw_bbox(img_before, box,color,labels[int(label)])\n    \n    boxes_list = []\n    scores_list = []\n    labels_list = []\n    weights = []\n    \n    boxes_single = []\n    labels_single = []\n    \n    cls_ids = img_annotations['class_id'].unique().tolist()\n    count_dict = Counter(img_annotations['class_id'].tolist())\n    #print(count_dict)\n\n    for cid in cls_ids:       \n        ## Performing Fusing operation only for multiple bboxes with the same label\n        if count_dict[cid]==1:\n            labels_single.append(cid)\n            single_box=img_annotations[img_annotations.class_id==cid][['x_min', 'y_min', 'x_max', 'y_max']].to_numpy()/(1.0*downscale_factor)\n            single_box=single_box.squeeze().tolist()\n            boxes_single.append(single_box)\n\n        else:\n            cls_list =img_annotations[img_annotations.class_id==cid]['class_id'].tolist()\n            labels_list.append(cls_list)\n            bbox = img_annotations[img_annotations.class_id==cid][['x_min', 'y_min', 'x_max', 'y_max']].to_numpy()/(1.0*downscale_factor)\n            ## Normalizing Bbox by Image Width and Height\n            bbox = bbox/(img.shape[1], img.shape[0], img.shape[1], img.shape[0])\n            bbox = np.clip(bbox, 0, 1)\n            boxes_list.append(bbox.tolist())\n            scores_list.append(np.ones(len(cls_list)).tolist())\n\n            weights.append(1)\n    #print(np.array(boxes_list).squeeze().shape)\n    #print(labels_list)\n    # Perform NMS\n    boxes, scores, box_labels = filtering_function(boxes_list, scores_list, labels_list, weights=weights,\n                                    iou_thr=iou_thr)\n    #print(box_labels)\n\n    boxes = boxes*(img.shape[1], img.shape[0], img.shape[1], img.shape[0])\n    boxes = boxes.round(1).tolist()\n    box_labels = box_labels.astype(int).tolist()\n\n    boxes.extend(boxes_single)\n    box_labels.extend(labels_single)\n        \n    ## Visualize Bboxes after operation\n    img_after = img.copy()\n    for box, label in zip(boxes, box_labels):\n        color = label2color[int(label)]\n        img_after = draw_bbox(img_after,box,color,labels[int(label)])\n    \n    return img_before,img_after \n\n###############################################################################################\n'''\nFunction name :read_image_bounding_boxes\n\nInputs:\n       image_path: the bath to the jpg image  \n       bounding_box_path: the path to the bounding box .txt in yolo format ,\n       \n\nOutput: img_array_before : the image before adding bounding boxes ,\n        img_array_after : the image after adding bounding boxes,\n        bboxs : bounding boxes ,\n        class_ids: the class id of the bounding boxes\n\n        \nResponsibility: read image and bounding boxes\n     \n'''\n\n\ndef read_image_bounding_boxes(image_path,bounding_box_path):\n    img_array  = cv2.imread(image_path)\n    file1 = open(bounding_box_path,\"r+\")\n    Lines = file1.readlines()\n    img_array_before=img_array.copy()\n\n    count = 0\n    # Strips the newline character\n    class_ids=[]\n    bboxs=[]\n    for line in Lines:\n        count += 1\n        #print(\"Line{}: {}\".format(count, line.strip()))\n        bbox=[]\n        for idx,dim in enumerate(line.strip().split()):\n            if idx==0:\n               class_ids.append(dim) \n            else:\n               bbox.append(float(dim))\n        bboxs.append(bbox)\n    bboxs=np.array(bboxs) \n\n    bboxs=bboxs*np.array((img_array.shape[1], img_array.shape[0], img_array.shape[1], img_array.shape[0]))\n    xmin=bboxs[:,0]-(bboxs[:,2])/2\n    xmax=bboxs[:,0]+(bboxs[:,2])/2\n    ymin=bboxs[:,1]-(bboxs[:,3])/2\n    ymax=bboxs[:,1]+(bboxs[:,3])/2\n    bboxs=np.stack((xmin,ymin,xmax,ymax),axis=0).T\n    \n    img_array_after=img_array.copy()\n\n    for label,box in zip(class_ids,bboxs.tolist()):\n        box=(np.array(box)).tolist()\n        color = label2color[int(label)]\n        img_array = draw_bbox(img_array_after,box,color,labels[int(label)])\n    \n    return img_array_before,img_array_after,bboxs,class_ids\n\n\n###############################################################################################\n'''\nFunction name :draw_bounding_box_of_image_using_image_id\n\nInputs:\n       train_annotated_df : the dataframe of the annotated images ,\n       image_id :the image id of the image,\n       base_dir: the directory of the image folder,\n       downscale_factor:\n       \n\nOutput: None\n        \nResponsibility: ploting image before and after adding bounding boxes\n     \n'''\n\ndef draw_bounding_box_of_image_using_image_id(train_annotated_df,image_id,base_dir,downscale_factor):\n    img_path=base_dir+image_id+'.dicom'\n    img=read_xray(img_path, voi_lut = True, fix_monochrome = True, downscale_factor = downscale_factor)\n    img=cv2.cvtColor(img,cv2.COLOR_GRAY2RGB)\n    img_=img.copy()\n    df=train_annotated_df[(train_annotated_df.image_id==image_id)]\n\n    for i in range(len(df)) :\n\n        x_min = df.iloc[i].x_min/(1.0*downscale_factor)\n        y_min = df.iloc[i].y_min/(1.0*downscale_factor)\n        x_max = df.iloc[i].x_max/(1.0*downscale_factor)\n        y_max = df.iloc[i].y_max/(1.0*downscale_factor)\n        bbox=[x_min,y_min,x_max,y_max]\n        color=tuple(label2color[df.iloc[i].class_id])\n        class_name=df.iloc[i].class_name.upper()\n        draw_bbox(img_,bbox,color,class_name)\n    fig, axes = plt.subplots(1, 2, figsize=(20,20))\n    axes[0].imshow(img)    \n    axes[1].imshow(img_)\n    return img,img_","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"###############################################################################################\n'''\nFunction name : bbox_filtering\n\nInputs:\n       img : the image array ,\n       img_annotations : the data frame of the image which contians the bounding boxes info ,\n       filtering_function: the filtering function that filter bounding boxes\n                                options: \n                                     Non-maximum Suppression (NMS)\n                                     Soft-NMS\n                                     Non-maximum weighted (NMW) \n                                     Weighted boxes fusion (WBF) ,      \n       downscale_factor \n       \n\nOutput: boxes : bounding boxes,\n        box_labels : class_id of the bounding boxes\n        \nResponsibility: bounding box filtering\n     \n'''\ndef bbox_filtering(img,img_annotations,filtering_function,downscale_factor):\n    boxes_list = []\n    scores_list = []\n    labels_list = []\n    weights = []\n    \n    boxes_single = []\n    labels_single = []\n    \n    cls_ids = img_annotations['class_id'].unique().tolist()\n    count_dict = Counter(img_annotations['class_id'].tolist())\n\n    for cid in cls_ids:       \n        ## Performing Fusing operation only for multiple bboxes with the same label\n        if count_dict[cid]==1:\n            labels_single.append(cid)\n            \n            single_box=img_annotations[img_annotations.class_id==cid][['x_min', 'y_min', 'x_max', 'y_max']].to_numpy()/(1.0*downscale_factor)#.squeeze()\n            single_box=single_box.squeeze()\n            single_box = single_box/(img.shape[1], img.shape[0], img.shape[1], img.shape[0])\n            single_box = np.clip(single_box, 0, 1).tolist()\n            boxes_single.append(single_box)\n\n        else:\n            cls_list =img_annotations[img_annotations.class_id==cid]['class_id'].tolist()\n            labels_list.append(cls_list)\n            bbox = img_annotations[img_annotations.class_id==cid][['x_min', 'y_min', 'x_max', 'y_max']].to_numpy()/(1.0*downscale_factor)\n            ## Normalizing Bbox by Image Width and Height\n            bbox = bbox/(img.shape[1], img.shape[0], img.shape[1], img.shape[0])\n            bbox = np.clip(bbox, 0, 1)\n            boxes_list.append(bbox.tolist())\n            scores_list.append(np.ones(len(cls_list)).tolist())\n\n            weights.append(1)\n    # Perform NMS\n    #print(boxes_list)\n    if boxes_list != []:\n       boxes, scores, box_labels = filtering_function(boxes_list, scores_list, labels_list, weights=weights,\n                                    iou_thr=iou_thr)\n    #print(boxes)\n    if boxes_single != [] and boxes_list != []:\n       boxes=np.concatenate((boxes,np.array(boxes_single)),axis=0)\n       box_labels=np.concatenate((box_labels,np.array(labels_single)),axis=0) \n    elif boxes_single != [] and boxes_list ==[]:\n         boxes=np.array(boxes_single)\n         box_labels=np.array(labels_single)   \n    \n    \n\n    box_labels = box_labels.astype(int).tolist()\n    \n    return boxes,box_labels\n\n###############################################################################################\n'''\nFunction name : saving_image_and_filtered_bounding_boxes_in_yolo_format\n\nInputs:\n       train_annotated_df : the dataframe of annotated images,\n       image_basename : the image id , \n       downscale_factor : ,\n       filtering_function :,\n       path :    \n       \n\nOutput: boxes : ,\n        box_labels : \n        \nResponsibility: save the image and the bounding boxes in yolo format\n     \n'''\n\ndef saving_image_and_filtered_bounding_boxes_in_yolo_format(train_annotated_df,image_basename,downscale_factor,filtering_function,path):\n    path_list=path.split('/')\n    #image_basename=images_id_with_annotations[idx]\n    img_path=train_dir+image_basename+'.dicom'\n    img=read_xray(img_path, voi_lut = True, fix_monochrome = True, downscale_factor = downscale_factor)\n    img=cv2.cvtColor(img,cv2.COLOR_GRAY2RGB)\n    \n    cv2.imwrite(path_list[0]+'/images/'+path_list[2]+'/'+image_basename+'.jpg', img)\n    \n    img_annotations = train_annotated_df[train_annotated_df.image_id==image_basename]\n    \n    \n    \n    boxes,box_labels=bbox_filtering(img,img_annotations,filtering_function,downscale_factor) \n    \n    x=boxes[:,0]+(boxes[:,2]-boxes[:,0])/2\n    y=boxes[:,1]+(boxes[:,3]-boxes[:,1])/2\n    w=boxes[:,2]-boxes[:,0]\n    h=boxes[:,3]-boxes[:,1]\n    boxes=np.stack((x, y,w,h), axis=1)\n    \n    detected_objects=np.concatenate((np.expand_dims(box_labels, axis=1),boxes), axis=1)\n    \n    label_file = open(path_list[0]+'/labels/'+path_list[2]+'/'+image_basename+'.txt',\"w+\")\n    for detected_object in detected_objects.tolist() :\n        label_file.write(str(int(detected_object[0]))+' '+str(detected_object[1])+' '+str(detected_object[2])+' '+str(detected_object[3])+' '+str(detected_object[4]))\n        label_file.write('\\n')\n    label_file.close()\n    \n    return boxes,box_labels\n\n###############################################################################################\n'''\nFunction name : read_image\n\nInputs:\n       directory: the path of the dicom (xray image) ,\n       image_id: the image id ,\n       downscale_factor:   \n       \n\nOutput: image : the image in numpy array \n        \nResponsibility: read image in dicom and transforms it to numpy array\n     \n'''\n\ndef read_image(directory,image_id,downscale_factor):\n    path=directory+image_id+'.dicom'\n    image=read_xray(path, voi_lut = True, fix_monochrome = True, downscale_factor = downscale_factor)\n    image=cv2.cvtColor(image,cv2.COLOR_GRAY2RGB)\n    return image\n###############################################################################################\n'''\nFunction name : rescale_bounding_boxes\n\nInputs:\n       image : the origonal image,\n       image_scaled : the scaled image,\n       bboxes:  bounding boxes \n       \n\nOutput: image : the image in numpy array after adding bounding boxes after rescaling the bounding boxes\n        \nResponsibility: read image in dicom and transforms it to numpy array\n     \n'''\n\ndef rescale_bounding_boxes(image,image_scaled,bboxes):\n    bboxes=bboxes*round(image.shape[0]/image_scaled.shape[0])\n\n    for label,box in zip(class_ids,bboxes.tolist()):\n        box=(np.array(box)).tolist()\n        color = label2color[int(label)]\n        image = draw_bbox(image,box,color,labels[int(label)])\n    return image \n\n'''\nFunction name : Reformat_the_prediction\n\nInputs:\n       test_images_path : the path to the test images ,\n       labels_path : the path to the test labels,\n       image_id : the image id ,\n       visualize : True or false  \n       \n\nOutput: image : the bounding boxes after reformating [class_id,confidence_score,xmin,ymin,xmax,ymax]\n        \nResponsibility: Reformating and visualizing the bounding boxes\n     \n'''\n\n\ndef Reformat_the_prediction(test_images_path,labels_path,image_id,visualize=False):\n    downscale_factor=1\n    image=read_image(test_dir,image_id,downscale_factor)\n\n    image_labels=[]\n    with open(test_labels_dir+image_id+'.txt') as fp:\n\n    #with open(test_labels_dir+test_list[100]) as fp:\n       line = fp.readline()\n       cnt = 1\n       while line:\n           labels_=[] \n           for i,item in enumerate(line.strip().split()) :\n               if i==0:\n                  labels_.append(int(item))\n               else:\n                  labels_.append(float(item))\n           image_labels.append(labels_)     \n           line = fp.readline()\n           cnt += 1    \n\n    image_labels=np.array(image_labels)\n    bboxs= image_labels[:,1:-1]   \n    bboxs=np.array(bboxs) \n\n    bboxs=bboxs*np.array((image.shape[1], image.shape[0], image.shape[1], image.shape[0]))\n    xmin=bboxs[:,0]-(bboxs[:,2])/2\n    xmax=bboxs[:,0]+(bboxs[:,2])/2\n    ymin=bboxs[:,1]-(bboxs[:,3])/2\n    ymax=bboxs[:,1]+(bboxs[:,3])/2\n    bboxs=np.stack((xmin,ymin,xmax,ymax),axis=0).T\n    \n    if visualize==True: \n    \n        img_array_after=copy.deepcopy(image)\n        class_ids=image_labels[:,0]\n        for label,box in zip(class_ids.tolist(),bboxs.tolist()):\n            box=(np.array(box)).tolist()\n            color = label2color[int(label)]\n            img_array = draw_bbox(img_array_after,box,color,labels[int(label)])\n        fig, axes = plt.subplots(1, 2, figsize=(20,20))\n        axes[0].imshow(image)    \n        axes[1].imshow(img_array_after)        \n    #else:\n    return np.stack((image_labels[:,0],image_labels[:,-1],xmin,ymin,xmax,ymax),axis=0).T ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def Reformat_the_prediction_(test_images_path,labels_path,image_id,test_images_shapes,index,visualize=False):\n    if visualize==True:\n        downscale_factor=1\n        image=read_image(test_dir,image_id,downscale_factor)\n    else:\n        image=test_images_shapes[index]\n        \n    image_labels=[]\n    with open(test_labels_dir+image_id+'.txt') as fp:\n\n    #with open(test_labels_dir+test_list[100]) as fp:\n       line = fp.readline()\n       cnt = 1\n       while line:\n           labels_=[] \n           for i,item in enumerate(line.strip().split()) :\n               if i==0:\n                  labels_.append(int(item))\n               else:\n                  labels_.append(float(item))\n           image_labels.append(labels_)     \n           line = fp.readline()\n           cnt += 1    \n\n    image_labels=np.array(image_labels)\n    bboxs= image_labels[:,1:-1]   \n    bboxs=np.array(bboxs) \n    if visualize==True:\n        bboxs=bboxs*np.array((image.shape[1], image.shape[0], image.shape[1], image.shape[0]))\n    else:\n        bboxs=bboxs*np.array((image[1], image[0], image[1], image[0]))\n        \n    xmin=bboxs[:,0]-(bboxs[:,2])/2\n    xmax=bboxs[:,0]+(bboxs[:,2])/2\n    ymin=bboxs[:,1]-(bboxs[:,3])/2\n    ymax=bboxs[:,1]+(bboxs[:,3])/2\n    bboxs=np.stack((xmin,ymin,xmax,ymax),axis=0).T\n    \n    if visualize==True: \n    \n        img_array_after=copy.deepcopy(image)\n        class_ids=image_labels[:,0]\n        for label,box in zip(class_ids.tolist(),bboxs.tolist()):\n            box=(np.array(box)).tolist()\n            color = label2color[int(label)]\n            img_array = draw_bbox(img_array_after,box,color,labels[int(label)])\n        fig, axes = plt.subplots(1, 2, figsize=(20,20))\n        axes[0].imshow(image)    \n        axes[1].imshow(img_array_after)        \n    return np.stack((image_labels[:,0],image_labels[:,-1],xmin,ymin,xmax,ymax),axis=0).T \n\ndef no_filtering(boxes_list, scores_list, labels_list, weights,iou_thr):\n    boxes=[]\n    labels_=[]\n    #print(labels_list)\n    for boxes_list_cls,labels_cls in zip(boxes_list,labels_list):\n        boxes+=boxes_list_cls\n        labels_+=labels_cls\n    boxes=np.array(boxes)\n    labels_cls=np.array(labels_)\n    return boxes,np.array(scores_list),labels_cls","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Spliting the data to train and validation sets"},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.model_selection import train_test_split\ntrain_list,val_list=train_test_split(list(images_id_with_annotations), test_size=0.2, random_state=42)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# The visualization of the training images and their Bounding Boxes"},{"metadata":{"trusted":true},"cell_type":"code","source":"for i in range(6):\n   draw_bounding_box_of_image_using_image_id(train_annotated_df,train_list[i],train_dir,1)  ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# The visualization of the training data and the filtering of the bounding boxes:\nThe repo for bounding boxes filtering : [https://github.com/ZFTurbo/Weighted-Boxes-Fusion](http://)\n## Filter function options:\n* no_filtering\n* nms\n* soft_nms\n* non_maximum_weighted\n* weighted_boxes_fusion\n\n## in this competition the filtering did not help in the LP score in my experience "},{"metadata":{"trusted":true},"cell_type":"code","source":"img_before,img_after=bounding_box_filtering(train_annotated_df,train_list[10],no_filtering,2)\nfig, axes = plt.subplots(1, 2, figsize=(20,20))\naxes[0].imshow(img_before)    \naxes[1].imshow(img_after)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"img,img_=draw_bounding_box_of_image_using_image_id(train_annotated_df,train_list[5],train_dir,1)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Creating the directories for training ,validation and test "},{"metadata":{"trusted":true},"cell_type":"code","source":"import os\n\n# define the name of the directory to be created\npath = \"vinbigdata/labels/train/\"\n\ntry:\n    os.makedirs(path)\nexcept OSError:\n    print (\"Creation of the directory %s failed\" % path)\nelse:\n    print (\"Successfully created the directory %s\" % path)\n###############################################################\npath = \"vinbigdata/labels/val/\"\n\ntry:\n    os.makedirs(path)\nexcept OSError:\n    print (\"Creation of the directory %s failed\" % path)\nelse:\n    print (\"Successfully created the directory %s\" % path)    \n####################################################################################################    \npath = \"vinbigdata/images/train/\"\n\ntry:\n    os.makedirs(path)\nexcept OSError:\n    print (\"Creation of the directory %s failed\" % path)\nelse:\n    print (\"Successfully created the directory %s\" % path)\n##############################################################\npath = \"vinbigdata/images/val/\"\n\ntry:\n    os.makedirs(path)\nexcept OSError:\n    print (\"Creation of the directory %s failed\" % path)\nelse:\n    print (\"Successfully created the directory %s\" % path)    \n        \npath = \"vinbigdata/test/\"\n\ntry:\n    os.makedirs(path)\nexcept OSError:\n    print (\"Creation of the directory %s failed\" % path)\nelse:\n    print (\"Successfully created the directory %s\" % path)     ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"path='vinbigdata/images/train/'\nboxes,labels_=saving_image_and_filtered_bounding_boxes_in_yolo_format(train_annotated_df,train_list[10],3,no_filtering,path)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"The number of images in the training set : \",len(train_list))\nprint(\"The number of images in the vaildation set : \",len(val_list))\nprint(\"The number of images in the test set : \",len(test_images_ids))\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Creating the training data , validation data and test data folders for the YOLO5 :\nThe details about the directory structure is mentioned in this link : [https://github.com/ultralytics/yolov5/wiki/Train-Custom-Data](http://)\n"},{"metadata":{},"cell_type":"markdown","source":"remove [0:10] from train_list,val_list,test_list to use all the data available "},{"metadata":{"trusted":true},"cell_type":"code","source":"\ndownscale_factor=3\n\npath='vinbigdata/images/train/'\nfor idx,image_basename in enumerate(train_list[0:10]):\n    print(\"train image : \",idx)\n    boxes,labels_=saving_image_and_filtered_bounding_boxes_in_yolo_format(train_annotated_df,image_basename,downscale_factor,no_filtering,path)\n\nprint(\"************************************************************************\")    \npath='vinbigdata/images/val/'\nfor idx,image_basename in enumerate(val_list[0:10]):\n    print(\"val image : \",idx)\n    boxes,labels_=saving_image_and_filtered_bounding_boxes_in_yolo_format(train_annotated_df,image_basename,downscale_factor,no_filtering,path)\n   \nprint(\"************************************************************************\")    \ntest_path = \"vinbigdata/test/\"\nfor idx,image_basename in enumerate(test_images_ids[0:10]):\n    print(\"test image : \",idx) \n    image=read_image(test_dir,image_basename,downscale_factor)\n    save_path=test_path+str(image_basename)+'.jpg'\n    cv2.imwrite(save_path,image)\n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"  \n\nimage_path='vinbigdata/images/train/'+train_list[0]+'.jpg'\nbounding_box_path='vinbigdata/labels/train/'+train_list[0]+'.txt'\nimage_scaled,image_bbox_scaled,bboxes,class_ids=read_image_bounding_boxes(image_path,bounding_box_path)\nimg_array=read_image(train_dir,train_list[0],1)\nimg_array=rescale_bounding_boxes(img_array,image_scaled,bboxes)\n\nfig, axes = plt.subplots(1, 3, figsize=(20,20))\naxes[0].imshow(image_scaled)    \naxes[1].imshow(image_bbox_scaled)\naxes[2].imshow(img_array)\n\n ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# YOLO5\nThe repo for YOLO5 pytorch [https://github.com/ultralytics/yolov5](http://) \n\nTrain on custom data: [https://github.com/ultralytics/yolov5/wiki/Train-Custom-Data](http://)\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"!git clone https://github.com/ultralytics/yolov5  # clone repo\n%cd yolov5\n%pip install -qr requirements.txt  # install dependencies\n\nimport torch\nfrom IPython.display import Image, clear_output  # to display images\n\nclear_output()\nprint('Setup complete. Using torch %s %s' % (torch.__version__, torch.cuda.get_device_properties(0) if torch.cuda.is_available() else 'CPU'))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Training using yolov5 \n*  ### change the number of epoches to bigger number\n* ### in --weights use yolov5x.pt instead of yolov5x.pt"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Train YOLOv5s on COCO128 for 3 epochs\n!WANDB_MODE=\"dryrun\" python train.py --img 640 --batch 16 --epochs 1 --data /kaggle/input/yaml-yolo5-vinbigdata/VinBigData.yaml --weights yolov5s.pt --cache ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Inference on testset \n"},{"metadata":{"trusted":true},"cell_type":"code","source":"#!WANDB_MODE=\"dryrun\" python test.py --weights /kaggle/working/yolov5/runs/train/exp/weights/last.pt --data coco128.yaml --conf-thres 0.7 --task test --save-conf --save-txt ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''\n!zip -r vinbigdata_00.zip vinbigdata\nfrom IPython.display import FileLink\nFileLink(r'vinbigdata_00.zip')\n'''","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Making the submission file\n## uncomment next lines to make the submission file"},{"metadata":{"trusted":true},"cell_type":"code","source":"'''\nimport os\ntest_labels_dir='/kaggle/working/yolov5/runs/test/exp/labels/'\ntest_list=os.listdir(test_labels_dir)\nlen(test_list)\ntest_images_shapes=np.load('../input/labes-images-shapes/content/labels_images_shapes/test_images_shapes.npy').tolist()\n'''","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''\ntest_path = \"/kaggle/working/vinbigdata/test/\"\n\nprediction_strings_list=[]\nfor i,image_id in enumerate(sample_submission_df['image_id'].tolist()):\n    if image_id+'.txt' in test_list:  \n        #predictions=Reformat_the_prediction(test_path,test_labels_dir,image_id,False)\n        predictions=Reformat_the_prediction_(test_path,test_labels_dir,image_id,test_images_shapes,i,False)\n        prediction_string=''\n        print(i,\" of \",len(sample_submission_df))\n        for preds in predictions.tolist():\n            for pred in preds:\n                #print(pred)\n                prediction_string+=str(pred)+' '\n    else:\n        prediction_string='14 1.0 0 0 1 1 '\n    prediction_strings_list.append(prediction_string[:-1])\n'''    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''\nsample_submission_df['image_id'].tolist()\nsample_submission_df['PredictionString']=np.array(prediction_strings_list)\nsample_submission_df.to_csv(\"submission_013.csv\",index=False)\n''''","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''\nfrom IPython.display import FileLink\nFileLink(r'submission_013.csv')\n'''","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#ls vinbigdata/images/train/\n#len(os.listdir('vinbigdata/test/'))\n#!unzip vinbigdata.zip\n#os.stat('vinbigdata.zip').st_size/(1024*1024*1024)\n#ls \"vinbigdata/test/\"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}