Исследование мазка периферической крови - недорогой, но неизбежный шаг, который помогает диагностировать несколько критических заболеваний, таких как лейкемия, гемолитическая анемия и тромбоцитопения. Традиционно обученные лаборанты или практикующие врачи исследовали мазки крови вручную с помощью микроскопа. Недавно были разработаны автоматизированные системы и процессы, помогающие более эффективно и широко анализировать мазки крови в контексте стадии, спецификаций и масштаба. Весь процесс состоит из следующих этапов: сегментация области интереса (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.

Мадхумала Гош, Дев Кумар Дас, Чандан Чакраборти, Аджой К. Рэй, Автоматическое распознавание лейкоцитов с использованием нечеткой дивергенции, Micron Vol-41, Issue -7, October 2010, Pages 840–846.

Выводы

Здоровье измеряется по крови путем проверки различных параметров крови. Если измерения параметров крови отклоняются от нормы или противоречат друг другу, это отразится на опасности для вашего здоровья. Вот почему так важно знать об общих заболеваниях крови, которые могут вызывать основные проблемы со здоровьем. Общие заболевания крови включают анемию, нарушения свертываемости крови, такие как гемофилия, сгустки крови и рак крови, такие как лейкемия, лимфома и миелома. Даже паразитарные инфекции, такие как малярия, также идентифицируются по параметрам крови. Вместо того, чтобы делать ручную интерпретацию, автоматическое определение характеристик мазков крови помогает оптимизировать ручные ошибки, сокращает ручные усилия и сводит к минимуму использование дорогостоящих ресурсов и химикатов. Впредь в следующих друг за другом блогах я буду подробно объяснять, как параметры крови приведут к обнаружению связанных с кровью нарушений со значимыми характеристиками, связанными с болезненными состояниями. До скорого.