Разница между функциями "im2uint8" (в MATLAB) и "bytescale" (в Python) - PullRequest
0 голосов
/ 09 октября 2018

Я хочу преобразовать изображение DICOM из int16 в uint8.Я сделал это на Python, используя Z_axis = bytescale(img), но это дает результаты, отличные от использования im2uint8 в MATLAB.В MATLAB минимальные и максимальные значения изображения DICOM после преобразования в uint8 с использованием im2uint8 равны (124, 136), соответственно.Но эти значения в Python после преобразования с использованием bytescale равны (0, 255).

Код Python:

for person in range(0, len(dirs1)):
if not os.path.exists(os.path.join(directory, dirs1[person])):
    Pathnew = os.path.join(directory, dirs1[person])
    os.makedirs(Pathnew)
    for root, dirs, files in os.walk(os.path.join(path, dirs1[person])):
        dcmfiles = [_ for _ in files if _.endswith('.dcm')]
        for dcmfile in dcmfiles:
            dcm_image = pydicom.read_file(os.path.join(root, dcmfile))
            img = dcm_image.pixel_array
            Z_axis = bytescale(img)  
            minVal = Z_axis.min()
            maxVal = Z_axis.max()

Код Matlab:

for j = 1 : length(Files2)
    img = dicomread([galleryPath Files2(j).name]);
    Z_axis = im2uint8(img);
    minVal = min(min(Z_axis));
    maxVal = max(max(Z_axis));

Изображениявыглядят одинаково при отображении, но числовые значения не.Итак, функции bytescale и im2uint8 равны или нет?Если нет, я хочу получить результаты вроде im2uint8 в Python.Какую функцию выбрать (особенно для изображений DICOM)?

Например, в MATLAB после чтения файла DICOM:

img = dicomread([galleryPath Files2(j).name]);
img = [ -1024,   -1024,   16;
        -1024,       8,   11;
           17,       5,    8];

Но в Python то же изображение после чтения:

dcm_image = pydicom.read_file(os.path.join(root, dcmfile))
img = dcm_image.pixel_array
img = array([[ -1024,    -1024,   27],
             [ -1024,       27,   26],
             [    24,       26,   23]])

Я не знаю, почему они отличаются в MATLAB и Python.После применения im2uint8 в MATLAB, вывод:

Z_axis = im2uint8(img)
Z_axis =
 3×3 uint8 matrix
   124    124   128
   124    128   128
   128    128   128

А после применения bytescale в Python, вывод:

bytescale(img)
Z_axis = 
    array([[0,    0,   83],
           [0,   83,   83],
           [83,  83,   83]], dtype=uint8)

Ответы [ 2 ]

0 голосов
/ 09 октября 2018

Да, это отличается

bytescale преобразовать матрицу в uint8, нормализуя все значения на самое высокое и самое низкое (самое высокое 255 и самое низкое 0)

img = array([[ 91.06794177,   3.39058326,  84.4221549 ],
                 [ 73.88003259,  80.91433048,   4.88878881],
                 [ 51.53875334,  34.45808177,  27.5873488 ]])

bytescale(img)

array([[255,   0, 236],
       [205, 225,   4],
       [140,  90,  70]], dtype=uint8)

в Matlab im2uint8полезно конвертировать двойные изображения в uint8.Двойные изображения имеют диапазон от 0 до 1. Чтобы сделать то же самое в кулаке Matlab, вам необходимо преобразовать изображение в диапазоне значений 0-1 (double), нормализуя данные, а затем применить im2uint8.

I = [ 91.06794177,   3.39058326,  84.4221549;
    73.88003259,  80.91433048,   4.88878881;
    51.53875334,  34.45808177,  27.5873488];

Inorm = (I - min(I(:))) ./ ( max(I(:)) - min(I(:)) );

I2 = im2uint8(Inorm);

Затем вы получитето же изображение:

I2 =

  3×3 uint8 matrix

   255     0   236
   205   225     4
   140    90    70
0 голосов
/ 09 октября 2018

Во-первых, что касается проблемы с чтением данных, я бы предложил использовать dcmread в Python, поскольку это дало мне те же точные данные, что и dicomread в MATLAB.

Во-вторых, в MATLAB, когда im2uint8 преобразует int16 значения, он масштабирует их, принимая минимальные и максимальные значения для данных, равные -32768 и 32767 соответственно (т.е. минимальное имаксимальные значения, представляемые int16).Чтобы bytescale вел себя одинаково, я считаю, что вам необходимо установить аргументы cmin и cmax соответственно (поскольку в противном случае они по умолчанию будут data.min() и data.max() соответственно).Это должно повторять результаты im2uint8 в Python:

Z_axis = bytescale(img.astype(float), cmin=-32768, cmax=32767)

Примечание: преобразование данных в плавающее в первую очередь необходимо, чтобы учесть очевидную ошибку в bytescale, которая не обрабатывает целочисленную арифметикуправильно (найдено благодаря Cris Luengo ).

...