{"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":"markdown","source":"# utils and import","metadata":{}},{"cell_type":"code","source":"import numpy as np \nimport pandas as pd\nimport cv2,torch\nimport matplotlib.pyplot as plt\nimport glob,os,random, time\nfrom pathlib import Path\nfrom tqdm.notebook import tqdm\n%matplotlib inline","metadata":{"execution":{"iopub.status.busy":"2022-12-31T05:32:00.116558Z","iopub.execute_input":"2022-12-31T05:32:00.116982Z","iopub.status.idle":"2022-12-31T05:32:00.721804Z","shell.execute_reply.started":"2022-12-31T05:32:00.116878Z","shell.execute_reply":"2022-12-31T05:32:00.720682Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"RESIZE_TO = (512,512)\nFP_IMG_OUTPUT = f'/kaggle/working/train_preprocessed_{RESIZE_TO[0]}'\n\n# Clone yolov5 repository\n!git clone https://github.com/ultralytics/yolov5\nMODEL = torch.hub.load('./yolov5', 'custom', path='/kaggle/input/rsna-breast-cancer-detection-roi-model/rsna-roi-003.pt', source='local')\n\n\ntrain = pd.read_csv('/kaggle/input/rsna-breast-cancer-detection/train.csv')","metadata":{"execution":{"iopub.status.busy":"2022-12-31T05:32:00.72332Z","iopub.execute_input":"2022-12-31T05:32:00.7244Z","iopub.status.idle":"2022-12-31T05:32:02.88403Z","shell.execute_reply.started":"2022-12-31T05:32:00.724365Z","shell.execute_reply":"2022-12-31T05:32:02.88272Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# functions\ndef show_imgs(imgs:list,titles=None):\n    %matplotlib inline\n    nrows = int((len(imgs)+2)/3)\n    fig, axs = plt.subplots(nrows,3,figsize=(15,5*nrows))\n    axs = axs.flatten()\n    for i,img in enumerate(imgs):\n        axs[i].imshow(img)\n        if titles:axs[i].set_title(titles[i])\n    plt.show()\n\ndef get_roi_xmin_ymin_xmax_ymax(img,MODEL):\n    results = MODEL(img).pandas().xyxy[0].to_dict(orient=\"records\")\n    try:\n        for result in results:\n            xmin, ymin, xmax, ymax = int(result['xmin']), int(result['ymin']), int(result['xmax']), int(result['ymax'])\n        return xmin, ymin, xmax, ymax\n    # return xmin, ymin, xmax, ymax = 0,0,0,0 when roi error occurs \n    # There are some images that ROI cannot be extracted\n    except:\n        # print(results)\n        return 0,0,0,0\n\n","metadata":{"execution":{"iopub.status.busy":"2022-12-31T05:32:02.88617Z","iopub.execute_input":"2022-12-31T05:32:02.886538Z","iopub.status.idle":"2022-12-31T05:32:02.901634Z","shell.execute_reply.started":"2022-12-31T05:32:02.886503Z","shell.execute_reply":"2022-12-31T05:32:02.900244Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# ROI extraction using yolo5","metadata":{}},{"cell_type":"markdown","source":"## Let's take a look at some examples\n## いくつか例を見てみましょう","metadata":{}},{"cell_type":"code","source":"# look at roi examples\nimgs=[]\nfile_list = glob.glob('/kaggle/input/rsna-breast-cancer-1024-pngs/output/*.png')\nfor img in random.sample(file_list, 15):\n    img = cv2.imread(img)\n    xmin, ymin, xmax, ymax = get_roi_xmin_ymin_xmax_ymax(img,MODEL)\n    imgs.append(cv2.rectangle(img,(xmin, ymin),(xmax, ymax),(255,0,0), 4))\nshow_imgs(imgs)","metadata":{"execution":{"iopub.status.busy":"2022-12-31T05:32:02.905092Z","iopub.execute_input":"2022-12-31T05:32:02.905418Z","iopub.status.idle":"2022-12-31T05:32:11.744672Z","shell.execute_reply.started":"2022-12-31T05:32:02.905389Z","shell.execute_reply":"2022-12-31T05:32:11.743134Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## caution!! There are some images that ROI cannot be extracted\n## 注意!! ROI抽出できない画像がいくつかあります。","metadata":{}},{"cell_type":"code","source":"# these are {patient_id}_{image_id} that ROI cannot be extracted.\nROI_IMPOSSIBLE_IDS = [\n    '8823_309184605',\n    '8421_141451331',\n    '8393_898783452',\n    '822_1942326353',\n    '735_804000911',\n    '735_2105598334',\n    '7330_171759076',\n    '7010_943445126',\n    '7010_1966077241',\n    '7010_1394606865',\n    '7010_1320320323',\n    '6637_1016408119',\n    '65471_658974043',\n    '65471_1729119684',\n    '65471_1435109581',\n    '64497_795954974',\n    '64456_1460733677',\n    '61688_1513474014',\n    '61198_1059280345',\n    '60669_875826928',\n    '60669_698291723',\n    '60669_377820496',\n    '60669_1680851388',\n    '59678_2084419034',\n    '59622_808346342',\n    '59622_1268104345',\n    '5945_1232071860',\n    '59427_1574841840',\n    '59101_824203447',\n    '59101_619281441',\n    '59101_1297544489',\n    '59101_1284818997',\n    '58535_824809615',\n    '58535_544454454',\n    '57543_802890376',\n    '56944_1674886477',\n    '5509_589777264',\n    '5509_432423933',\n    '5509_2011641884',\n    '5509_1817551939',\n    '5509_1227482395',\n    '5484_1787143772',\n    '54728_302552510',\n    '54713_457517852',\n    '54713_2109891320',\n    '54713_1672136872',\n    '54713_1507749602',\n    '54350_1613430858',\n    '54350_1005679241',\n    '54207_723926661',\n    '53879_2140017035',\n    '53879_206949522',\n    '53879_1386775331',\n    '53470_1663571485',\n    '53169_73891292',\n    '52509_930239507',\n    '52509_910813610',\n    '52509_775490405',\n    '52509_1072010415',\n    '51985_42754403',\n    '51985_1418182316',\n    '51985_1020096391',\n    '51115_136057818',\n    '51115_1124698320',\n    '51028_618600644',\n    '50883_1421845880',\n    '50865_194452157',\n    '50601_2041460652',\n    '5039_1454766283',\n    '50203_643148078',\n    '50086_1170159026',\n    '50039_469442434',\n    '50039_2079544503',\n    '50039_1998024633',\n    '49782_1702347808',\n    '49631_265605590',\n    '489_41369903',\n    '48273_212003030',\n    '48214_508220360',\n    '48214_373241958',\n    '48214_2064732798',\n    '47542_703427092',\n    '47542_1433236877',\n    '47094_1114821222',\n    '47094_1033138599',\n    '4659_1899676803',\n    '4659_1244500533',\n    '46373_914022232',\n    '46373_689012688',\n    '45355_1835017710',\n    '4502_1587934243',\n    '44996_1080733527',\n    '44351_381072284',\n    '44351_1135818329',\n    '44259_446024592',\n    '44259_2010399357',\n    '43368_665044649',\n    '43230_866964794',\n    '4275_882939987',\n    '42087_951770334',\n    '41347_2141240688',\n    '41347_1188748074',\n    '41219_824310278',\n    '4073_760569175',\n    '4073_492190855',\n    '4073_373657584',\n    '4073_2006141912',\n    '40538_1732136065',\n    '3996_2016160657',\n    '3996_1940625234',\n    '39850_79625830',\n    '39850_1940095769',\n    '39850_1062225308',\n    '38739_1889694445',\n    '38739_1632645203',\n    '38739_1189630231',\n    '38739_1110010839',\n    '38703_1938481823',\n    '38703_104678006',\n    '38571_646631209',\n    '38571_1711736849',\n    '38571_1289924620',\n    '38571_1281685733',\n    '3768_490308031',\n    '3768_197998560',\n    '3768_1634189725',\n    '37298_1870133039',\n    '36866_795543914',\n    '36847_522455815',\n    '3681_2045338450',\n    '36590_83218100',\n    '36584_962636509',\n    '36584_1767584249',\n    '36584_1762855227',\n    '36584_1103166696',\n    '36327_822062677',\n    '35145_542190316',\n    '34736_74538260',\n    '34736_1769077139',\n    '34671_651509199',\n    '33790_1825580114',\n    '33581_357843412',\n    '33581_2114024528',\n    '33581_208340179',\n    '33581_1586149541',\n    '33581_1398764972',\n    '33581_1335115222',\n    '33208_291911454',\n    '33208_1706592735',\n    '33150_508458124',\n    '33084_1990776518',\n    '32292_1929671544',\n    '32292_142501842',\n    '32292_1269795496',\n    '31709_1254229293',\n    '31401_2021827605',\n    '31065_1718862070',\n    '31042_2124348347',\n    '31025_2119117357',\n    '29768_309005418',\n    '29768_1975290049',\n    '29552_1362288007',\n    '294_60872123',\n    '294_2044098614',\n    '28752_743466894',\n    '2818_1624831082',\n    '28081_1571542936',\n    '2738_344392941',\n    '2738_1581308545',\n    '2738_1441486221',\n    '2738_1154819623',\n    '27199_389762847',\n    '26832_191973146',\n    '26700_88710137',\n    '26576_995786985',\n    '26576_687648578',\n    '26576_648237272',\n    '26530_1652786431',\n    '26102_501727322',\n    '26102_2056915646',\n    '26102_1734849791',\n    '25779_127056519',\n    '25578_631616205',\n    '25578_478017244',\n    '25578_1835471584',\n    '25369_821681566',\n    '25323_1743461841',\n    '24754_994468509',\n    '24754_1841985142',\n    '23419_949631286',\n    '23388_38981656',\n    '23388_2016619119',\n    '23251_220537118',\n    '23251_1477486748',\n    '23055_331990135',\n    '22739_227894185',\n    '22573_2037879772',\n    '22573_1816191467',\n    '21827_1072895377',\n    '2086_1450443663',\n    '20302_169932945',\n    '20008_750295971',\n    '20008_434991604',\n    '20008_1950237901',\n    '20008_1039395882',\n    '19977_1649284370',\n    '19277_1824000692',\n    '19277_1374212920',\n    '19277_1275907951',\n    '18646_1189625864',\n    '17111_998909338',\n    '17111_543347978',\n    '17111_1809890037',\n    '1660_1626904413',\n    '16497_1541367572',\n    '16497_134523937',\n    '16488_793868015',\n    '16488_1920435875',\n    '16488_1712612317',\n    '16124_1300489913',\n    '15877_1957636078',\n    '15503_882855657',\n    '15237_476991646',\n    '15237_1757900723',\n    '1511_764545189',\n    '13095_486827821',\n    '13095_1766531436',\n    '13095_1606501400',\n    '13095_1525295982',\n    '13095_1007282680',\n    '12994_74950104',\n    '12937_2022584518',\n    '1219_1911606224',\n    '10086_2029358943',\n]\n\n# # find out impossible roi extraction imgs\n# imgs=[]\n# file_list = glob.glob('/kaggle/input/rsna-breast-cancer-1024-pngs/output/*.png')\n# impossible_roi_imgs = []\n# for f in file_list:\n#     img = cv2.imread(f)\n#     xmin, ymin, xmax, ymax = get_roi_xmin_ymin_xmax_ymax(img,MODEL)\n#     if max(xmin, ymin, xmax, ymax)==0:\n#         # print(Path(f).name)\n#         impossible_roi_imgs.append(Path(f).stem)\n# impossible_roi_imgs\n\nprint('ROI_IMPOSSIBLE_IDS length:',len(ROI_IMPOSSIBLE_IDS))","metadata":{"execution":{"iopub.status.busy":"2022-12-31T05:32:11.74689Z","iopub.execute_input":"2022-12-31T05:32:11.747547Z","iopub.status.idle":"2022-12-31T05:32:11.767312Z","shell.execute_reply.started":"2022-12-31T05:32:11.747511Z","shell.execute_reply":"2022-12-31T05:32:11.765984Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Let's take a look at these \"ROI extraction impossible\" images\n### これらのROI抽出不可の画像を見てみましょう。","metadata":{}},{"cell_type":"code","source":"# look at images that ROI cannot be extracted\nimpossible_roi_imgs = [cv2.imread(f'/kaggle/input/rsna-breast-cancer-1024-pngs/output/{i}.png') for i in ROI_IMPOSSIBLE_IDS]\ntitles=[f'{i}.png' for i in ROI_IMPOSSIBLE_IDS]\nshow_imgs(impossible_roi_imgs,titles)","metadata":{"execution":{"iopub.status.busy":"2022-12-31T05:32:11.769062Z","iopub.execute_input":"2022-12-31T05:32:11.769447Z","iopub.status.idle":"2022-12-31T05:33:23.173445Z","shell.execute_reply.started":"2022-12-31T05:32:11.769412Z","shell.execute_reply":"2022-12-31T05:33:23.171783Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 822_1942326353.png is somehow all white\n# This also may be because ROI extraction error \ntrain[train.patient_id==822]\nplt.imshow(cv2.imread('/kaggle/input/rsna-breast-cancer-1024-pngs/output/822_1942326353.png'))","metadata":{"execution":{"iopub.status.busy":"2022-12-31T05:33:23.175227Z","iopub.execute_input":"2022-12-31T05:33:23.175678Z","iopub.status.idle":"2022-12-31T05:33:23.583208Z","shell.execute_reply.started":"2022-12-31T05:33:23.175639Z","shell.execute_reply":"2022-12-31T05:33:23.582077Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# define preprocessing function","metadata":{}},{"cell_type":"code","source":"def preprocess(train,verbose=500):\n    print('start')\n    !rm -rf {FP_IMG_OUTPUT}\n    !mkdir -p {FP_IMG_OUTPUT}\n    i = 0\n    start_time = time.time()\n    \n    for patient_id,image_id,machine_id,laterality in tqdm(zip(train.patient_id.values,train.image_id.values,train.machine_id.values,train.laterality.values)):\n        # read a image\n        path = f'/kaggle/input/rsna-breast-cancer-1024-pngs/output/{patient_id}_{image_id}.png'\n        img = cv2.imread(path)\n        assert img.shape == (1024,1024,3)\n        \n        # clip\n        # return xmin, ymin, xmax, ymax = 0,0,0,0 when roi error occurs \n        xmin, ymin, xmax, ymax = get_roi_xmin_ymin_xmax_ymax(img,MODEL)\n        if max(xmin, ymin, xmax, ymax)>0:\n            img = img[ymin:ymax,xmin:xmax]\n            \n        # resize\n        img = cv2.resize(img, dsize=RESIZE_TO)\n        \n        # normalize\n        get_norm_img(img)\n        \n        # flip: C type -> D type\n        if machine_id==49:  \n            # clip&flip machine_id=49 images using yolo5 \n            # flip: C type -> D type\n            if (xmin-0)> (1024-xmax):\n                img = cv2.flip(img,flipCode=1)            \n        elif laterality == 'R':\n            img = cv2.flip(img,flipCode=1)            \n\n        # save        \n        cv2.imwrite(f'{FP_IMG_OUTPUT}/{patient_id}_{image_id}.png', img.astype(np.uint8))\n        \n        # show verbose\n        if i%verbose==0 and i>0:\n            print(f'i={i}, avg time per iter:{(time.time()-start_time)/i*1000}[msec]')\n        i+=1\n        \ndef get_norm_img(img):\n    img = (img - img.min()) / (img.max() - img.min())\n    return img * 255","metadata":{"execution":{"iopub.status.busy":"2022-12-31T05:33:23.584473Z","iopub.execute_input":"2022-12-31T05:33:23.5848Z","iopub.status.idle":"2022-12-31T05:33:23.606106Z","shell.execute_reply.started":"2022-12-31T05:33:23.584769Z","shell.execute_reply":"2022-12-31T05:33:23.604832Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# this is used for faster processing\ndef preprocess_only_for_machine49(train,verbose=500):\n    print('start')\n    !rm -rf {FP_IMG_OUTPUT}\n    !mkdir -p {FP_IMG_OUTPUT}\n    i = 0\n    start_time = time.time()\n    for patient_id,image_id,machine_id in tqdm(zip(train.patient_id.values,train.image_id.values,train.machine_id.values)):\n        path = f'/kaggle/input/rsna-roi-preprocessed-png-512/train_resized_512/{patient_id}_{image_id}.png'\n        if machine_id==49 or not os.path.exists(path) :\n            path = f'/kaggle/input/rsna-breast-cancer-1024-pngs/output/{patient_id}_{image_id}.png'\n            img = cv2.imread(path)\n            \n            # clip&flip machine_id=49 images using yolo5 \n            # flip: C type -> D type\n            xmin, ymin, xmax, ymax = get_roi_xmin_ymin_xmax_ymax(img,MODEL)\n            if max(xmin, ymin, xmax, ymax)>0:\n                img = img[ymin:ymax,xmin:xmax]\n            if (xmin-0)> (1024-xmax):\n                img = cv2.flip(img,flipCode=1)\n            # resize\n            img = cv2.resize(img, dsize=RESIZE_TO)\n            \n            # normalize\n            img = get_norm_img(img)\n        else:\n            img = cv2.imread(path)\n\n        # save        \n        cv2.imwrite(f'{FP_IMG_OUTPUT}/{patient_id}_{image_id}.png', img.astype(np.uint8))\n        if i%verbose==0 and i>0:\n            print(f'i={i}, avg time per iter:{(time.time()-start_time)/i*1000}[msec]')\n        i+=1","metadata":{"execution":{"iopub.status.busy":"2022-12-31T05:33:23.607489Z","iopub.execute_input":"2022-12-31T05:33:23.60815Z","iopub.status.idle":"2022-12-31T05:33:23.628173Z","shell.execute_reply.started":"2022-12-31T05:33:23.608112Z","shell.execute_reply":"2022-12-31T05:33:23.626665Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Example use of preprocess()\n# failed to flip correctly in this way -> patient_id = 59750,42998\nn = 30\ndf = train.sample(n=n)\nprint(f'df shape: {df.shape}')\npreprocess(df,verbose=4)\n\npaths = glob.glob(f'{FP_IMG_OUTPUT}/*.png')\nimgs = [cv2.imread(path) for path in paths]\ntitles = [path.split('/')[-1] for path in paths]\nshow_imgs(imgs,titles)","metadata":{"execution":{"iopub.status.busy":"2022-12-31T05:33:23.629704Z","iopub.execute_input":"2022-12-31T05:33:23.630189Z","iopub.status.idle":"2022-12-31T05:33:40.652559Z","shell.execute_reply.started":"2022-12-31T05:33:23.630156Z","shell.execute_reply":"2022-12-31T05:33:40.651267Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# why `if machine_id==49`??","metadata":{}},{"cell_type":"code","source":"# len(train.machine_id.unique())\nfig,axs = plt.subplots(len(train.machine_id.unique()),len(train.laterality.unique()),figsize=(4,40))\nfor i,machine_id in enumerate(train.machine_id.unique()):\n    for j,laterality in enumerate(['L','R']): # train.laterality.unique()\n        df = train[train.machine_id==machine_id][train.laterality==laterality].sample()\n        image_id = int(df['image_id'])\n        patient_id = int(df['patient_id'])\n        path = f'/kaggle/input/rsna-breast-cancer-detection-poi-images/bc_1024_roi_train/bc_1024_roi_train/{patient_id}_{image_id}.png'\n        img = cv2.imread(path)\n        axs[i,j].imshow(img)\n        axs[i,j].set_title(f'machine id={machine_id},{laterality}')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-12-31T05:35:29.766613Z","iopub.execute_input":"2022-12-31T05:35:29.767414Z","iopub.status.idle":"2022-12-31T05:35:33.77292Z","shell.execute_reply.started":"2022-12-31T05:35:29.76737Z","shell.execute_reply":"2022-12-31T05:35:33.771853Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# process all the images using multiprocessing","metadata":{}},{"cell_type":"code","source":"%%time\n\npreprocess(train)","metadata":{"execution":{"iopub.status.busy":"2022-12-31T05:33:46.288504Z","iopub.execute_input":"2022-12-31T05:33:46.289172Z","iopub.status.idle":"2022-12-31T05:35:29.756739Z","shell.execute_reply.started":"2022-12-31T05:33:46.289132Z","shell.execute_reply":"2022-12-31T05:35:29.755495Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n# import multiprocessing as mp\n\n# print(mp.cpu_count())\n\n# n = len(train)\n# train_batches = []\n# n_split=300\n# for i in range(n_split):\n#     train_batches.append(train.iloc[int(n/n_split*i):int(n/n_split*(i+1)),:])\n\n\n# with mp.Pool(mp.cpu_count()) as p:\n#     p.map(preprocess_only_for_machine49, train_batches)","metadata":{"execution":{"iopub.status.busy":"2022-12-31T05:35:29.760526Z","iopub.execute_input":"2022-12-31T05:35:29.760884Z","iopub.status.idle":"2022-12-31T05:35:29.765545Z","shell.execute_reply.started":"2022-12-31T05:35:29.760852Z","shell.execute_reply":"2022-12-31T05:35:29.764612Z"},"trusted":true},"execution_count":null,"outputs":[]}]}