Исследование мазка периферической крови - недорогой, но неизбежный шаг, который помогает диагностировать несколько критических заболеваний, таких как лейкемия, гемолитическая анемия и тромбоцитопения. Традиционно обученные лаборанты или практикующие врачи исследовали мазки крови вручную с помощью микроскопа. Недавно были разработаны автоматизированные системы и процессы, помогающие более эффективно и широко анализировать мазки крови в контексте стадии, спецификаций и масштаба. Весь процесс состоит из следующих этапов: сегментация области интереса (ROI), идентификация и характеристика параметров ROI для болезненного / здорового состояния, интерпретация стадии, характеристик и шкалы. Следовательно, сегментация ROI является одним из основных шагов на пути к обнаружению болезненного состояния по мазкам периферической крови. Это процесс отделения определенной области от набора отдельных областей, присутствующих на изображении. Здесь, в этом блоге, обсуждался конкретный метод, в котором один из параметров крови сегментируется с помощью нечеткой меры дивергенции при выборе порога в автоматическом режиме.
- Каковы параметры крови и почему они необходимы для выявления заболевания?
Кровь содержит три типа клеток: эритроциты (эритроциты), лейкоциты (лейкоциты) и тромбоциты. Нормальный мазок крови описывается двумя вещами: достаточное количество клеток и клетки имеют нормальный вид. Но аномальный мазок крови считается аномальным, если размер, форма, цвет или количество клеток в крови являются ненормальными. Аномальные результаты могут отличаться в зависимости от типа пораженных клеток крови. Заболевание, связанное с кровью, состоит из трех типов расстройств.
- Нарушения эритроцитов: железодефицитная анемия, серповидно-клеточная анемия, гемолитико-уремический синдром, красная полицитемия.
- Нарушения лейкоцитов: острый или хронический лейкоз, ВИЧ, вирусная инфекция гепатита С, паразитарные инфекции, грибковые инфекции (кандидоз), другие лимфопролиферативные заболевания (миелома).
- Нарушения тромбоцитов: миелопролиферативные нарушения, тромбоцитопения.
Клиническое исследование, касающееся формы, размера, цвета, текстуры и количества этих параметров крови, помогает выявить заболевание / здоровое состояние.
Пример: сегментация лейкоцитов (ROI) из мазков крови (микроскопическое изображение)
На протяжении многих лет нечеткие методы используются как один из основных технических подходов для выделения объекта из фона. Нечеткая дивергенция - это такой метод, который имеет дело с распределением априорной вероятности объекта и фона на основе его гистограммы уровней серого изображения. В таких ситуациях порог выбирается из максимизации информационного содержания априорного распределения вероятностей в классе объекта-фон на гистограмме уровней серого.
Действия, которые необходимо выполнить:
Шаг 1. Представьте серое изображение как нечеткое
Нечеткое изображение - это комбинация значений серого и соответствующих им значений принадлежности. Пусть нечеткое изображение A размером M × N и с уровнями серого L определяется как комбинация уровней серого и его значение принадлежности (i, j) пиксель. Значение принадлежности конкретного пикселя должно быть в пределах этого интервала [0,1]. Частота определенного уровня серого определяется количеством вхождений в это конкретное изображение. Сначала на основе определенного порогового значения в (0, 255) вычисляется средний уровень серого фона и области объекта. Во-вторых, для вычисления значения принадлежности (членство гаммы) учитывалось абсолютное значение расстояния между средним значением области, к которой принадлежит пиксель, и уровнем серого этого пикселя.
Шаг 2. Различение объекта и фона внутри нечеткого изображения
Рассчитайте фон и дискриминацию объектов на основе значений принадлежности. Рассматривайте объекты изображения и фон как отдельные изображения, и, следовательно, мы можем вычислить различие между ними. Количество информации об объекте и фоне в определенной точке (i, j) на изображении обозначается как,
ехр (memOb [i, j] -memB [i, j])
* memOb = принадлежность к объекту, memB = принадлежность к фону
Шаг 3: Расчет нечеткого расхождения между двумя нечеткими изображениями с использованием экспоненциальной энтропии Шеннона
Основываясь на экспоненциальной энтропии Шеннона, мы можем сформулировать расхождение между объектом и фоном:
Шаг 4. Найдите пороговое значение, которое дает минимальное значение расхождения.
Шаг 5. Используйте это пороговое значение, чтобы отделить объект от фона.
Шаг 6. Восстановите изображение для сегментированной части изображения.
Полученные результаты:
Код на Python (блокнот jupyter):
# import all libraries import numpy as np from scipy import signal import cv2 import pip import matplotlib.pyplot as plt %matplotlib inline import math from math import e from scipy.signal import find_peaks # this function helps to find out the mean value for onject and background regions separately # this function helps to find out the mean value for onject and background regions separately def mean_obj_back(img, threshold): Y = img.shape[0]*img.shape[1] # setting the max and min of histogram peaks within which threshold point to be found fmax = 250 fmin = 180 const = 1/(fmax-fmin) # calculate the histogram hist,bins = np.histogram(img.ravel(),256,[0,256]) # set an arbitrary threshold point th = threshold # initialize the parameters s0 = 0 s1 = 0 s00 = 0 s11 = 0 s = 0 s2 = 0 for f in range(0,th): s = bins[f]*hist[f] num = s0 + s den = s1 + hist[f] s0 = num s1 = den # mue of object mueOb = round(num/den) for f in range(th,256): s2 = bins[f]*hist[f] numb = s00 + s2 s00 = numb denb = s11 + hist[f] s11 = denb # mue of background mueB = round(numb/denb) return mueOb, mueB,const # make a gray image to a fuzzy image def fuzzyImage(img,th,mueOb,mueB,const): for i in range(0, img.shape[0]): for j in range(0, img.shape[1]): if (img[i,j]<th): f = (-const) * abs(img[i,j] - mueOb) mem[i,j] = np.exp(f) else: f1 = (-const) * abs(img[i,j] - mueB) mem[i,j] = np.exp(f1) return mem # calculation of fuzzy divergence measure def fuzzydivergence(mem): u1 = 0 for i in range(0, mem.shape[0]): for j in range(0, mem.shape[1]): p1 = (np.exp(mem[i,j]-1)) p2 = (np.exp(1-mem[i,j])) h = (2 -((mem[i,j]+1)*p1)-(1-1+mem[i,j])*p2) + u1 u1 = h return h # calculate the divergence measurement between image object and image background def divergence(img): div_vec = [] threshold =[] fmax = 250 fmin = 180 for th in range(fmin,fmax): const = 1/(fmax-fmin) mueOb = mean_obj_back(img, th)[0] mueB = mean_obj_back(img, th)[1] mem = np.zeros((img.shape[0], img.shape[1])) p = th mem = fuzzyImage(img,p,mueOb,mueB,const) h = fuzzydivergence(mem) Y = img.shape[0] * img.shape[1] div = h/Y div_vec.append(div) threshold.append(th) return div_vec,threshold # area based filter that will helps to filter out ROI from rest of the image def area_based_filter(binary): #make binary image as integer type binary = np.array(binary, dtype=np.uint8) #find all your connected components (white blobs in your image) nb_components, output, stats, centroids = cv2.connectedComponentsWithStats(binary, connectivity=8) #connectedComponentswithStats yields every seperated component with information on each of them, such as size #the following part is just taking out the background which is also considered a component, but most of the time we don't want that. sizes = stats[1:, -1]; nb_components = nb_components - 1 min_size = max(sizes) # minimum size of particles we want to keep (number of pixels) #here, it's a fixed value, but you can set it as you want, eg the mean of the sizes or whatever #your answer image result = np.zeros((output.shape)) #for every component in the image, you keep it only if it's above min_size for i in range(0, nb_components): if sizes[i] >= min_size: result[output == i + 1] = 255 return result # make binary of image def binarize_image(img,threshold_value): binary = np.zeros((img.shape[0], img.shape[1])) for i in range(0, img.shape[0]): for j in range(0, img.shape[1]): if (img[i,j] < threshold_value): binary[i,j] = 255 else: binary[i,j] = 0 return binary # fill the segmented region holes def img_fill(im_in): # n = binary image threshold #th, im_th = cv2.threshold(im_in, n, 255, cv2.THRESH_BINARY); im_th = im_in.astype('uint8') # Copy the thresholded image. im_floodfill = im_th.copy() # Mask used to flood filling. # Notice the size needs to be 2 pixels than the image. h, w = im_th.shape[:2] mask = np.zeros((h + 2, w + 2), np.uint8) # Floodfill from point (0, 0) cv2.floodFill(im_floodfill, mask, (0, 0), 255); # Invert floodfilled image im_floodfill_inv = cv2.bitwise_not(im_floodfill) # Combine the two images to get the foreground. fill_image = im_th | im_floodfill_inv return fill_image Path_to_image = '.../Original_Image.jpg' # read image from directory path img = cv2.imread(path_to_image) # make it gray img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) # get the histogram hist,bins = np.histogram(img.ravel(),256,[0,256]) # define a membership mask for processing mem = np.zeros((img.shape[0], img.shape[1])) # find out the divergence measure for segmentation diver,thr = divergence(img) # find out the minimum divergence value min_diver = min(diver) index = [i for i,x in enumerate(diver) if x == min_diver] val = index.pop() # find out the threshold value for which divergence value is minimum threshold_value = thr[val] # binarize the image using the threshold value binary = binarize_image(img, threshold_value) # set an area based filter to get region of interest (ROI) area_filtered_image = area_based_filter(binary) # fill up segmented area for reconstruction of original ROI fill_img = img_fill(area_filtered_image) # remap segmented ROI with original gray image ROI out = fill_img.copy() out[fill_img == 255] = img[fill_img == 255] ## Plot the results fig, axes = plt.subplots(ncols= 2, figsize=(10, 5)) ax = axes.ravel() ax[0].imshow(img, cmap=plt.cm.gray) ax[0].set_title('Original Image') ax[0].axis('off') ax[1].plot(diver) ax[1].set_title('Divergence Plot') ax[1].axis('on') plt.show() fig, axes = plt.subplots(ncols= 3, figsize=(15, 8)) ax = axes.ravel() ax[0].imshow(binary, cmap=plt.cm.gray) ax[0].set_title('Thresholded') ax[1].imshow(fill_img, cmap=plt.cm.gray) ax[1].set_title('Segmented_Leukocyte') ax[2].imshow(out, cmap=plt.cm.gray) ax[2].set_title('Reconstructed_Leukocyte ') for a in ax: a.axis('off') plt.show()
Ссылка: Для справки следуйте моей статье о Micron, Elsevier.
Выводы
Здоровье измеряется по крови путем проверки различных параметров крови. Если измерения параметров крови отклоняются от нормы или противоречат друг другу, это отразится на опасности для вашего здоровья. Вот почему так важно знать об общих заболеваниях крови, которые могут вызывать основные проблемы со здоровьем. Общие заболевания крови включают анемию, нарушения свертываемости крови, такие как гемофилия, сгустки крови и рак крови, такие как лейкемия, лимфома и миелома. Даже паразитарные инфекции, такие как малярия, также идентифицируются по параметрам крови. Вместо того, чтобы делать ручную интерпретацию, автоматическое определение характеристик мазков крови помогает оптимизировать ручные ошибки, сокращает ручные усилия и сводит к минимуму использование дорогостоящих ресурсов и химикатов. Впредь в следующих друг за другом блогах я буду подробно объяснять, как параметры крови приведут к обнаружению связанных с кровью нарушений со значимыми характеристиками, связанными с болезненными состояниями. До скорого.