{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install -U albumentations==0.4.5\n!pip install torch==1.7.1 torchvision==0.8.2\n!pip install segmentation-models-pytorch\n!wget https://download.openmmlab.com/mmcv/dist/1.3.0/torch1.7.0/cu102/mmcv_full-1.3.0%2Btorch1.7.0%2Bcu102-cp37-cp37m-manylinux1_x86_64.whl\n!pip install ./mmcv_full-1.3.0+torch1.7.0+cu102-cp37-cp37m-manylinux1_x86_64.whl\n!pip install ../input/mmdetectionv260/addict-2.4.0-py3-none-any.whl\n!pip install ../input/mmdetectionv260/mmpycocotools-12.0.3-cp37-cp37m-linux_x86_64.whl\n!git clone https://github.com/shinya7y/UniverseNet\n!cp -r UniverseNet/* ./\n!pip install -v -e .\n!cp ../input/molconfig/uniconfig.py configs/universenet/universenet101.py","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_kg_hide-output":true,"execution":{"iopub.status.busy":"2021-06-03T10:46:36.221882Z","iopub.execute_input":"2021-06-03T10:46:36.222259Z","iopub.status.idle":"2021-06-03T10:47:28.962165Z","shell.execute_reply.started":"2021-06-03T10:46:36.222177Z","shell.execute_reply":"2021-06-03T10:47:28.961084Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import mmcv\nimport os\nfrom tqdm.auto import tqdm\nimport segmentation_models_pytorch as smp\nprint(mmcv.__version__)\nimport copy\nimport os.path as osp\nimport glob\n# Check Pytorch installation\nimport torch, torchvision\nprint(torch.__version__, torch.cuda.is_available())\nimport albumentations as albu\n# Check MMDetection installation\nimport mmdet\nprint(mmdet.__version__)\n\n# Check mmcv installation\nfrom mmcv.ops import get_compiling_cuda_version, get_compiler_version\nfrom mmcv import Config\nprint(get_compiling_cuda_version())\nprint(get_compiler_version())\n\nfrom mmdet.datasets import build_dataset, CocoDataset\nfrom mmdet.models import build_detector\nfrom mmdet.datasets.builder import DATASETS\nfrom mmdet.datasets.custom import CustomDataset\nfrom mmdet.apis import train_detector, set_random_seed, init_detector#, inference_detector\n\nfrom pycocotools.coco import COCO\nfrom pycocotools.cocoeval import COCOeval\n\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport matplotlib.animation as animation\nimport warnings\n\nimport mmcv\nimport numpy as np\nimport torch\nfrom mmcv.ops import RoIPool\nfrom mmcv.parallel import collate, scatter\nfrom mmcv.runner import load_checkpoint\n\nfrom mmdet.core import get_classes\nfrom mmdet.datasets import replace_ImageToTensor\nfrom mmdet.datasets.pipelines import Compose\nfrom mmdet.models import build_detector\nfrom IPython.core.display import display, HTML\nimport pickle\nimport cv2\nfrom matplotlib import pyplot as plt\nimport numpy as n\nfrom skimage.segmentation import mark_boundaries\nfrom skimage.measure import label, regionprops\nfrom collections import Counter\nimport numpy as np\nfrom matplotlib import pyplot as plt\nfrom scipy.spatial import distance\nfrom torch.utils.data import TensorDataset, DataLoader, Dataset\n","metadata":{"execution":{"iopub.status.busy":"2021-06-03T10:47:28.965701Z","iopub.execute_input":"2021-06-03T10:47:28.965968Z","iopub.status.idle":"2021-06-03T10:47:32.717406Z","shell.execute_reply.started":"2021-06-03T10:47:28.96594Z","shell.execute_reply":"2021-06-03T10:47:32.716542Z"},"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def inference_detector(model, imgs,rot90=True):\n    \"\"\"Inference image(s) with the detector.\n    Args:\n        model (nn.Module): The loaded detector.\n        imgs (str/ndarray or list[str/ndarray] or tuple[str/ndarray]):\n           Either image files or loaded images.\n    Returns:\n        If imgs is a list or tuple, the same length list type results\n        will be returned, otherwise return the detection results directly.\n    \"\"\"\n\n    if isinstance(imgs, (list, tuple)):\n        is_batch = True\n    else:\n        imgs = [imgs]\n        is_batch = False\n\n    cfg = model.cfg\n    device = next(model.parameters()).device  # model device\n\n    if isinstance(imgs[0], np.ndarray):\n        cfg = cfg.copy()\n        # set loading pipeline type\n        cfg.data.test.pipeline[0].type = 'LoadImageFromWebcam'\n\n    cfg.data.test.pipeline = replace_ImageToTensor(cfg.data.test.pipeline)\n    test_pipeline = Compose(cfg.data.test.pipeline)\n\n    datas = []\n    for img in imgs:\n        # prepare data\n        if isinstance(img, np.ndarray):\n            # directly add img\n            data = dict(img=img)\n        else:\n            # add information into dict\n            data = dict(img_info=dict(filename=img), img_prefix=None)\n        # build the data pipeline\n        data = test_pipeline(data)\n        datas.append(data)\n\n    data = collate(datas, samples_per_gpu=len(imgs))\n    # just get the actual data from DataContainer\n    data['img_metas'] = [img_metas.data[0] for img_metas in data['img_metas']]\n#     if data['img'][0].data[0].shape[-1] > data['img'][0].data[0].shape[-2]:\n#         data['img'] = [img.data[0] for img in data['img']]\n#     else:\n#         if rot90:\n#             data['img'] = [torch.rot90(img.data[0],1,[-2, -1]) for img in data['img']]\n#         else:\n    data['img'] = [img.data[0] for img in data['img']]\n        \n    if next(model.parameters()).is_cuda:\n        # scatter to specified GPU\n        data = scatter(data, [device])[0]\n    else:\n        for m in model.modules():\n            assert not isinstance(\n                m, RoIPool\n            ), 'CPU inference with RoIPool is not supported currently.'\n\n    # forward the model\n    with torch.no_grad():\n        results = model(return_loss=False, rescale=True, **data)\n\n    if not is_batch:\n        return results[0]\n    else:\n        return results\ndef norm(img):\n    img-=img.min()\n    return img/img.max()\ndef nms(dets, scores, thresh):\n    '''\n    dets is a numpy array : num_dets, 4\n    scores ia  nump array : num_dets,\n    '''\n    x1 = dets[:, 0]\n    y1 = dets[:, 1]\n    x2 = dets[:, 2]\n    y2 = dets[:, 3]\n\n    areas = (x2 - x1 + 1) * (y2 - y1 + 1)\n    order = scores.argsort()[::-1] # get boxes with more ious first\n\n    keep = []\n    while order.size > 0:\n        i = order[0] # pick maxmum iou box\n        keep.append(i)\n        xx1 = np.maximum(x1[i], x1[order[1:]])\n        yy1 = np.maximum(y1[i], y1[order[1:]])\n        xx2 = np.minimum(x2[i], x2[order[1:]])\n        yy2 = np.minimum(y2[i], y2[order[1:]])\n\n        w = np.maximum(0.0, xx2 - xx1 + 1) # maximum width\n        h = np.maximum(0.0, yy2 - yy1 + 1) # maxiumum height\n        inter = w * h\n        ovr = inter / (areas[i] + areas[order[1:]] - inter)\n\n        inds = np.where(ovr <= thresh)[0]\n        order = order[inds + 1]\n\n    return keep\ndef bb_intersection_over_union(boxA, boxB):\n    # determine the (x, y)-coordinates of the intersection rectangle\n    xA = max(boxA[0], boxB[0])\n    yA = max(boxA[1], boxB[1])\n    xB = min(boxA[2], boxB[2])\n    yB = min(boxA[3], boxB[3])\n    # compute the area of intersection rectangle\n    interArea = max(0, xB - xA + 1) * max(0, yB - yA + 1)\n    # compute the area of both the prediction and ground-truth\n    # rectangles\n    boxAArea = (boxA[2] - boxA[0] + 1) * (boxA[3] - boxA[1] + 1)\n    boxBArea = (boxB[2] - boxB[0] + 1) * (boxB[3] - boxB[1] + 1)\n    # compute the intersection over union by taking the intersection\n    # area and dividing it by the sum of prediction + ground-truth\n    # areas - the interesection area\n    iou = interArea / float(boxAArea + boxBArea - interArea)\n    # return the intersection over union value\n    return iou\ndef load_obj(name ):\n    with open(name, 'rb') as f:\n        return pickle.load(f)\ndef to_tensor(x, **kwargs):\n    return x.transpose(2, 0, 1).astype('float32')\n\ndef get_valid_augmentation(size=512):\n    return albu.Compose([\n        albu.Resize(size,size,always_apply=True),\n    ])\n\n\ndef get_preprocessing(preprocessing_fn):\n    _transform = [\n        albu.Lambda(image=preprocessing_fn),\n        albu.Lambda(image=to_tensor, mask=to_tensor),\n    ]\n    return albu.Compose(_transform)\n\nclass MolDataset(Dataset):\n    def __init__(self, paths, transforms=None, preprocessing=None,mode='test'):\n        self.paths = paths\n        self.transforms = transforms\n        self.preprocessing = preprocessing\n        self.mode = mode\n    def __getitem__(self, idx):\n        p = self.paths[idx]\n        img = cv2.imread(p,0)\n        noise_img = cv2.cvtColor(img.astype(np.uint8),cv2.COLOR_GRAY2RGB)\n        if self.transforms:\n            augmented = self.transforms(image=noise_img)\n            noise_img = augmented['image']\n        if self.preprocessing:\n            preprocessed = self.preprocessing(image=noise_img)\n            noise_img = preprocessed['image']\n        return noise_img,p\n\n    def __len__(self):\n        return len(self.paths)\ndef predict_one_image(config,img_real):\n    config['model'].eval()\n#     img_real = cv2.imread(path,0)\n    img = cv2.cvtColor(img_real.astype(np.uint8),cv2.COLOR_GRAY2RGB)\n    if config['aug']:\n        augmented = config['aug'](image=img)\n        img = augmented['image']\n    if config['preprocessing']:\n        preprocessed = config['preprocessing'](image=img)\n        img = preprocessed['image']\n    x = torch.from_numpy(np.expand_dims(img,0)).to(config['d'])\n    with torch.no_grad():\n        predicted,p_class = config['model'](x)\n        predicted_sigmoid = torch.sigmoid(predicted)\n        fet = config['model'].encoder.extract_features(x)\n        avg_features = torch.nn.AvgPool2d([fet.shape[-2],fet.shape[-1]])(fet)\n    mask = predicted_sigmoid[0].cpu().numpy().transpose(1,2,0)\n    mask = cv2.resize(mask,(img_real.shape[1],img_real.shape[0]))\n    return mask\n\ndef predict_one_image_with_crop(config,img_real):\n    config['model'].eval()\n#     img_real = cv2.imread(path,0)\n    h,w = img_real.shape[0:2]\n    flag = h>w\n    m = max(h,w)\n    c = min(h,w)\n    masks = np.zeros([h,w,3])\n    x_flag = False\n    y_flag = False\n    for row in range(0,m,c):\n        if flag:\n            img = cv2.cvtColor(img_real[row:row+c].astype(np.uint8),cv2.COLOR_GRAY2RGB)\n            if img.shape[0] != img.shape[1]:\n                img = cv2.cvtColor(img_real[-c:].astype(np.uint8),cv2.COLOR_GRAY2RGB)\n                y_flag = True\n        else:\n            img = cv2.cvtColor(img_real[:,row:row+c].astype(np.uint8),cv2.COLOR_GRAY2RGB)\n            if img.shape[0] != img.shape[1]:\n                img = cv2.cvtColor(img_real[:,-c:].astype(np.uint8),cv2.COLOR_GRAY2RGB)\n                x_flag = True\n        if config['aug']:\n            augmented = config['aug'](image=img)\n            img = augmented['image']\n        if config['preprocessing']:\n            preprocessed = config['preprocessing'](image=img)\n            img = preprocessed['image']\n        x = torch.from_numpy(np.expand_dims(img,0)).to(config['d'])\n        with torch.no_grad():\n            predicted,p_class = config['model'](x)\n            predicted_sigmoid = torch.sigmoid(predicted)\n            fet = config['model'].encoder.extract_features(x)\n            avg_features = torch.nn.AvgPool2d([fet.shape[-2],fet.shape[-1]])(fet)\n        mask = predicted_sigmoid[0].cpu().numpy().transpose(1,2,0)\n        mask = cv2.resize(mask,(c,c))\n        if flag:\n            if y_flag:\n                masks[-c:] = mask\n            else:\n                masks[row:row+c] = mask\n        else:\n            if x_flag:\n                masks[:,-c:] = mask\n            else:\n                masks[:,row:row+c] = mask\n    return masks","metadata":{"execution":{"iopub.status.busy":"2021-06-03T10:47:32.719342Z","iopub.execute_input":"2021-06-03T10:47:32.719658Z","iopub.status.idle":"2021-06-03T10:47:32.761368Z","shell.execute_reply.started":"2021-06-03T10:47:32.719627Z","shell.execute_reply":"2021-06-03T10:47:32.760465Z"},"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"classes = load_obj('../input/csv2kaggle/data/mapper.pkl') \n@DATASETS.register_module()\nclass MolLatter2(CocoDataset):\n    CLASSES = tuple([str(row) for row in classes.keys()])\nclasses","metadata":{"execution":{"iopub.status.busy":"2021-06-03T10:47:32.763139Z","iopub.execute_input":"2021-06-03T10:47:32.763556Z","iopub.status.idle":"2021-06-03T10:47:32.781239Z","shell.execute_reply.started":"2021-06-03T10:47:32.763516Z","shell.execute_reply":"2021-06-03T10:47:32.780091Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"config_file = 'configs/universenet/universenet101.py'\ncheckpoint_file = '../input/fork-of-step2-universenet20-08-101/epoch_1.pth'\ndevice = 'cuda:0'\n# init a detector\nmodel = init_detector(config_file, checkpoint_file, device=device)\n# inference the demo image\n","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2021-06-03T10:47:32.782763Z","iopub.execute_input":"2021-06-03T10:47:32.783197Z","iopub.status.idle":"2021-06-03T10:47:37.288385Z","shell.execute_reply.started":"2021-06-03T10:47:32.783096Z","shell.execute_reply":"2021-06-03T10:47:37.287525Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"paths = glob.glob('../input/bms-molecular-translation/test/0/0/0/*.png')\ndf = pd.read_csv(\"../input/bms-molecular-translation/train_labels.csv\")\nconfig_b5 = {\n    \"backbone\":\"efficientnet-b5\",\n    \"im_size\":384,\n    \"model_path\":\"../input/moleffunet/best_unet-b5.pth\",\n    \"seg_calss\": 3,\n    \"cls_class\":12,\n    \"d\":'cuda:0'}\nconfig_b3 = {\n    \"backbone\":\"efficientnet-b3\",\n    \"im_size\":512,\n    \"model_path\":\"../input/moleffunet/best_unet-b3.pth\",\n    \"seg_calss\": 3,\n    \"cls_class\":12,\n    \"d\":'cuda:0'}\nclass config:\n    real_path=\"../input/bms-molecular-translation/train\"\n    mask_path='../input/mol-temp'\n    font = cv2.FONT_HERSHEY_SIMPLEX\n    classes = ('1', '35', '5', '7', '8', '9', '14', '15', '16', '17', '53')\n    colors = [(255,0,0),(0,255,0),(0,0,255),(255,0,255),(255,255,0),(0,255,255),(255,255,255),(255,127,255),(255,255,127),(127,255,255),(127,127,127)]\n    unet = [config_b5,config_b3]\n    mask_TH = 0.5\n    bbox_TH = 0.2","metadata":{"execution":{"iopub.status.busy":"2021-06-03T10:47:37.289991Z","iopub.execute_input":"2021-06-03T10:47:37.290332Z","iopub.status.idle":"2021-06-03T10:47:41.812267Z","shell.execute_reply.started":"2021-06-03T10:47:37.29028Z","shell.execute_reply":"2021-06-03T10:47:41.811164Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i in range(len(config.unet)):\n    aux_params=dict(pooling='avg',dropout=0.2,activation=\"sigmoid\",classes=config.unet[i]['cls_class'])\n    config.unet[i]['model'] = torch.nn.DataParallel(smp.Unet(config.unet[i]['backbone'], classes=config.unet[i]['seg_calss'],encoder_weights=None, aux_params=aux_params))\n    config.unet[i]['model'].load_state_dict(torch.load(config.unet[i]['model_path'],map_location='cpu'))\n    config.unet[i]['model'] = config.unet[i]['model'].module\n    config.unet[i]['model'].to(config.unet[i]['d'])\nfor i in range(len(config.unet)):\n    config.unet[i]['preprocessing']= get_preprocessing(smp.encoders.get_preprocessing_fn(config.unet[i]['backbone'],\"imagenet\"))\n    config.unet[i]['aug'] = get_valid_augmentation(config.unet[i]['im_size'])","metadata":{"execution":{"iopub.status.busy":"2021-06-03T10:47:41.81368Z","iopub.execute_input":"2021-06-03T10:47:41.814072Z","iopub.status.idle":"2021-06-03T10:47:42.757163Z","shell.execute_reply.started":"2021-06-03T10:47:41.814028Z","shell.execute_reply":"2021-06-03T10:47:42.756267Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def norm(img):\n    img = img.astype(float)\n    img-=img.min()\n    img/=img.max()\n    img*=255\n    return img.astype(np.uint8)\n\ndef get_image(n):\n    path_img = f'{config.real_path}/{n[0]}/{n[1]}/{n[2]}/{n}.png'\n    img = cv2.imread(path_img,0)\n    if os.path.exists(f'{config.mask_path}/{n}.png'):\n        path_mask = f'{config.mask_path}/{n}.png'\n        mask = cv2.imread(path_mask)>(config.mask_TH*255)\n        by_crop = False\n    else:\n        ratio = float(img.shape[0])/float(img.shape[1])\n        if ratio > 3.5 or ratio < 1/3.5 or max(img.shape[0],img.shape[1])>550:\n            mask = predict_one_image_with_crop(config_b3,img)\n            mask = mask>(0.2)\n            by_crop = True\n        else:\n            mask = predict_one_image(config_b3,img)\n            mask = mask>config.mask_TH\n            by_crop = False\n        mask = mask[:,:,::-1]\n    img = np.expand_dims(img,-1)\n    img2 = np.concatenate([norm(mask),norm(img)],-1)\n    \n    return img2,by_crop\n\ndef get_Letters(n,imreal,img,verbose=False,TH=0.2,rot90=True):\n    is_rot90 = False\n#     imreal = f\"{real_path}/{n[0]}/{n[1]}/{n[2]}/{n}.png\"\n#     imreal = cv2.imread(imreal,0)\n#     path = f\"{mask_path}/{n}.png\"\n#     img = mmcv.imread(path)\n    img[:,:,0] = 255-imreal\n    img = cv2.UMat(img).get()\n    if img.shape[0]>img.shape[1] and rot90:\n        img = cv2.UMat(np.rot90(img,1).astype(np.uint8)).get()\n        imreal = np.rot90(imreal,1)\n        is_rot90=True\n    res = inference_detector(model, img,rot90=rot90)\n    res[0][:,-1]*=5\n    res[1][:,-1]*=2\n    new = []\n    label = []\n    for cl,row in enumerate(res):\n        for i in row:\n            new.append(np.array(i))\n            label.append(cl)\n    new = np.array(new) \n    label = np.array(label) \n    index = nms(new[:,:4],new[:,4],0.2)\n    final = np.concatenate([new[index],label[index].reshape(-1,1)],1)\n    if verbose:\n        for bbox in final:\n            x0,y0,x1,y1,p,cl = bbox\n            if p>TH:\n                cv2.putText(img,str(config.classes[int(cl)]),(int(x0),int(y0)),cv2.FONT_HERSHEY_SIMPLEX,0.6 if img.shape[0]>300 else 0.45, (255, 255, 255), 1, cv2.LINE_AA)\n    #             cv2.putText(img,str(round(p,1)),(int(x1)+6,int(y0)),font,0.6, (255, 255, 255), 1, cv2.LINE_AA)\n                cv2.rectangle(img,(int(x0),int(y0)),(int(x1),int(y1)),config.colors[int(cl)])\n        plt.figure(figsize=[20,20])\n        plt.subplot(121)\n        plt.imshow(imreal,cmap='gray')\n        plt.subplot(122)\n        plt.imshow(img)\n        plt.show()\n    return final[final[:,-2]>TH],is_rot90\n\ndef get_Neighbors_Atom(name,verbose=False,real_path=\"../input/bms-molecular-translation/test\",mask_path='../input/mol-temp'):\n    noise_img,by_crop = get_image(name)\n    print(by_crop)\n    Letters_cord,rot_90 = get_Letters(name,noise_img[:,:,-1].copy(),noise_img[:,:,:3].copy(),verbose=verbose,TH=config.bbox_TH)\n    if rot_90:\n        noise_img = np.rot90(noise_img,1)\n    if verbose:\n        plt.figure(figsize=[20,20])\n        plt.subplot(141)\n        plt.imshow(noise_img)\n        plt.subplot(142)\n        plt.imshow(noise_img[:,:,-1],cmap='gray')\n        plt.subplot(143)\n        plt.imshow(noise_img[:,:,1]-noise_img[:,:,0])\n        plt.subplot(144)\n        plt.imshow(noise_img[:,:,2])\n        plt.show()\n    im1 = noise_img[:,:,1]>0\n    im_real = noise_img[:,:,-1]<127\n    im0 = noise_img[:,:,0]>0.9\n    im_real_bool = im_real.astype(float)-im0.astype(float)\n    im_real_bool[im_real_bool<0]=0\n    lbl_0 = label(im0) \n    props = regionprops(lbl_0)\n    im = im1.astype(float)-im0.astype(float)\n    im[im<0]=0\n    lbl_1 = label(im) \n    props_1 = regionprops(lbl_1)\n    lbl_0 = lbl_0.astype(np.uint8)\n    r = np.array(Counter(lbl_0.reshape(-1)))\n    if verbose:\n        plt.figure(figsize=[20,20])\n        plt.subplot(141)\n        plt.imshow(lbl_0,cmap='hot')\n        plt.subplot(142)\n        plt.imshow(lbl_1,cmap='hot')\n        plt.subplot(143)\n        plt.imshow(im_real_bool,cmap='gray')\n        plt.subplot(144)\n        plt.imshow(im)\n        plt.show()\n    bbox = []\n    area =[]\n    dist ={}\n    Atom = {}\n    dist_min =[]\n    font                   = cv2.FONT_HERSHEY_SIMPLEX\n    fontScale              = 0.5\n    fontColor              = (0,0,255)\n    lineType               = 2\n    # fontColor              = 255\n    img = np.zeros([noise_img.shape[0],noise_img.shape[1],3])\n    img[:,:,0] = noise_img[:,:,-1].copy()\n    size_final = 0 \n    x,y = props[0].centroid\n    for i,prp in enumerate(props):\n    #     if prp.area>5:\n        c_flag = True\n        for j,bbox in enumerate(Letters_cord):\n            if bb_intersection_over_union([prp.bbox[1],prp.bbox[0],prp.bbox[3],prp.bbox[2]],bbox[0:4])>0:\n                cl = bbox[-1]\n                Atom[i]=int(config.classes[int(cl)])\n                c_flag = False\n                break\n        if c_flag:\n            Atom[i] = 6\n        cv2.putText(img,str(i), \n            (prp.bbox[1],prp.bbox[0]), \n            font, \n            fontScale,\n            fontColor,\n            lineType)\n        size_final+=1\n        if i!=0:\n            x1,y1 = prp.centroid\n            d = distance.euclidean([x1,y1],[x,y])\n            dist[i] = d\n            dist_min.append(int(d))\n    dist_min = np.sort(dist_min)[4]\n    img_0 = np.zeros([lbl_0.shape[0],lbl_0.shape[1],3]).astype(np.uint8)\n    print(lbl_0.max())\n    for i,prop in enumerate(props):\n        if prop.area>5:\n            y,x = prop.centroid\n            r = max(abs(prop.bbox[1]-prop.bbox[3]),abs(prop.bbox[0]-prop.bbox[2]))*1\n            cv2.circle(img_0,(int(x),int(y)),int(r),(i,0,0),-1)\n    d = np.zeros_like(img_0)\n    img_0 = img_0[:,:,0]\n    final = np.zeros([size_final,size_final])\n    avg = []\n    for row in range(lbl_1.max()):\n        l = lbl_1.copy()\n        l[l!=row+1]=0\n        l[l!=0]=1\n        res = img_0*l\n        avg.append(res.sum())\n    avg = np.median(avg)\n    for row in range(lbl_1.max()+1):\n\n        l = lbl_1.copy()\n        l[l!=row+1]=0\n        l[l!=0]=1\n        res = img_0*l\n        result = list(Counter(res.reshape(-1)))\n        if len(result)==2:\n            dist_new = dist[result[-1]]\n            if dist_new>dist_min:\n                continue\n            final[result[0],result[1]]+=1\n            final[result[1],result[0]]+=1\n        elif len(result)==3:\n            final[result[1],result[2]]+=1\n            final[result[2],result[1]]+=1\n    final[:,0][final[:,0]>2]=2\n    final[0,:][final[0,:]>2]=2\n    if verbose:\n        plt.figure(figsize=(15, 15))\n        plt.subplot(121)\n        plt.imshow(final,cmap='hot')\n        plt.subplot(122)\n        plt.imshow(img)\n        plt.show()\n    return pd.DataFrame(final),pd.DataFrame.from_dict(Atom, orient=\"index\",columns=['Atom_num'])","metadata":{"execution":{"iopub.status.busy":"2021-06-03T10:47:42.759301Z","iopub.execute_input":"2021-06-03T10:47:42.759696Z","iopub.status.idle":"2021-06-03T10:47:42.802644Z","shell.execute_reply.started":"2021-06-03T10:47:42.759656Z","shell.execute_reply":"2021-06-03T10:47:42.801647Z"},"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for row in tqdm(range(0,20)):\n    print(df.image_id[row])\n    print(df['InChI'][row])\n    n_table,ATOM = get_Neighbors_Atom(df.image_id[row],True,real_path=config.real_path,mask_path=config.mask_path)\n    print(\"---------------------------------------------------------------\")","metadata":{"execution":{"iopub.status.busy":"2021-06-03T10:47:42.804425Z","iopub.execute_input":"2021-06-03T10:47:42.804827Z","iopub.status.idle":"2021-06-03T10:47:47.296271Z","shell.execute_reply.started":"2021-06-03T10:47:42.804786Z","shell.execute_reply":"2021-06-03T10:47:47.295422Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}