{"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 python-gdcm -q","metadata":{"execution":{"iopub.status.busy":"2023-01-23T13:16:07.191363Z","iopub.execute_input":"2023-01-23T13:16:07.191901Z","iopub.status.idle":"2023-01-23T13:16:24.735317Z","shell.execute_reply.started":"2023-01-23T13:16:07.191796Z","shell.execute_reply":"2023-01-23T13:16:24.73383Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install pylibjpeg -q","metadata":{"execution":{"iopub.status.busy":"2023-01-23T13:16:24.738867Z","iopub.execute_input":"2023-01-23T13:16:24.739439Z","iopub.status.idle":"2023-01-23T13:16:37.637743Z","shell.execute_reply.started":"2023-01-23T13:16:24.739381Z","shell.execute_reply":"2023-01-23T13:16:37.636616Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Extract ROI area of breast image, using two lines in vertical and horizontal axes to generate the area.","metadata":{}},{"cell_type":"code","source":"import pydicom\nimport matplotlib.pyplot as plt\nimport pandas as pd\nimport numpy as np\nimport os\nimport cv2","metadata":{"execution":{"iopub.status.busy":"2023-01-23T13:16:37.639218Z","iopub.execute_input":"2023-01-23T13:16:37.639653Z","iopub.status.idle":"2023-01-23T13:16:38.095336Z","shell.execute_reply.started":"2023-01-23T13:16:37.639597Z","shell.execute_reply":"2023-01-23T13:16:38.094184Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def select_position(image_array, line_number, background, direction, offset=80):\n    min_pixel = image_array[:, line_number].min()\n    max_pixel = image_array[:, line_number].max()\n    try:\n        if direction == 0:\n            min_pixel_check_vertical_delete_line = image_array[:, line_number + offset].min()\n            max_pixel_check_vertical_delete_line = image_array[:, line_number + offset].max()\n        else:\n            min_pixel_check_vertical_delete_line = image_array[:, line_number - offset].min()\n            max_pixel_check_vertical_delete_line = image_array[:, line_number - offset].max()\n\n        if max_pixel_check_vertical_delete_line == min_pixel_check_vertical_delete_line:\n            return -1\n\n        if background == 0 and (min_pixel != max_pixel and max_pixel != 0):\n            return line_number\n        elif background == 1 and (min_pixel != max_pixel and min_pixel != 1):\n            return line_number\n    except: pass\n    return None","metadata":{"execution":{"iopub.status.busy":"2023-01-23T13:16:38.097762Z","iopub.execute_input":"2023-01-23T13:16:38.09814Z","iopub.status.idle":"2023-01-23T13:16:38.107303Z","shell.execute_reply.started":"2023-01-23T13:16:38.098104Z","shell.execute_reply":"2023-01-23T13:16:38.106121Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def find_vertical_split_point(image_array, background, direction, offset=80):\n    if direction == \"left->right\":\n        position = 0\n        while position < image_array.shape[1]:\n            position_check = select_position(image_array, position, background, direction=0)\n            if position_check == -1:\n                position += offset\n                continue\n            elif not(position_check is None):\n                return position_check\n            else:\n                return position\n            position += 2\n    elif direction == \"right->left\":\n        position = image_array.shape[1] - 1\n        while position > -1:\n            position_check = select_position(image_array, position, background, direction=1)\n            if position_check == -1:\n                position -= offset\n                continue\n            elif not (position_check is None):\n                return position_check\n            else:\n                return position\n            position -= 2","metadata":{"execution":{"iopub.status.busy":"2023-01-23T13:16:38.108863Z","iopub.execute_input":"2023-01-23T13:16:38.109357Z","iopub.status.idle":"2023-01-23T13:16:38.12091Z","shell.execute_reply.started":"2023-01-23T13:16:38.109311Z","shell.execute_reply":"2023-01-23T13:16:38.119884Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def find_horizonal_split_point(image_array, background):\n    result_list = []\n    one_of_images = []\n    has_image = 0\n    for i in range(0, image_array.shape[0], 2):\n        horizonal_min = image_array[i, :].min()\n        horizonal_max = image_array[i, :].max()\n        if has_image == 0 and ((horizonal_min != background) or (horizonal_max != background)):\n            one_of_images.append(i)\n            has_image = 1\n        elif has_image == 1 and ((horizonal_min == background) and (horizonal_max == background)):\n            one_of_images.append(i)\n            result_list.append(one_of_images)\n            one_of_images = []\n            has_image = 0\n\n    if len(one_of_images) > 0:\n        one_of_images.append(image_array.shape[0])\n        result_list.append(one_of_images)\n\n    length_list = list(map(lambda x: x[1]-x[0], result_list))\n    try:\n        return result_list[length_list.index(max(length_list))]\n    except:\n        return [0, image_array.shape[0]]","metadata":{"execution":{"iopub.status.busy":"2023-01-23T13:16:38.12237Z","iopub.execute_input":"2023-01-23T13:16:38.122844Z","iopub.status.idle":"2023-01-23T13:16:38.134225Z","shell.execute_reply.started":"2023-01-23T13:16:38.122799Z","shell.execute_reply":"2023-01-23T13:16:38.132863Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def crop_limitations(image_array, up_bottom_bounder_threshold):\n    left_min, left_max, right_min, right_max = image_array[:, 0].min(), image_array[:, 0].max(), image_array[:, -1].min(), image_array[:, -1].max()\n    if left_min == 0 and left_max == 0:\n        background = 0\n        left_split = max(0, find_vertical_split_point(image_array, background, direction=\"left->right\") - 1)\n        right_split = image_array.shape[0]\n    elif right_min == 0 and right_max == 0:\n        background = 0\n        right_split = find_vertical_split_point(image_array, background, direction=\"right->left\") + 1\n        left_split = 0\n    elif left_min == 1 and left_max == 1:\n        background = 1\n        left_split = max(0, find_vertical_split_point(image_array, background, direction=\"left->right\") - 1)\n        right_split = image_array.shape[0]\n    elif right_min == 1 and right_max == 1:\n        background = 1\n        right_split = find_vertical_split_point(image_array, background, direction=\"right->left\") + 1\n        left_split = 0\n    else:\n        return None\n\n    up_split, bottom_split = find_horizonal_split_point(image_array[:, left_split: right_split], background)\n    return (left_split, right_split, up_split, bottom_split)","metadata":{"execution":{"iopub.status.busy":"2023-01-23T13:16:38.135985Z","iopub.execute_input":"2023-01-23T13:16:38.136347Z","iopub.status.idle":"2023-01-23T13:16:38.150468Z","shell.execute_reply.started":"2023-01-23T13:16:38.136314Z","shell.execute_reply":"2023-01-23T13:16:38.149193Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def image_process_label_in_title(csv_address, image_address, output_image_address, resize_coefficient=None, up_bottom_bounder_threshold=1):\n    resize_height, resize_width, count_images = 0, 0, 0\n    special_case = []\n    data_frame = pd.read_csv(csv_address)\n\n    for current_director, folder_list, file_list in os.walk(image_address):\n        print(current_director)\n        for file in file_list:\n            # dicom_image -> array\n            file_name = file.split(\".\")[0]\n            dicom = pydicom.dcmread(os.path.join(current_director, file))\n            image_array = dicom.pixel_array\n            image_array = (image_array - image_array.min()) / (image_array.max() - image_array.min())\n            if dicom.PhotometricInterpretation == \"MONOCHROME1\":\n                image_array = 1 - image_array\n\n            # crop center image\n            crop_coordinate = crop_limitations(image_array, up_bottom_bounder_threshold)\n            if crop_coordinate is None:\n                special_case.append(file_name)\n            else:\n                left, right, up, bottom = crop_coordinate\n                image_result = image_array[up: bottom, left: right]\n\n                # label process to image title\n                specific_record = data_frame[data_frame[\"image_id\"] == int(file_name)] ###\n                laterality = specific_record.iloc[0, 3]\n                cancer = specific_record.iloc[0, 6]\n\n                if resize_coefficient is None:  # calculate_average_coefficient\n                    resize_width += image_result.shape[0]\n                    resize_height += image_result.shape[1]\n                    count_images += 1\n                else:\n                    if len(resize_coefficient) == 2:\n                        image_result = cv2.resize(image_result, (resize_coefficient[0], resize_coefficient[1]))\n                    else:\n                        image_result = cv2.resize(image_result, (image_result.shape[1] // 5, image_result.shape[0] // 5))\n                    cv2.imwrite(output_image_address + f\"{file_name}_{laterality}_{cancer}.png\",\n                                (image_result * 255).astype(np.uint8))\n\n    if resize_coefficient is None:\n        print(resize_width / count_images, resize_height / count_images)","metadata":{"execution":{"iopub.status.busy":"2023-01-23T13:16:38.152379Z","iopub.execute_input":"2023-01-23T13:16:38.152836Z","iopub.status.idle":"2023-01-23T13:16:38.16866Z","shell.execute_reply.started":"2023-01-23T13:16:38.152801Z","shell.execute_reply":"2023-01-23T13:16:38.167352Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**image_process_label_in_title** is used to generate .png images.\n- no specific resize_coefficient: calculate average ROI width & height\n- given resize_coefficient: generate resized .png images","metadata":{}},{"cell_type":"code","source":"csv_path = \"../input/rsna-breast-cancer-detection/train.csv\"\nimage_root_path = \"../input/rsna-breast-cancer-detection/train_images/\"\n# avg height&width\n# image_process_label_in_title(csv_path, image_root_path, \"./\")\n\n# generate images\nimage_process_label_in_title(csv_path, image_root_path, \"./\", 'original')","metadata":{"execution":{"iopub.status.busy":"2023-01-23T13:16:38.170123Z","iopub.execute_input":"2023-01-23T13:16:38.170448Z","iopub.status.idle":"2023-01-24T00:22:11.439332Z","shell.execute_reply.started":"2023-01-23T13:16:38.170408Z","shell.execute_reply":"2023-01-24T00:22:11.43256Z"},"trusted":true},"execution_count":null,"outputs":[]}]}