Прежде чем погрузиться в часть моего вопроса, посвященную кодированию, я должен написать введение, чтобы дать вам представление о том, чего я пытаюсь достичь. Также имейте в виду, что у меня очень слабый опыт программирования, и что это мой первый проект Python.
Я работаю над проектом, связанным с микрофлюидикой (µflu) и визуализацией клеток человека. Общая идея проекта состоит в том, чтобы улавливать отдельные клетки в определенных c местах в микрофлюидных c устройствах, чтобы сделать возможным визуализацию отдельных клеток с помощью инновационных методов. Чтобы оценить эффективность моих устройств microfluidi c, у меня есть доступ к имидж-сканеру планшетов . Это позволяет мне делать снимки всего устройства µflu (зона примерно 3x2 см²) с клетками (отмеченными флуоресценцией) в нем. Полученные изображения .tif очень большие (около 20000x10000 пикселей) и весят около 500 МБ каждое. Вот пример изображения (снимок экрана с фактическим изображением):
Th µflu device aims at immobilizing single cells on a regularly spaced grid (which is not really visible on the images), which you can see on some parts of the previous image, or on this close-up view :
However, things are not perfect and as you saw on the first image, a lot of fluorescent signal is leaking in the µflu channels, clogging can happen, etc...
So, here is what I am trying to write code for :
- Cleaning the image : removing parasite fluorescent signal
- Counting all the cells on the cleaned image
- Counting only the cells that are on the designed grid
- Discriminating between single cells and cells agglomerates (which you can see one of in the second image)
Regarding the first objective, I managed to obtain this image from the first one (the image is NOT pitch black, the cells are juste really small compared to the whole image) :
Here is the code I wrote for this :
imgArray = imageio.imread(filename) #Loading the image
#Converting the image from 16bit to 8bit array
imgConvertedArray = (imgArray >> 8).astype('uint8') #Actual conversion
#Thresholding the array and filling small holes
imgThresholdedArray = (imgConvertedArray == 255) * imgConvertedArray #Actual thresholding (setting all values < 250 to 0)
imgThresholdedArray = morphology.remove_small_holes(imgThresholdedArray, 100, 1)
imgThresholdedArray = imgThresholdedArray.astype('uint8')
#Removing objects too small or too big for a cell from thresholded image
nb_components, output, stats, centroids = cv2.connectedComponentsWithStats(imgThresholdedArray, connectivity=4) #Find all the connected components
sizes = stats[1:, -1]; nb_components = nb_components - 1
min_size = 10 #Minimum size of component to keep
max_size = 300 #Maximum size of component to keep
imgThresholdedArrayCleaned = numpy.zeros((output.shape)) #Creating an array with the same size as the array to filter
for i in range(0, nb_components): #Keeping only the components with good size
if sizes[i] >= min_size and sizes[i]
Now, the results I obtain is not perfect, as there is still some "parasite" signal, and I might have lost some actual cells in the process. Also, the code is slow (about 5 minutes to run on a single image), but this might simply be due to the size of the images.
Here are my questions :
- how should I go about improving my image "cleaning" code ? Would a "contour finding" method provide better results ?
- I have no idea how to approach counting the cells that are on the grid. Any idea ?
I will answer questions or provide more images if needed. Thank you.
EDIT 1 - Here is a highlight of the difference between the cells (in green) and the parasitic signal left after I already "cleaned" the image (in red) :
введите описание изображения здесь