疟疾对许多发展中国家的医疗系统构成了沉重负担,并且是导致死亡的主要原因之一。在世界某些地区,疟疾是地方病,这意味着该疾病在该地区定期出现。因此,早期检测疟疾以挽救生命至关重要,这促使提高疟疾诊断的效率和速度。为此,专门的技术在抗击这一问题中显得至关重要。
在疟疾诊断中,快速诊断测试(RDT)和显微镜诊断是最常用的临床方法。RDT是一种有效且快速的工具,并且不需要训练有素的医疗专业人员。但是,RDT有一些缺点,如对热和湿度的敏感性以及与光学显微镜相比成本较高。显微镜诊断系统没有这些缺点,但它需要训练有素的显微镜操作员。最近,机器学习在医学领域引起了广泛关注。机器学习方法在疾病诊断中被证明是成功的。
本疟疾检测系统的主要目标是通过使用机器学习和图像处理自动化疟疾检测过程,解决现有系统中的挑战。
用于疟疾检测的数据集由“国立卫生研究院”提供,包含30000张细胞图像。该数据集可以从此处下载。数据集包括两个文件夹:测试和训练文件夹,分别包含测试和训练图像。此外,还有两个更多的文件夹——寄生文件夹包含疟疾感染的细胞图像,未感染文件夹包含正常细胞图像。由于有等量的细胞图像分布,因此不需要处理数据不平衡的问题,因此它对特定类别的偏见较小。
输入图像首先被处理以从RGB细胞图像中去除不需要的噪声。然后,预处理后的图像被输入到分割阶段。图像被分割以提取图像中的兴趣区域,得到分割后的图像。然后,将图像作为输入输入到特征提取阶段,输出将是特征向量。下一个阶段是分类阶段,输入将是特征向量,输出是分类标签,作为寄生和非寄生。
这是第一阶段。数据预处理的目的是清洁细胞图像。这个阶段将去除不需要的噪声。
kernel1 = np.ones((9,9),np.uint8)
clean1 = cv2.morphologyEx(image, cv2.MORPH_OPEN, kernel1)
这是第二阶段,图像被分割以提取图像中的兴趣区域。这里将使用两种图像分割技术,如下:
它用于通过图像阈值处理自动分割细胞图像。它返回一个单一的强度阈值,将像素分为两类。
import numpy as np
import cv2
from matplotlib import pyplot as plt
img = cv2.imread(r'C33P1thinF_IMG_20150619_114756a_cell_181.png')
b,g,r = cv2.split(img)
rgb_img = cv2.merge([r,g,b])
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
# noise removal
kernel = np.ones((2,2),np.uint8)
closing = cv2.morphologyEx(thresh,cv2.MORPH_CLOSE,kernel, iterations = 2)
# sure background area
sure_bg = cv2.dilate(closing,kernel,iterations=3)
# Finding sure foreground area
dist_transform = cv2.distanceTransform(sure_bg,cv2.DIST_L2,3)
# Threshold
ret, sure_fg = cv2.threshold(dist_transform,0.1*dist_transform.max(),255,0)
# Finding unknown region
sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(sure_bg,sure_fg)
# Marker labelling
ret, markers = cv2.connectedComponents(sure_fg)
# Add one to all labels so that sure background is not 0, but 1
markers = markers+1
# Now, mark the region of unknown with zero
markers[unknown==255] = 0
markers = cv2.watershed(img,markers)
img[markers == -1] = [255,0,0]
plt.subplot(211),plt.imshow(rgb_img)
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(212),plt.imshow(thresh, 'gray')
plt.title("Otsu's binary threshold"), plt.xticks([]), plt.yticks([])
plt.tight_layout()
plt.show()
Watershed segmentation是一种图像分割算法,它将图像分割成几个汇水盆地或区域。输入图像可以被分割成区域,概念上雨水会流入同一个湖泊,这将导致将图像分割成汇水盆地和分水岭线。
import numpy as np
import cv2
from matplotlib import pyplot as plt
img = cv2.imread(r'C33P1thinF_IMG_20150619_114756a_cell_181.png')
b,g,r = cv2.split(img)
rgb_img = cv2.merge([r,g,b])
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
plt.subplot(211),plt.imshow(closing, 'gray')
plt.title("morphologyEx:Closing:2x2"), plt.xticks([]), plt.yticks([])
plt.subplot(212),plt.imshow(sure_bg, 'gray')
plt.title("Dilation"), plt.xticks([]), plt.yticks([])
plt.tight_layout()
plt.show()
# Convolutional Neural Network
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout, Activation
image_gen = ImageDataGenerator(rotation_range=20,
width_shift_range=0.10,
height_shift_range=0.10,
rescale=1/255,
shear_range=0.1,
zoom_range=0.1,
horizontal_flip=True,
fill_mode='nearest')
model = Sequential()
model.add(Conv2D(filters=32, kernel_size=(3,3),input_shape=image_shape, activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(filters=64, kernel_size=(3,3),input_shape=image_shape, activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(filters=64, kernel_size=(3,3),input_shape=image_shape, activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(128))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation('sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
from tkinter import *
from tkinter import ttk
from tkinter import filedialog
class Root(Tk):
def __init__(self):
super(Root, self).__init__()
self.title("Python Tkinter Dialog Widget")
self.minsize(640, 400)
self.labelFrame = ttk.LabelFrame(self, text = "Open File")
self.labelFrame.grid(column = 0, row = 1, padx = 20, pady = 20)
self.button()
self.button1()
def button(self):
self.button = ttk.Button(self.labelFrame, text = "Browse A File",command = self.fileDialog)
self.button.grid(column = 1, row = 1)
def fileDialog(self):
self.filename = filedialog.askopenfilename(initialdir = "/", title = "Select A File", filetype = (("png files","*.png"),("all files","*.*")))
self.label = ttk.Label(self.labelFrame, text = "")
self.label.grid(column = 1, row = 2)
self.label.configure(text = self.filename)
def button1(self):
self.button = ttk.Button(self.labelFrame, text = "submit", command = self.get_prediction)
self.button.grid(column = 1, row = 20)
def get_prediction(self):
s=model.predict(my_image)
if(s==[[1.]]):
self.label.configure(text="non parasitic")
else:
self.label.configure(text="parasitic")
root = Root()
root.mainloop()