{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.7.9","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":13451,"databundleVersionId":1188070,"sourceType":"competition"},{"sourceId":2170623,"sourceType":"datasetVersion","datasetId":1303051},{"sourceId":7504502,"sourceType":"datasetVersion","datasetId":4370231},{"sourceId":7219,"sourceType":"modelInstanceVersion","modelInstanceId":5660}],"dockerImageVersionId":30068,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Load Data","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport pydicom\nimport os\nimport matplotlib.pyplot as plt\nimport collections\nfrom tqdm import tqdm_notebook as tqdm\nfrom datetime import datetime\nfrom math import ceil, floor, log\nimport cv2\nimport tensorflow as tf\nimport keras\nimport sys\nfrom keras.applications import *\nfrom keras.layers import *\nfrom sklearn.model_selection import ShuffleSplit\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport os\nimport PIL\nimport tensorflow as tf\nimport pathlib\nfrom tensorflow import keras\nfrom PIL import Image\nimport pandas as pd\nfrom glob import glob\nfrom tqdm import tqdm\nimport matplotlib.pyplot as plt\nfrom keras.models import *\nfrom keras.layers import *\nfrom keras.optimizers import *\nfrom keras.applications import *\nfrom keras.applications.vgg16 import VGG16\nfrom keras.applications.inception_v3 import InceptionV3\nfrom keras.applications.xception import Xception\nfrom keras.applications import DenseNet121, ResNet50V2, InceptionV3\nfrom keras.callbacks import EarlyStopping\nfrom keras.utils import plot_model\nfrom keras.callbacks import TensorBoard\nfrom tensorflow.keras.callbacks import EarlyStopping\nfrom tensorflow.keras.callbacks import ModelCheckpoint\nfrom keras.callbacks import EarlyStopping, ReduceLROnPlateau\nfrom keras.utils import Sequence\n\nif 'checkpoint' not in os.listdir('./'):\n    os.mkdir('./checkpoint')\n\n\ninput_path = \"../input/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/\"\ntest_images_dir = input_path + 'stage_2_test/'\ntrain_images_dir = input_path + 'stage_2_train/'","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"path = '../input/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/stage_2_train/ID_000012eaf.dcm'\nimg = pydicom.dcmread(path)\nimg","metadata":{"execution":{"iopub.status.busy":"2024-02-12T13:34:10.686966Z","iopub.execute_input":"2024-02-12T13:34:10.687352Z","iopub.status.idle":"2024-02-12T13:34:10.712482Z","shell.execute_reply.started":"2024-02-12T13:34:10.687315Z","shell.execute_reply":"2024-02-12T13:34:10.71171Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data Pre-Processing","metadata":{}},{"cell_type":"code","source":"def correct_dcm(dcm):\n    x = dcm.pixel_array + 1000\n    px_mode = 4096\n    x[x>=px_mode] = x[x>=px_mode] - px_mode\n    dcm.PixelData = x.tobytes()\n    dcm.RescaleIntercept = -1000\n\ndef window_image(dcm, window_center, window_width):\n    \n    if (dcm.BitsStored == 12) and (dcm.PixelRepresentation == 0) and (int(dcm.RescaleIntercept) > -100):\n        correct_dcm(dcm)\n    \n    img = dcm.pixel_array * dcm.RescaleSlope + dcm.RescaleIntercept\n    img_min = window_center - window_width // 2\n    img_max = window_center + window_width // 2\n    img = np.clip(img, img_min, img_max)\n\n    return img\n\ndef bsb_window(dcm):\n    brain_img = window_image(dcm, 40, 80)\n    subdural_img = window_image(dcm, 80, 200)\n    soft_img = window_image(dcm, 40, 380)\n    \n    brain_img = (brain_img - 0) / 80\n    subdural_img = (subdural_img - (-20)) / 200\n    soft_img = (soft_img - (-150)) / 380\n    bsb_img = np.array([brain_img, subdural_img, soft_img]).transpose(1,2,0)\n\n    return bsb_img\n\ndicom = pydicom.dcmread(train_images_dir + 'ID_5c8b5d701' + '.dcm')\nplt.imshow(bsb_window(dicom), cmap=plt.cm.bone);\n","metadata":{"execution":{"iopub.status.busy":"2024-02-12T13:34:14.769848Z","iopub.execute_input":"2024-02-12T13:34:14.770194Z","iopub.status.idle":"2024-02-12T13:34:15.03098Z","shell.execute_reply.started":"2024-02-12T13:34:14.770165Z","shell.execute_reply":"2024-02-12T13:34:15.030206Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def window_with_correction(dcm, window_center, window_width):\n    if (dcm.BitsStored == 12) and (dcm.PixelRepresentation == 0) and (int(dcm.RescaleIntercept) > -100):\n        correct_dcm(dcm)\n    img = dcm.pixel_array * dcm.RescaleSlope + dcm.RescaleIntercept\n    img_min = window_center - window_width // 2\n    img_max = window_center + window_width // 2\n    img = np.clip(img, img_min, img_max)\n    return img\n\ndef window_without_correction(dcm, window_center, window_width):\n    img = dcm.pixel_array * dcm.RescaleSlope + dcm.RescaleIntercept\n    img_min = window_center - window_width // 2\n    img_max = window_center + window_width // 2\n    img = np.clip(img, img_min, img_max)\n    return img\n\ndef window_testing(img, window):\n    brain_img = window(img, 40, 80)\n    subdural_img = window(img, 80, 200)\n    soft_img = window(img, 40, 380)\n    \n    brain_img = (brain_img - 0) / 80\n    subdural_img = (subdural_img - (-20)) / 200\n    soft_img = (soft_img - (-150)) / 380\n    bsb_img = np.array([brain_img, subdural_img, soft_img]).transpose(1,2,0)\n\n    return bsb_img\n\n# example of a \"bad data point\" (i.e. (dcm.BitsStored == 12) and (dcm.PixelRepresentation == 0) and (int(dcm.RescaleIntercept) > -100) == True)\ndicom = pydicom.dcmread(train_images_dir + \"ID_036db39b7\" + \".dcm\")\n\nfig, ax = plt.subplots(1, 2)\n\nax[0].imshow(window_testing(dicom, window_without_correction), cmap=plt.cm.bone);\nax[0].set_title(\"original\")\nax[1].imshow(window_testing(dicom, window_with_correction), cmap=plt.cm.bone);\nax[1].set_title(\"corrected\");","metadata":{"execution":{"iopub.status.busy":"2024-02-12T13:34:15.883967Z","iopub.execute_input":"2024-02-12T13:34:15.884325Z","iopub.status.idle":"2024-02-12T13:34:16.239149Z","shell.execute_reply.started":"2024-02-12T13:34:15.884294Z","shell.execute_reply":"2024-02-12T13:34:16.238242Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = pd.read_csv('../input/rsna-csv-files/RSNA_DATA/good_slices.csv',index_col = 'Unnamed: 0')","metadata":{"execution":{"iopub.status.busy":"2024-02-12T13:34:18.412403Z","iopub.execute_input":"2024-02-12T13:34:18.412783Z","iopub.status.idle":"2024-02-12T13:34:19.579426Z","shell.execute_reply.started":"2024-02-12T13:34:18.412737Z","shell.execute_reply":"2024-02-12T13:34:19.578691Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.head()","metadata":{"execution":{"iopub.status.busy":"2024-02-12T13:34:19.823749Z","iopub.execute_input":"2024-02-12T13:34:19.824082Z","iopub.status.idle":"2024-02-12T13:34:19.843095Z","shell.execute_reply.started":"2024-02-12T13:34:19.824054Z","shell.execute_reply":"2024-02-12T13:34:19.842323Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.shape","metadata":{"execution":{"iopub.status.busy":"2024-02-12T13:34:21.479128Z","iopub.execute_input":"2024-02-12T13:34:21.479547Z","iopub.status.idle":"2024-02-12T13:34:21.487321Z","shell.execute_reply.started":"2024-02-12T13:34:21.479511Z","shell.execute_reply":"2024-02-12T13:34:21.486203Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tqdm import trange\ndef get_partition_labels(df):\n    partition = dict()\n    labels = dict()\n    for i in trange(len(df)):\n        id_ = df.Image[i]\n        label = df.iloc[i,1:7].to_numpy(dtype = 'int32')\n        labels[id_] = label\n        \n    df = df.sample(frac = 0.1)\n    training = df.sample(frac = 0.8)\n    \n    validation = df.drop(training.index, axis = 0)\n    test = validation.sample(frac = 0.5)\n    validation = validation.drop(test.index, axis = 0) \n    \n    partition['train'] = list(training.Image)\n    partition['validation'] = list(validation.Image)\n    partition['test'] = list(test.Image)\n    return partition,labels","metadata":{"execution":{"iopub.status.busy":"2024-02-12T13:34:23.251086Z","iopub.execute_input":"2024-02-12T13:34:23.251428Z","iopub.status.idle":"2024-02-12T13:34:23.258897Z","shell.execute_reply.started":"2024-02-12T13:34:23.251398Z","shell.execute_reply":"2024-02-12T13:34:23.25809Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"partition,labels = get_partition_labels(df)","metadata":{"execution":{"iopub.status.busy":"2024-02-12T13:34:32.688387Z","iopub.execute_input":"2024-02-12T13:34:32.688715Z","iopub.status.idle":"2024-02-12T13:35:52.071234Z","shell.execute_reply.started":"2024-02-12T13:34:32.688685Z","shell.execute_reply":"2024-02-12T13:35:52.070209Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(partition['train'])\nvalues_view = labels.values()\nvalue_iterator = iter(values_view)\nfirst_value = next(value_iterator)\nprint(next(iter(labels)))\nprint(first_value)\n\n\nvalues_view2 = partition.values()\nvalue_iterator2 = iter(values_view)\nfirst_value2 = next(value_iterator)\nprint(next(iter(partition['train'])))\nprint(first_value2)","metadata":{"execution":{"iopub.status.busy":"2024-02-12T13:35:58.782129Z","iopub.execute_input":"2024-02-12T13:35:58.782574Z","iopub.status.idle":"2024-02-12T13:35:58.792437Z","shell.execute_reply.started":"2024-02-12T13:35:58.782532Z","shell.execute_reply":"2024-02-12T13:35:58.79076Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(partition['train'])\n#len(partition['validation'])\n#len(partition['test'])","metadata":{"execution":{"iopub.status.busy":"2024-02-12T13:36:01.019552Z","iopub.execute_input":"2024-02-12T13:36:01.019933Z","iopub.status.idle":"2024-02-12T13:36:01.025487Z","shell.execute_reply.started":"2024-02-12T13:36:01.019898Z","shell.execute_reply":"2024-02-12T13:36:01.024633Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def _read(path, desired_size):\n    dcm = pydicom.dcmread(path)\n    \n    try:\n        img = bsb_window(dcm)\n    except:\n        img = np.zeros(desired_size)\n    \n    \n    img = cv2.resize(img, desired_size[:2], interpolation=cv2.INTER_LINEAR)\n    return img\n \nplt.imshow(\n    _read(train_images_dir+'ID_5c8b5d701'+'.dcm', (256, 256,3)), cmap=plt.cm.bone\n);","metadata":{"execution":{"iopub.status.busy":"2024-02-12T13:36:04.387785Z","iopub.execute_input":"2024-02-12T13:36:04.388159Z","iopub.status.idle":"2024-02-12T13:36:04.555451Z","shell.execute_reply.started":"2024-02-12T13:36:04.388125Z","shell.execute_reply":"2024-02-12T13:36:04.554466Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"type(_read(train_images_dir+'ID_5c8b5d701'+'.dcm', (256, 256,3)))","metadata":{"execution":{"iopub.status.busy":"2024-02-11T12:08:37.488091Z","iopub.execute_input":"2024-02-11T12:08:37.488482Z","iopub.status.idle":"2024-02-11T12:08:37.510627Z","shell.execute_reply.started":"2024-02-11T12:08:37.488444Z","shell.execute_reply":"2024-02-11T12:08:37.509754Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nimport keras\n\nclass DataGenerator(keras.utils.Sequence):\n    'Generates data for Keras'\n    def __init__(self, list_IDs, labels, batch_size=64, dim=(32,32,32), n_channels=1,\n                 n_classes=10, shuffle=True):\n        'Initialization'\n        self.dim = dim\n        self.batch_size = batch_size\n        self.labels = labels\n        self.list_IDs = list_IDs\n        self.n_channels = n_channels\n        self.n_classes = n_classes\n        self.shuffle = shuffle\n        self.true_labels = []\n        self.on_epoch_end()\n\n    def __len__(self):\n        'Denotes the number of batches per epoch'\n        return int(np.floor(len(self.list_IDs) / self.batch_size))\n\n    def __getitem__(self, index):\n        'Generate one batch of data'\n        indexes = self.indexes[index*self.batch_size:(index+1)*self.batch_size]\n\n        list_IDs_temp = [self.list_IDs[k] for k in indexes]\n\n        X, y = self.__data_generation(list_IDs_temp)\n        \n        self.true_labels.append(y)\n\n        return X, y\n\n    def on_epoch_end(self):\n        'Updates indexes after each epoch'\n        self.indexes = np.arange(len(self.list_IDs))\n        if self.shuffle == True:\n            np.random.shuffle(self.indexes)\n\n    def __data_generation(self, list_IDs_temp):\n        'Generates data containing batch_size samples' \n        X = np.empty((self.batch_size, *self.dim)) \n        y = np.empty(self.batch_size, dtype=int) # here we remove np.empty((self.batch_size,6))\n\n        # Generate data\n        for i, ID in enumerate(list_IDs_temp):\n            # Store sample\n            image_dir = '../input/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/stage_2_train/'\n            X[i,] = _read(image_dir+ID+'.dcm',self.dim)\n            #print(X)\n            # Store class\n            \n            # y[i] = self.labels[ID]\n            y[i] =np.argmax(self.labels[ID])\n\n        return X,y","metadata":{"execution":{"iopub.status.busy":"2024-02-12T13:36:09.343671Z","iopub.execute_input":"2024-02-12T13:36:09.344052Z","iopub.status.idle":"2024-02-12T13:36:09.357Z","shell.execute_reply.started":"2024-02-12T13:36:09.344016Z","shell.execute_reply":"2024-02-12T13:36:09.356106Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.losses import SparseCategoricalCrossentropy\nfrom tensorflow.keras.losses import CategoricalCrossentropy\nfrom tensorflow.keras.utils import to_categorical\n","metadata":{"execution":{"iopub.status.busy":"2024-02-12T13:36:12.501513Z","iopub.execute_input":"2024-02-12T13:36:12.50189Z","iopub.status.idle":"2024-02-12T13:36:12.506585Z","shell.execute_reply.started":"2024-02-12T13:36:12.501852Z","shell.execute_reply":"2024-02-12T13:36:12.505543Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"params = {'dim':(224,224,3),\n         'batch_size':64,\n         'n_classes':6,\n         'n_channels':0,\n         'shuffle':True}\n\ncallbacks = [\n    ModelCheckpoint(filepath='./checkpoint', monitor = 'val_weighted_loss' ,save_best_only=True,verbose = 3),\n    ReduceLROnPlateau(monitor= 'val_weighted_loss', factor=0.1, patience= 3, verbose=1,mode='auto', min_delta=0.0001)]\n\n# Convert labels to categorical if not already\n#labels_categorical = {k: to_categorical(v, num_classes=params['n_classes']) for k, v in labels.items()}\n\n# Generators\n\ntraining_generator = DataGenerator(partition['train'], labels, **params)\nvalidation_generator = DataGenerator(partition['validation'], labels, **params)\n\n\n# Design model\nmodel = Sequential([\n    tf.keras.applications.ResNet50V2(\n    include_top=False,\n    weights=\"imagenet\",\n    input_shape=params['dim'],\n    pooling='max'),\n    Flatten(),\n    Dense(256,activation = 'relu'),\n    Dense(6,activation = 'sigmoid'),\n    Dense(6, activation = 'softmax')\n    #Dense(params['n_classes'], activation='softmax')\n])\n\nprint(\"Model Input Shape:\", model.input_shape)\nprint(\"Model Output Shape:\", model.output_shape)\n\n# Check the model input and output shapes with a sample batch\n#for batch_x, batch_y in training_generator:\n #   logits = model(batch_x)\n  #  print(\"Logits Shape:\", logits.shape)\n  #  print(\"Labels Shape:\", batch_y.shape)\n   # break\n\nmodel.compile(optimizer='adam', loss = SparseCategoricalCrossentropy(from_logits=True), metrics=['accuracy'])\n\n","metadata":{"execution":{"iopub.status.busy":"2024-02-12T14:03:47.292337Z","iopub.execute_input":"2024-02-12T14:03:47.292831Z","iopub.status.idle":"2024-02-12T14:03:48.990991Z","shell.execute_reply.started":"2024-02-12T14:03:47.29276Z","shell.execute_reply":"2024-02-12T14:03:48.990076Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#SparseCategoricalCrossentropy(from_logits=True)\n","metadata":{"execution":{"iopub.status.busy":"2024-02-12T14:03:48.992776Z","iopub.execute_input":"2024-02-12T14:03:48.993101Z","iopub.status.idle":"2024-02-12T14:03:48.996426Z","shell.execute_reply.started":"2024-02-12T14:03:48.993071Z","shell.execute_reply":"2024-02-12T14:03:48.995721Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Model Input Shape:\", model.input_shape)\nprint(\"Model Output Shape:\", model.output_shape)\nfor batch_x, batch_y in training_generator:\n    logits = model(batch_x)\n    print(\"Logits Shape:\", logits.shape)\n    print(\"Labels Shape:\", batch_y.shape)\n    break\n","metadata":{"execution":{"iopub.status.busy":"2024-02-12T14:03:48.997565Z","iopub.execute_input":"2024-02-12T14:03:48.997872Z","iopub.status.idle":"2024-02-12T14:03:49.760887Z","shell.execute_reply.started":"2024-02-12T14:03:48.997845Z","shell.execute_reply":"2024-02-12T14:03:49.759993Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Training & Evaluation","metadata":{}},{"cell_type":"code","source":"# Train model on dataset\nhistory = model.fit(training_generator, validation_data=validation_generator, epochs=1, callbacks=callbacks)","metadata":{"execution":{"iopub.status.busy":"2024-02-12T14:03:54.44065Z","iopub.execute_input":"2024-02-12T14:03:54.441003Z","iopub.status.idle":"2024-02-12T14:10:07.206651Z","shell.execute_reply.started":"2024-02-12T14:03:54.440973Z","shell.execute_reply":"2024-02-12T14:10:07.205892Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Save the entire model (including architecture, optimizer state, and weights)\n#model.save(\"my_model.h5\")\n","metadata":{"execution":{"iopub.status.busy":"2024-01-26T14:55:11.431221Z","iopub.execute_input":"2024-01-26T14:55:11.431612Z","iopub.status.idle":"2024-01-26T14:55:12.286111Z","shell.execute_reply.started":"2024-01-26T14:55:11.431577Z","shell.execute_reply":"2024-01-26T14:55:12.285276Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"code","source":"import os\nfrom tensorflow.keras.models import load_model\n\n# Specify the path where your model is stored\nmodel_path = '/kaggle/input/ich_classification/tensorflow2/slug/1/my_model.h5'\n\n# Load the model\nloaded_model = load_model(model_path)\n","metadata":{"execution":{"iopub.status.busy":"2024-01-28T11:12:31.316058Z","iopub.execute_input":"2024-01-28T11:12:31.316387Z","iopub.status.idle":"2024-01-28T11:12:36.536235Z","shell.execute_reply.started":"2024-01-28T11:12:31.316355Z","shell.execute_reply":"2024-01-28T11:12:36.53547Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nfrom sklearn.metrics import accuracy_score\nfrom sklearn.metrics import classification_report\n\n# Assuming you have test data and labels\ntest_data_generator = DataGenerator(partition['test'], labels, **params)\n\n# Make predictions on the test data\npredictions = loaded_model.predict(test_data_generator)\n\n# Convert predicted probabilities to class labels\npredicted_labels = np.argmax(predictions, axis=1)\n\n# Calculate the number of samples in the test partition\nnum_test_samples = len(predicted_labels)\n\n# Get true labels from the generator\ntrue_labels = np.concatenate(test_data_generator.true_labels)\ntrue_labels = true_labels[:num_test_samples]\n\n\n# Calculate accuracy\n#accuracy = accuracy_score(true_labels, predicted_labels)\n#print(f'Accuracy: {accuracy * 100:.2f}%')\n\n# Print classification report\nprint(classification_report(true_labels, predicted_labels))\n","metadata":{"execution":{"iopub.status.busy":"2024-01-28T11:12:36.538729Z","iopub.execute_input":"2024-01-28T11:12:36.539005Z","iopub.status.idle":"2024-01-28T11:14:13.255118Z","shell.execute_reply.started":"2024-01-28T11:12:36.538979Z","shell.execute_reply":"2024-01-28T11:14:13.2542Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#history=loaded_model\nimport matplotlib.pyplot as plt\n\nacc = history.history['accuracy']\nval_acc =  history.history['val_accuracy']\n\nloss = history.history['loss']\nval_loss = history.history['val_loss']\n\nepochs = range(1, len(acc) + 1)\n\nplt.plot(epochs, acc, 'r', label='Training Accuracy')\nplt.plot(epochs, val_acc, 'b', label='Validation Accuracy')\nplt.title('Training and validation acc')\nplt.legend()\nplt.figure()\n\nplt.plot(epochs, loss, 'r', label='Training loss')\nplt.plot(epochs, val_loss, 'b', label='Validation loss')\nplt.title('Training and validation loss')\nplt.legend()\nplt.figure()\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-02-12T14:12:38.448483Z","iopub.execute_input":"2024-02-12T14:12:38.448857Z","iopub.status.idle":"2024-02-12T14:12:38.764358Z","shell.execute_reply.started":"2024-02-12T14:12:38.448823Z","shell.execute_reply":"2024-02-12T14:12:38.763478Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nacc = history.history['accuracy']\nval_acc =  history.history['val_accuracy']\n\nloss = history.history['loss']\nval_loss = history.history['val_loss']\n\nepochs = range(1, len(acc) + 1)\n\nplt.plot(epochs, acc, 'r', label='Training Accuracy')\nplt.plot(epochs, val_acc, 'b', label='Validation Accuracy')\nplt.title('Training and validation acc')\nplt.legend()\nplt.figure()\n\nplt.plot(epochs, loss, 'r', label='Training loss')\nplt.plot(epochs, val_loss, 'b', label='Validation loss')\nplt.title('Training and validation loss')\nplt.legend()\nplt.figure()\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-02-12T14:10:57.407086Z","iopub.execute_input":"2024-02-12T14:10:57.40743Z","iopub.status.idle":"2024-02-12T14:10:57.75472Z","shell.execute_reply.started":"2024-02-12T14:10:57.407401Z","shell.execute_reply":"2024-02-12T14:10:57.753965Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nacc = history.history['accuracy']\nval_acc =  history.history['val_accuracy']\n\nloss = history.history['loss']\nval_loss = history.history['val_loss']\n\nepochs = range(1, len(acc) + 1)\n\nplt.plot(epochs, acc, 'r', label='Training Accuracy')\nplt.plot(epochs, val_acc, 'b', label='Validation Accuracy')\nplt.title('Training and validation acc')\nplt.legend()\nplt.figure()\n\nplt.plot(epochs, loss, 'r', label='Training loss')\nplt.plot(epochs, val_loss, 'b', label='Validation loss')\nplt.title('Training and validation loss')\nplt.legend()\nplt.figure()\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-01-26T16:25:19.659816Z","iopub.execute_input":"2024-01-26T16:25:19.660153Z","iopub.status.idle":"2024-01-26T16:25:19.693365Z","shell.execute_reply.started":"2024-01-26T16:25:19.660077Z","shell.execute_reply":"2024-01-26T16:25:19.692345Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras import backend as K\n\ndef weighted_log_loss(y_true, y_pred):\n    class_weights =  tf.Variable([2., 1., 1., 1., 1., 1.])\n    eps = K.epsilon()\n    \n    y_pred = K.clip(y_pred, eps, 1.0-eps)\n\n    out = -(         y_true  * K.log(      y_pred) * class_weights\n            + (1.0 - y_true) * K.log(1.0 - y_pred) * class_weights)\n    \n    return K.mean(out, axis=-1)\n####\ndef weighted_log_loss_V2(y_true, y_pred):\n    class_weights =  tf.constant([2., 1., 1., 1., 1., 1.])\n    \n    eps = tf.keras.backend.epsilon()\n    y_pred = tf.clip_by_value(y_pred, eps, 1.0-eps)\n\n    out = -(         y_true  * tf.math.log(      y_pred) * class_weights\n            + (1.0 - y_true) * tf.math.log(1.0 - y_pred) * class_weights)\n    \n    return tf.reduce_mean(out, axis=-1)\n\n\ndef _normalized_weighted_average(arr, weights=None):\n    if weights is not None:\n        scl = K.sum(weights)\n        weights = K.expand_dims(weights, axis=1)\n        return K.sum(K.dot(arr, weights), axis=1) / scl\n    return K.mean(arr, axis=1)\n\n\ndef weighted_loss(y_true, y_pred):\n\n    class_weights = tf.constant([2., 1., 1., 1., 1., 1.])\n    eps = tf.keras.backend.epsilon()\n    y_pred = tf.clip_by_value(y_pred, eps, 1.0-eps)\n\n    loss = -(        y_true  * tf.math.log(      y_pred)\n            + (1.0 - y_true) * tf.math.log(1.0 - y_pred))\n    \n    loss_samples = _normalized_weighted_average(loss, class_weights)\n    return tf.reduce_mean(loss_samples)\n\n\ndef weighted_log_loss_metric(trues, preds):\n    class_weights = [2., 1., 1., 1., 1., 1.]\n    \n    epsilon = 1e-7\n    \n    preds = np.clip(preds, epsilon, 1-epsilon)\n    loss = trues * np.log(preds) + (1 - trues) * np.log(1 - preds)\n    loss_samples = np.average(loss, axis=1, weights=class_weights)\n\n    return - loss_samples.mean()\n\n","metadata":{"execution":{"iopub.status.busy":"2024-01-28T11:14:13.257325Z","iopub.execute_input":"2024-01-28T11:14:13.257703Z","iopub.status.idle":"2024-01-28T11:14:13.272781Z","shell.execute_reply.started":"2024-01-28T11:14:13.257662Z","shell.execute_reply":"2024-01-28T11:14:13.272067Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Evaluation\nparams_test = {'dim':(224,224,3),\n         'batch_size':1,\n         'n_classes':6,\n         'n_channels':0,\n         'shuffle':False}\n\ntest_generator = DataGenerator(partition['test'], labels, **params_test)\ntest_pred = loaded_model.predict(test_generator,verbose=1)\npredicted_classes = tf.argmax(test_pred, axis=1)","metadata":{"execution":{"iopub.status.busy":"2024-01-28T11:14:38.583586Z","iopub.execute_input":"2024-01-28T11:14:38.58393Z","iopub.status.idle":"2024-01-28T11:15:21.63686Z","shell.execute_reply.started":"2024-01-28T11:14:38.5839Z","shell.execute_reply":"2024-01-28T11:15:21.636169Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Evaluation\nparams_test = {'dim':(224,224,3),\n         'batch_size':1,\n         'n_classes':6,\n         'n_channels':0,\n         'shuffle':False}\n\ntest_generator = DataGenerator(partition['test'], labels, **params_test)\ntest_pred = loaded_model.predict(test_generator,verbose=1)\npredicted_classes = tf.argmax(test_pred, axis=1)","metadata":{"execution":{"iopub.status.busy":"2024-01-28T06:00:00.7817Z","iopub.execute_input":"2024-01-28T06:00:00.782014Z","iopub.status.idle":"2024-01-28T06:00:46.114115Z","shell.execute_reply.started":"2024-01-28T06:00:00.781986Z","shell.execute_reply":"2024-01-28T06:00:46.113381Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(len(partition['test']))\npredicted_classes = tf.squeeze(predicted_classes).numpy()\n\nprint(len(predicted_classes))\n\n#total_list = np.concatenate([label for label in test_generator.labels.values()])\n\n\n#print(type(test_generator.labels[10]))\ntotal_list = np.concatenate(test_generator.labels)\ntotal_list = total_list[:-1]\nprint(len(total_list))\n\n\nfrom sklearn.metrics import accuracy_score\nfrom sklearn.metrics import multilabel_confusion_matrix, classification_report\n\naccuracy = accuracy_score(total_list, predicted_classes)\nprint(\"Accuracy:\", accuracy)\nconfusion_matrix = multilabel_confusion_matrix(total_list, predicted_classes)\nprint(\"Confusion Matrix:\")\nprint(confusion_matrix)\nclassification_report = classification_report(total_list, predicted_classes, target_names=['Any', 'Epidural', 'Intraparenchymal', 'Intraventricular', 'Subarachnoid', 'Subdural'])\nprint(\"Classification Report:\")\nprint(classification_report)","metadata":{"execution":{"iopub.status.busy":"2024-01-28T03:45:55.186219Z","iopub.execute_input":"2024-01-28T03:45:55.186616Z","iopub.status.idle":"2024-01-28T03:45:55.24456Z","shell.execute_reply.started":"2024-01-28T03:45:55.186581Z","shell.execute_reply":"2024-01-28T03:45:55.243072Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(len(partition['test']))\nprediction_with_treshold = []\n\ntreshold = 0.1\n\nfor sample in test_pred:\n    prediction_with_treshold.append([1 if i>=treshold else 0 for i in sample ] )\nprediction_with_treshold = np.array(prediction_with_treshold)\nprint(len(prediction_with_treshold))\n\nprint(type(test_generator.true_labels[10]))\ntotal_list = np.concatenate(test_generator.true_labels)\ntotal_list = total_list[:-1, :]\nprint(len(total_list))\n\nfrom sklearn.metrics import accuracy_score\nfrom sklearn.metrics import multilabel_confusion_matrix, classification_report\n\naccuracy_score(total_list, prediction_with_treshold)\nprint(multilabel_confusion_matrix(total_list, prediction_with_treshold))\nprint(classification_report(total_list, prediction_with_treshold, target_names = ['Any', 'Epidural', 'Intraparenychemal','Intraventricular','Subarachnoid','Subdural']))","metadata":{"execution":{"iopub.status.busy":"2023-06-25T07:54:33.450128Z","iopub.execute_input":"2023-06-25T07:54:33.450506Z","iopub.status.idle":"2023-06-25T07:54:33.564538Z","shell.execute_reply.started":"2023-06-25T07:54:33.450467Z","shell.execute_reply":"2023-06-25T07:54:33.563675Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.metrics import average_precision_score\naverage_precision_score(total_list, test_pred, average='micro', pos_label=1, sample_weight=None)","metadata":{"execution":{"iopub.status.busy":"2024-01-28T06:05:23.097173Z","iopub.execute_input":"2024-01-28T06:05:23.097632Z","iopub.status.idle":"2024-01-28T06:05:23.101666Z","shell.execute_reply.started":"2024-01-28T06:05:23.097575Z","shell.execute_reply":"2024-01-28T06:05:23.100713Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def sigmoid_window(dcm, window_center, window_width, U=1.0, eps=(1.0 / 255.0)):\n    img = dcm.pixel_array\n    img = cp.array(np.array(img))\n    _, _, intercept, slope = get_windowing(dcm)\n    img = img * slope + intercept\n    ue = cp.log((U / eps) - 1.0)\n    W = (2 / window_width) * ue\n    b = ((-2 * window_center) / window_width) * ue\n    z = W * img + b\n    img = U / (1 + cp.power(np.e, -1.0 * z))\n    img = (img - cp.min(img)) / (cp.max(img) - cp.min(img))\n    return cp.asnumpy(img)\ndef get_first_of_dicom_field_as_int(x):\n    #get x[0] as in int is x is a 'pydicom.multival.MultiValue', otherwise get int(x)\n    if type(x) == pydicom.multival.MultiValue:\n        return int(x[0])\n    else:\n        return int(x)\n\ndef get_windowing(data):\n    dicom_fields = [data[('0028','1050')].value, #window center\n                    data[('0028','1051')].value, #window width\n                    data[('0028','1052')].value, #intercept\n                    data[('0028','1053')].value] #slope\n    return [get_first_of_dicom_field_as_int(x) for x in dicom_fields]","metadata":{"execution":{"iopub.status.busy":"2024-01-28T11:18:14.057049Z","iopub.execute_input":"2024-01-28T11:18:14.057431Z","iopub.status.idle":"2024-01-28T11:18:14.06733Z","shell.execute_reply.started":"2024-01-28T11:18:14.057395Z","shell.execute_reply":"2024-01-28T11:18:14.066506Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"execution":{"iopub.status.busy":"2024-02-11T12:42:15.824238Z","iopub.execute_input":"2024-02-11T12:42:15.824633Z","iopub.status.idle":"2024-02-11T12:42:16.41619Z","shell.execute_reply.started":"2024-02-11T12:42:15.8246Z","shell.execute_reply":"2024-02-11T12:42:16.415397Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# SUBMITTER UNIT\n\ntest_csv = \"../input/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/stage_2_sample_submission.csv\"\ntest_dir = \"../input/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/stage_2_test\"\nTEST_DIR = \"stage_2_test/\"\ntest_df = pd.read_csv(test_csv)\ntest_df.head()\n\ntestdf = test_df.ID.str.rsplit(\"_\", n=1, expand=True)\ntestdf = testdf.rename({0: \"id\", 1: \"subtype\"}, axis=1)\ntestdf.loc[:, \"label\"] = 0\n\ntestdf = pd.pivot_table(testdf, index=\"id\", columns=\"subtype\", values=\"label\")\n\ndef preprocess(file,type=\"WINDOW\",DIR=test_images_dir):\n    dcm = pydicom.dcmread(test_images_dir+file+\".dcm\")\n    if type == \"WINDOW\":\n        window_center , window_width, intercept, slope = get_windowing(dcm)\n        w = window_image(dcm, window_center, window_width)\n        win_img = np.repeat(w[:, :, np.newaxis], 3, axis=2)\n        #return win_img\n    elif type == \"SIGMOID\":\n        window_center , window_width, intercept, slope = get_windowing(dcm)\n        test_img = dcm.pixel_array\n        w = sigmoid_window(dcm, window_center, window_width)\n        win_img = np.repeat(w[:, :, np.newaxis], 3, axis=2)\n        #return win_img\n    elif type == \"BSB\":\n        win_img = bsb_window(dcm)\n        #return win_img\n    elif type == \"SIGMOID_BSB\":\n        win_img = sigmoid_bsb_window(dcm)\n    elif type == \"GRADIENT\":\n        win_img = rainbow_window(dcm)\n        #return win_img\n    else:\n        win_img = dcm.pixel_array\n    resized = cv2.resize(win_img,(224,224))\n    return resized\n\nclass DataLoader(Sequence):\n    def __init__(self, dataframe,\n                 batch_size,\n                 shuffle,\n                 input_shape,\n                 num_classes=6,\n                 steps=None,\n                 prep=\"SIGMOID\"):\n        \n        self.data_ids = dataframe.index.values\n        self.dataframe = dataframe\n        self.batch_size = batch_size\n        self.shuffle = shuffle\n        self.input_shape = input_shape\n        self.num_classes = num_classes\n        self.current_epoch=0\n        self.prep = prep\n        self.steps=steps\n        if self.steps is not None:\n            self.steps = np.round(self.steps/3) * 3\n            self.undersample()\n        \n    def undersample(self):\n        part = np.int(self.steps/3 * self.batch_size)\n        zero_ids = np.random.choice(self.dataframe.loc[self.dataframe[\"any\"] == 0].index.values, size=5000, replace=False)\n        hot_ids = np.random.choice(self.dataframe.loc[self.dataframe[\"any\"] == 1].index.values, size=5000, replace=True)\n        self.data_ids = list(set(zero_ids).union(hot_ids))\n        np.random.shuffle(self.data_ids)\n        \n    # defines the number of steps per epoch\n    def __len__(self):\n        if self.steps is None:\n            return np.int(np.ceil(len(self.data_ids) / np.float(self.batch_size)))\n        else:\n            return 3*np.int(self.steps/3) \n    \n    # at the end of an epoch: \n    def on_epoch_end(self):\n        # if steps is None and shuffle is true:\n        if self.steps is None:\n            self.data_ids = self.dataframe.index.values\n            if self.shuffle:\n                np.random.shuffle(self.data_ids)\n        else:\n            self.undersample()\n        self.current_epoch += 1\n    \n    # should return a batch of images\n    def __getitem__(self, item):\n        # select the ids of the current batch\n        current_ids = self.data_ids[item*self.batch_size:(item+1)*self.batch_size]\n        X, y = self.__generate_batch(current_ids)\n        return X, y\n    \n    # collect the preprocessed images and targets of one batch\n    def __generate_batch(self, current_ids):\n        X = np.empty((self.batch_size, *self.input_shape, 3))\n        y = np.empty((self.batch_size, self.num_classes))\n        for idx, ident in enumerate(current_ids):\n            # Store sample\n            #image = self.preprocessor.preprocess(ident) \n            image = preprocess(ident,self.prep)\n            X[idx] = image\n            # Store class\n            y[idx] = self.__get_target(ident)\n        return X, y\n    \n    # extract the targets of one image id:\n    def __get_target(self, ident):\n        targets = self.dataframe.loc[ident].values\n        return targets\n    \ndef turn_pred_to_dataframe(data_df, pred):\n    df = pd.DataFrame(pred, columns=data_df.columns, index=data_df.index)\n    df = df.stack().reset_index()\n    df.loc[:, \"ID\"] = df.id.str.cat(df.subtype, sep=\"_\")\n    df = df.drop([\"id\", \"subtype\"], axis=1)\n    df = df.rename({0: \"Label\"}, axis=1)\n    return df\n\ndef weighted_loss(y_true, y_pred):\n    \n    class_weights = tf.constant([2., 1., 1., 1., 1., 1.])\n    \n    eps = tf.keras.backend.epsilon()\n    \n    y_pred = tf.clip_by_value(y_pred, eps, 1.0-eps)\n\n    loss = -(        y_true  * tf.math.log(      y_pred)\n            + (1.0 - y_true) * tf.math.log(1.0 - y_pred))\n    \n    loss_samples = _normalized_weighted_average(loss, class_weights)\n    \n    return tf.reduce_mean(loss_samples)\n\nimport keras.losses\n\ntest_dataloader = DataLoader(testdf,32,shuffle=False,input_shape=(224,224),prep=\"SIGMOID\")\n\ntest_pred = loaded_model.predict(test_dataloader,verbose=1)\n\npred = test_pred[0:testdf.shape[0]]\nprint(len(pred))","metadata":{"execution":{"iopub.status.busy":"2024-01-28T11:18:15.206215Z","iopub.execute_input":"2024-01-28T11:18:15.206552Z","iopub.status.idle":"2024-01-28T11:18:19.336613Z","shell.execute_reply.started":"2024-01-28T11:18:15.206523Z","shell.execute_reply":"2024-01-28T11:18:19.334514Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#test_generator = DataGenerator(partition['test'], labels, **params)\n\n#print(\"Test Accuracy: \", model.evaluate(test_generator))","metadata":{"execution":{"iopub.status.busy":"2024-01-28T06:56:08.536526Z","iopub.execute_input":"2024-01-28T06:56:08.536827Z","iopub.status.idle":"2024-01-28T06:56:08.540433Z","shell.execute_reply.started":"2024-01-28T06:56:08.536797Z","shell.execute_reply":"2024-01-28T06:56:08.539467Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"testdf.head()\n","metadata":{"execution":{"iopub.status.busy":"2024-01-28T11:18:40.380568Z","iopub.execute_input":"2024-01-28T11:18:40.381005Z","iopub.status.idle":"2024-01-28T11:18:40.394164Z","shell.execute_reply.started":"2024-01-28T11:18:40.380961Z","shell.execute_reply":"2024-01-28T11:18:40.39337Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install cupy","metadata":{"execution":{"iopub.status.busy":"2024-01-28T04:34:21.263947Z","iopub.execute_input":"2024-01-28T04:34:21.264324Z","iopub.status.idle":"2024-01-28T04:34:29.576843Z","shell.execute_reply.started":"2024-01-28T04:34:21.264295Z","shell.execute_reply":"2024-01-28T04:34:29.575931Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nimport cv2\nimport pydicom\nfrom tensorflow.keras.models import load_model\nimport cupy as cp\n\n\ndef preprocess_image(file_path, type=\"SIGMOID\", desired_size=(224, 224)):\n    dcm = pydicom.dcmread(file_path)\n\n    if type == \"WINDOW\":\n        window_center, window_width, intercept, slope = get_windowing(dcm)\n        w = window_image(dcm, window_center, window_width)\n        img = np.repeat(w[:, :, np.newaxis], 3, axis=2)\n    elif type == \"SIGMOID\":\n        window_center, window_width, intercept, slope = get_windowing(dcm)\n        w = sigmoid_window(dcm, window_center, window_width)\n        img = np.repeat(w[:, :, np.newaxis], 3, axis=2)\n    elif type == \"BSB\":\n        img = bsb_window(dcm)\n    elif type == \"SIGMOID_BSB\":\n        img = sigmoid_bsb_window(dcm)\n    elif type == \"GRADIENT\":\n        img = rainbow_window(dcm)\n    else:\n        img = dcm.pixel_array\n\n    resized_img = cv2.resize(img, desired_size, interpolation=cv2.INTER_LINEAR)\n    return resized_img\n\ndef turn_pred_to_dataframe(data_df, pred, single_label=True):\n    if single_label:\n        df = pd.DataFrame(pred.reshape(1, -1), columns=data_df.columns, index=[0])\n    else:\n        df = pd.DataFrame(pred, columns=data_df.columns, index=data_df.index)\n\n    df = df.stack().reset_index()\n    df[\"ID\"] = df[\"level_0\"].astype(str) + \"_\" + df[\"subtype\"].astype(str)\n    df = df.drop([\"level_0\", \"subtype\"], axis=1)\n    df = df.rename({0: \"Label\"}, axis=1)\n    return df\n    \ndef predict_single_image(model, image_path):\n    # Preprocess the image\n    preprocessed_image = preprocess_image(image_path, type=\"SIGMOID\")  # You can choose the desired preprocessing type\n\n    # Reshape the image to match the model's expected input shape\n    input_image = preprocessed_image.reshape((1, 224, 224, 3))\n\n    # Make prediction\n    predictions = model.predict(input_image)\n\n    # Convert predictions to DataFrame\n    prediction_df = turn_pred_to_dataframe(testdf, predictions)\n\n    # Get the predicted labels\n    predicted_labels = np.argmax(predictions, axis=1)\n    \n    # Display the result\n    if predicted_labels[0] == 1:\n        print(\"Hemorrhage Detected!\")\n        hemorrhage_type = prediction_df.iloc[0][\"subtype\"]\n        print(\"Hemorrhage Type:\", hemorrhage_type)\n    else:\n        print(\"No Hemorrhage Detected.\")\n\n# Load the trained model\nmodel_path='/kaggle/input/ich_classification/tensorflow2/slug/1/my_model.h5'\nmodel = load_model(model_path)\n\n# Provide the path to the CT scan image you want to predict\nimage_path=\"/kaggle/input/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/stage_2_train/ID_0005b2d86.dcm\"\n# Make predictions\npredict_single_image(model, image_path)\n","metadata":{"execution":{"iopub.status.busy":"2024-01-28T11:38:16.703041Z","iopub.execute_input":"2024-01-28T11:38:16.703446Z","iopub.status.idle":"2024-01-28T11:38:22.318841Z","shell.execute_reply.started":"2024-01-28T11:38:16.703414Z","shell.execute_reply":"2024-01-28T11:38:22.318069Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pydicom\nimport numpy as np\nimport cv2\nfrom PIL import Image\n\ndef convert_image_to_dicom(image_path, output_dicom_path, patient_name=\"Anonymous\"):\n    # Read the image\n    image = cv2.imread(image_path)\n    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n\n    # Create a DICOM dataset\n    ds = pydicom.Dataset()\n\n    # Set DICOM metadata\n    ds.PatientName = patient_name\n    ds.ImageType = [\"ORIGINAL\", \"PRIMARY\", \"OTHER\"]\n    ds.SOPClassUID = pydicom.uid.ExplicitVRLittleEndian\n    ds.SOPInstanceUID = pydicom.uid.generate_uid()\n\n    # Set image pixel data\n    ds.PixelData = image.tobytes()\n    ds.Rows, ds.Columns, _ = image.shape\n    ds.BitsStored = 8\n    ds.BitsAllocated = 8\n    ds.SamplesPerPixel = 3\n    ds.HighBit = 7\n    ds.PhotometricInterpretation = \"RGB\"\n\n    # Save the DICOM file\n    ds.save_as(output_dicom_path)\n\n# Example usage:\njpg_image_path = 'path_to_your_input_image.jpg'\noutput_dicom_path = 'path_to_output_dicom_file.dcm'\n\nconvert_image_to_dicom(jpg_image_path, output_dicom_path)\n","metadata":{},"execution_count":null,"outputs":[]}]}