--- a +++ b/scripts/ConvertDICOMToAVI.ipynb @@ -0,0 +1,215 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "# David Ouyang 10/2/2019\n", + "\n", + "# Notebook which iterates through a folder, including subfolders, \n", + "# and convert DICOM files to AVI files of a defined size (natively 112 x 112)\n", + "\n", + "import re\n", + "import os, os.path\n", + "from os.path import splitext\n", + "import pydicom as dicom\n", + "import numpy as np\n", + "from pydicom.uid import UID, generate_uid\n", + "import shutil\n", + "from multiprocessing import dummy as multiprocessing\n", + "import time\n", + "import subprocess\n", + "import datetime\n", + "from datetime import date\n", + "import sys\n", + "import cv2\n", + "#from scipy.misc import imread\n", + "import matplotlib.pyplot as plt\n", + "import sys\n", + "from shutil import copy\n", + "import math\n", + "\n", + "destinationFolder = \"Output Folder Name\"\n" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Requirement already satisfied: pillow in c:\\programdata\\anaconda3\\lib\\site-packages (6.2.0)\n", + "Requirement already satisfied: scipy in c:\\programdata\\anaconda3\\lib\\site-packages (1.3.1)\n" + ] + } + ], + "source": [ + "# Dependencies you might need to run code\n", + "# Commonly missing\n", + "\n", + "#!pip install pydicom\n", + "#!pip install opencv-python\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "def mask(output):\n", + " dimension = output.shape[0]\n", + " \n", + " # Mask pixels outside of scanning sector\n", + " m1, m2 = np.meshgrid(np.arange(dimension), np.arange(dimension))\n", + " \n", + "\n", + " mask = ((m1+m2)>int(dimension/2) + int(dimension/10)) \n", + " mask *= ((m1-m2)<int(dimension/2) + int(dimension/10))\n", + " mask = np.reshape(mask, (dimension, dimension)).astype(np.int8)\n", + " maskedImage = cv2.bitwise_and(output, output, mask = mask)\n", + " \n", + " #print(maskedImage.shape)\n", + " \n", + " return maskedImage\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "def makeVideo(fileToProcess, destinationFolder):\n", + " try:\n", + " fileName = fileToProcess.split('\\\\')[-1] #\\\\ if windows, / if on mac or sherlock\n", + " #hex(abs(hash(fileToProcess.split('/')[-1]))).upper()\n", + "\n", + " if not os.path.isdir(os.path.join(destinationFolder,fileName)):\n", + "\n", + " dataset = dicom.dcmread(fileToProcess, force=True)\n", + " testarray = dataset.pixel_array\n", + "\n", + " frame0 = testarray[0]\n", + " mean = np.mean(frame0, axis=1)\n", + " mean = np.mean(mean, axis=1)\n", + " yCrop = np.where(mean<1)[0][0]\n", + " testarray = testarray[:, yCrop:, :, :]\n", + "\n", + " bias = int(np.abs(testarray.shape[2] - testarray.shape[1])/2)\n", + " if bias>0:\n", + " if testarray.shape[1] < testarray.shape[2]:\n", + " testarray = testarray[:, :, bias:-bias, :]\n", + " else:\n", + " testarray = testarray[:, bias:-bias, :, :]\n", + "\n", + "\n", + " print(testarray.shape)\n", + " frames,height,width,channels = testarray.shape\n", + "\n", + " fps = 30\n", + "\n", + " try:\n", + " fps = dataset[(0x18, 0x40)].value\n", + " except:\n", + " print(\"couldn't find frame rate, default to 30\")\n", + "\n", + " fourcc = cv2.VideoWriter_fourcc('M','J','P','G')\n", + " video_filename = os.path.join(destinationFolder, fileName + '.avi')\n", + " out = cv2.VideoWriter(video_filename, fourcc, fps, cropSize)\n", + "\n", + "\n", + " for i in range(frames):\n", + "\n", + " outputA = testarray[i,:,:,0]\n", + " smallOutput = outputA[int(height/10):(height - int(height/10)), int(height/10):(height - int(height/10))]\n", + "\n", + " # Resize image\n", + " output = cv2.resize(smallOutput, cropSize, interpolation = cv2.INTER_CUBIC)\n", + "\n", + " finaloutput = mask(output)\n", + "\n", + "\n", + " finaloutput = cv2.merge([finaloutput,finaloutput,finaloutput])\n", + " out.write(finaloutput)\n", + "\n", + " out.release()\n", + "\n", + " else:\n", + " print(fileName,\"hasAlreadyBeenProcessed\")\n", + " except:\n", + " print(\"something filed, not sure what, have to debug\", fileName)\n", + " return 0" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "AllA4cNames = \"Input Folder Name\"\n", + "\n", + "count = 0\n", + " \n", + "cropSize = (112,112)\n", + "subfolders = os.listdir(AllA4cNames)\n", + "\n", + "\n", + "for folder in subfolders:\n", + " print(folder)\n", + "\n", + " for content in os.listdir(os.path.join(AllA4cNames, folder)):\n", + " for subcontent in os.listdir(os.path.join(AllA4cNames, folder, content)):\n", + " count += 1\n", + " \n", + "\n", + " VideoPath = os.path.join(AllA4cNames, folder, content, subcontent)\n", + "\n", + " print(count, folder, content, subcontent)\n", + "\n", + " if not os.path.exists(os.path.join(destinationFolder,subcontent + \".avi\")):\n", + " makeVideo(VideoPath, destinationFolder)\n", + " else:\n", + " print(\"Already did this file\", VideoPath)\n", + "\n", + "\n", + "print(len(AllA4cFilenames))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}