{"cells":[{"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 os\nimport pydicom\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut\nfrom skimage.transform import resize\nimport tensorflow as tf\nfrom tqdm.notebook import tqdm\nimport warnings\nwarnings.filterwarnings('ignore')\n\nfrom joblib import Parallel, delayed\nimport time, math\nimport random\nimport cv2\n#import png\n\ndef convert_to_png(dicomimage, filename):\n    ds = pydicom.dcmread(dicomimage)\n    img = apply_voi_lut(ds.pixel_array, ds)\n    orginal_shape = img.shape\n    img = resize(img, img.shape, anti_aliasing=True)\n    \n    if ds.PhotometricInterpretation == \"MONOCHROME1\":\n        img = np.amax(img) - img\n        \n    img = (((img - np.min(img))/np.max(img))*255.0).astype(np.uint8) \n    with open(filename + dicomimage.split('/')[-1].replace(\".dicom\", \".png\"), \"wb\") as fn:\n        img = cv2.imencode('.png',img)[1]\n        data_encode = np.array(img)\n        str_encode = data_encode.tostring()\n        fn.write(str_encode)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_path = \"../input/vinbigdata-chest-xray-abnormalities-detection/test/\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_images = os.listdir(test_path)\n\ntest_path_image = [test_path + image for image in test_images]\n\nfiletest = './original_testpng/' \nif not os.path.exists(os.path.dirname(filetest)):\n    os.makedirs(filetest)\n\nout = Parallel(n_jobs=-1)(delayed(convert_to_png)(image_path, filetest) \\\n    for image_path in tqdm(test_path_image))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#First Binary classifier model\ntez_path = '../input/tez-lib/'\ntimm_path = '../input/timm-pytorch-image-models/pytorch-image-models-master'\nimport sys\nsys.path.append(tez_path)\nsys.path.append(timm_path)\n\nimport os\nimport albumentations\nimport pandas as pd\n\nimport tez\nfrom tez.datasets import ImageDataset\nfrom tez.callbacks import EarlyStopping\n\nimport torch\nimport torch.nn as nn\nfrom torch.nn import functional as F\nimport torchvision\nimport torchvision.transforms as transforms\nfrom PIL import Image\n\nfrom sklearn import metrics, model_selection, preprocessing\nfrom scipy.special import softmax\nimport timm\n\nIMG_SIZE = 512\n\nclass CathModel(tez.Model):\n    def __init__(self, num_classes, model_name='resnext50_32x4d', pretrained=False):\n        super().__init__()\n\n        self.model = timm.create_model(model_name, pretrained=pretrained)\n        n_features = self.model.fc.in_features\n        self.out = nn.Linear(n_features, num_classes)\n        self.step_scheduler_after = \"epoch\"\n        self.criterion = nn.CrossEntropyLoss()\n        self.transform = transforms.Compose([\n            transforms.Resize((IMG_SIZE,IMG_SIZE)),\n            transforms.ToTensor(),\n            transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225))])\n    \n    def forward(self, image, targets=None):\n        batch_size, _, _, _ = image.shape\n        outputs = self.model(image)\n        return outputs, None, None\n    \n    def load(self, model_path, device=\"cuda\"):\n        self.device = device\n        if next(self.parameters()).device != self.device:\n            self.to(self.device)\n        model_dict = torch.load(model_path, map_location=device)\n        self.load_state_dict(model_dict[\"state_dict\"])\n        \n    def predict(self, data, device=\"cuda\"):\n        data = self.transform(data).to(device)\n        data = data.unsqueeze(0)\n        with torch.no_grad():\n            out = self.predict_one_step(data)\n            out = out.cpu().detach().numpy()\n            return out\n        \n    def model_fn(self, data):\n        #for key, value in data.items():\n        data = data.to(self.device)\n        output = self.model(data)\n        print(output)\n        output = softmax(output)\n        output = torch.argmax(output)\n        return output\n    \n    def predict_one_step(self, data):\n        output = self.model_fn(data)\n        return output","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# **Binary Classifier**"},{"metadata":{"trusted":true},"cell_type":"code","source":"model_BC = CathModel(num_classes=2, model_name='resnet18d')\nmodel_BC.load(\"../input/detectionmodel/resnet18d.bin\", device='cpu')\n#img = Image.open(\"./original_testpng/f5f77203f00504c40b45a65d23cd8948.png\").convert('RGB')\n#out = model.predict(img,'cpu')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 14 Class classifier"},{"metadata":{"trusted":true},"cell_type":"code","source":"model_14 = CathModel(num_classes=14, model_name='resnest101e')\nmodel_14.load(\"../input/detectionmodel/resnest101e.bin\", device='cuda')\n#img = Image.open(\"./original_testpng/f5f77203f00504c40b45a65d23cd8948.png\").convert('RGB')\n#out = model_14.predict(img)\n#out","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Detr Module"},{"metadata":{"trusted":true},"cell_type":"code","source":"import albumentations as A\nclass DETRModel(nn.Module):\n    def __init__(self,num_classes,num_queries):\n        super(DETRModel,self).__init__()\n        self.num_classes = num_classes\n        self.num_queries = num_queries\n        \n        self.model = torch.hub.load('facebookresearch/detr', 'detr_resnet50', pretrained=False)\n        self.in_features = self.model.class_embed.in_features\n        \n        self.model.class_embed = nn.Linear(in_features=self.in_features,out_features=self.num_classes)\n        self.model.num_queries = self.num_queries\n        \n    def forward(self,images):\n        return self.model(images)\n    \ndef predict(model, data, img,device='cuda'):\n    model.eval()\n    model.to(device)\n    cpu_device = torch.device('cpu')\n    h,w = img.size\n    with torch.no_grad():\n        outputs = model(data)\n        \n    outputs = [{k: v.to(cpu_device) for k, v in outputs.items()}]\n    oboxes = outputs[0]['pred_boxes'][0].detach().cpu().numpy()\n    oboxes = [np.array(box).astype(np.int32) for box in A.augmentations.bbox_utils.denormalize_bboxes(oboxes,h,w)]\n    prob   = outputs[0]['pred_logits'][0].softmax(1).detach().cpu().numpy()[:,0]\n    return oboxes, prob\n\ndetr_transform = transforms.Compose([\n            transforms.Resize((IMG_SIZE,IMG_SIZE)),\n            transforms.ToTensor(),\n            transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225))])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#model_detr = DETRModel(num_classes=1,num_queries=100)\n#model_detr.load_state_dict(torch.load(\"../input/detectionmodel/detrv1.pth\", map_location='cpu'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#img = Image.open(\"./original_testpng/f5f77203f00504c40b45a65d23cd8948.png\").convert('RGB')\n#data = detr_transform(img).to('cpu')\n#data = data.unsqueeze(0)\n#predict(model_detr, data, img, 'cpu')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import torchvision.transforms as transforms\nimport cv2\nimport numpy\nimport numpy as np\nimport glob\n\nimport torchvision\nimport torch\n\nfrom torchvision.models.detection.faster_rcnn import FastRCNNPredictor\nfrom torchvision.models.detection import FasterRCNN\n\nCOLORS = np.random.uniform(0, 255, size=(2, 3))\n\n# define the torchvision image transforms\ntransform = transforms.Compose([\n    #transforms.Resize((IMG_SIZE*2,IMG_SIZE*2)),\n    transforms.ToTensor(),\n    transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225))])\n\ncoco_names = [\n    '__background__',\n    'Interest'\n]\n\ndef predict(image, model, device, detection_threshold):\n    # transform the image to tensor\n    image = transform(image).to(device)\n    image = image.unsqueeze(0) # add a batch dimension\n    outputs = model(image) # get the predictions on the image\n    # print the results individually\n    # print(f\"BOXES: {outputs[0]['boxes']}\")\n    # print(f\"LABELS: {outputs[0]['labels']}\")\n    # print(f\"SCORES: {outputs[0]['scores']}\")\n    # get all the predicited class names\n    pred_classes = [coco_names[i] for i in outputs[0]['labels'].cpu().numpy()]\n    # get score for all the predicted objects\n    pred_scores = outputs[0]['scores'].detach().cpu().numpy()\n    # get all the predicted bounding boxes\n    pred_bboxes = outputs[0]['boxes'].detach().cpu().numpy()\n    # get boxes above the threshold score\n    boxes = pred_bboxes[pred_scores >= detection_threshold].astype(np.int32)\n    return boxes, pred_classes, outputs[0]['labels'], pred_scores\n\ndef draw_boxes(boxes, classes, labels, image):\n    # read the image with OpenCV\n    image = cv2.cvtColor(np.asarray(image), cv2.COLOR_BGR2RGB)\n    for i, box in enumerate(boxes):\n        color = COLORS[labels[i]]\n        cv2.rectangle(\n            image,\n            (int(box[0]), int(box[1])),\n            (int(box[2]), int(box[3])),\n            color, 2\n        )\n        cv2.putText(image, classes[i], (int(box[0]), int(box[1]-5)),\n                    cv2.FONT_HERSHEY_SIMPLEX, 0.8, color, 2, \n                    lineType=cv2.LINE_AA)\n    return image","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# download or load the model from disk\nmodel = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=False, pretrained_backbone=False)\ndevice = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')\n\nnum_classes = 2  # 1 class (wheat) + background\n\n# get number of input features for the classifier\nin_features = model.roi_heads.box_predictor.cls_score.in_features\n\n# replace the pre-trained head with a new one\nmodel.roi_heads.box_predictor = FastRCNNPredictor(in_features, num_classes)\n\n# Load the trained weights\nmodel.load_state_dict(torch.load('../input/detectionmodel/frcnnv1.bin', map_location = device))\nmodel.eval()\n\nx = model.to(device)\nfrom matplotlib import pyplot as plt\n\n#for imgPath in glob.glob(\"./original_testpng/*\"):\n#    image = Image.open(imgPath).convert('RGB')\n#    model.eval().to(device)\n#    boxes, classes, labels, pred_scores = predict(image, model, device, 0.3)\n    #image = draw_boxes(boxes, classes, labels, image)\n#    print(imgPath, boxes)\n\n#cv2.imshow('Image', image)\n#cv2.imwrite(f\"result.jpg\", image)\n#cv2.waitKey(0)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def format_prediction_string(labels, boxes, scores):\n    pred_strings = []\n    for j in zip(labels, scores, boxes):\n        pred_strings.append(\"{0} {1:.4f} {2} {3} {4} {5}\".format(\n            j[0], j[1], j[2][0], j[2][1], j[2][2], j[2][3]))\n\n    return \" \".join(pred_strings)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def finetune_classifier(boxes, img):\n    labels = list()\n    for bb in boxes:\n        #img_crop = img[int(bb[1]):int(bb[3]),int(bb[0]):int(bb[2])]\n        img_crop = img.crop((bb[0], bb[1], bb[2], bb[3]))\n        out = 1 #model_14.predict(img_crop)\n        #out = out.tolist()\n        labels.append(out)\n        \n    return labels","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from tqdm.notebook import tqdm \ndevice = 'cuda'\nresults = list()\nfor imgPath in tqdm(glob.glob(\"./original_testpng/*\")):\n    image_id = imgPath.split(\"/\")[-1].split(\".\")[0]\n    result = {\n    'image_id': image_id,\n    'PredictionString': '14 1.0 0 0 1 1'\n    }\n    #Binary classifier\n    img = Image.open(imgPath).convert('RGB')\n    out = model_BC.predict(img,device)\n    \n    if out == 0:\n        print(\"Empty case\")\n    else:\n        #Pass into frcnn network\n        boxes, classes, labels, pred_scores = predict(img, model, device, 0.3)\n        if len(boxes):\n            class_labels = finetune_classifier(boxes, img)\n            result = {\n            'image_id': image_id,\n            'PredictionString': format_prediction_string(class_labels, boxes.astype(np.int32), pred_scores)\n        }\n        \n    results.append(result)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df = pd.DataFrame(results, columns=['image_id', 'PredictionString'])\ntest_df.to_csv('submission.csv', index=False)\ntest_df.head()\n","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}