{"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":"3d rotation is way to increase numer of 2d slices for training.\n\n**WARNING:** original 3d image should have approximately equal axes scales or new slices would be highly distorted.","metadata":{}},{"cell_type":"code","source":"import os, re, pydicom\nimport numpy as np\nfrom scipy.ndimage import affine_transform\nimport matplotlib.pyplot as plt","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_directory = '../input/rsna-miccai-brain-tumor-radiogenomic-classification/'","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot3d(img3d):\n    fig, ax = plt.subplots(1,3)\n    fig.set_figheight(10)\n    fig.set_figwidth(20)\n    \n    ax[0].imshow(img3d[:,:,img3d.shape[2]//2])\n    ax[1].imshow(img3d[:,img3d.shape[1]//2,:])\n    ax[2].imshow(img3d[img3d.shape[0]//2,:,:])\n    plt.show()\n\ndef img3d_from_dicom(path):\n    files = sorted(os.listdir(path), key=lambda x: int(re.findall('\\\\d+', x)[0]))\n    deepth = len(os.listdir(path))\n    \n    for idx, f in enumerate(files):\n        dicom = pydicom.read_file(path + f)\n        data = dicom.pixel_array.astype(np.float32)\n           \n        if idx > 0:\n            img3d[:,:,idx] = data\n        else:            \n            img3d = np.zeros((data.shape[0], data.shape[1], deepth), dtype=np.float32)\n            img3d[:,:,0] = data\n        \n    return img3d - np.min(img3d)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Rotation vector (rot_v) is a three-dimensional vector \n# whose direction is the axis of rotation and \n# whose magnitude is the angle in radians.\n\ndef rotate_by_vector(img3d, rot_v):\n    \n    x, y, z = rot_v\n    angle = np.sqrt(x*x + y*y + z*z)\n    cos = np.cos(angle)\n    sin = np.sin(angle)\n    x, y, z = rot_v / angle\n\n    R = np.eye(4, dtype=np.float32)\n    R[0, 0] = cos + (1 - cos)*x*x\n    R[1, 1] = cos + (1 - cos)*y*y\n    R[2, 2] = cos + (1 - cos)*z*z\n    R[0, 1] = (1 - cos)*x*y - sin*z\n    R[0, 2] = (1 - cos)*x*z + sin*y    \n    R[1, 0] = (1 - cos)*x*y + sin*z\n    R[1, 2] = (1 - cos)*y*z - sin*x\n    R[2, 0] = (1 - cos)*x*z - sin*y\n    R[2, 1] = (1 - cos)*y*z + sin*x\n    \n    T1 = np.array(img3d.shape) / 2\n    T2 = np.matmul(R[:3,:3], T1)\n    R[:3, 3] = T1 - T2\n   \n    return affine_transform(img3d, R)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"patient = '00000'\npath = data_directory + '/train/' + patient + '/FLAIR/'\n\nimg3d  = img3d_from_dicom(path)[80:400, 110:410, 40:350]\nplot3d(img3d)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img3d_r = rotate_by_vector(img3d, np.radians([0, 10, 0]))\nplot3d(img3d_r)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img3d_r = rotate_by_vector(img3d, np.radians([-5, 10, -2]))\nplot3d(img3d_r)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}