Как сегментировать похожие области (по цвету) внутри изображения, которые принадлежат биопробам с opencv и python? - PullRequest
2 голосов
/ 18 февраля 2020

Я пытаюсь проанализировать изображения биопленок псевдомонии, я делаю это для того, чтобы найти какую-то корреляцию между ее ростом и распределением с некоторыми независимыми переменными. Я применил сегментацию, чтобы получить круговую область интереса, и теперь я думал о применении некоторой цветовой сегментации к изображению с его значениями HSV, чтобы просто оставить области с биопленкой. Я пытался придумать способ полностью изолировать все важные области, я применил к изображению побитовые, а не негативные изображения и обнаружил, что визуально легче различить guish, все области. на желтом sh есть бактерии.

Исходное изображение:

original

Отрицательный:

negative

С помощью кода, который я написал, я должен сегментировать большие пятна бактерий, но не все области, которые действительно имеют его.

import cv2
import numpy as np
import os
def color_segmentation(image):
    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    mask1 = cv2.inRange(hsv, (90,90,50), (179,255,160))
    target = cv2.bitwise_and(image, image, mask=mask1)
    return target
test = cv2.imread(path)
result = color_segmentation(test)
cv2.imshow('result', result)

Я уже знаю, что код действительно прост, поэтому меня не удивило, когда я не смог выделить все области интереса, вы думаете, что, если применить больше масок, я смогу извлечь все области yellowi sh ? Или, может быть, кто-то может сказать алгоритм, который несколько похож на то, что я ищу. Заранее спасибо всем, кто заинтересован.

Результат:

result

1 Ответ

2 голосов
/ 18 февраля 2020

Одна идея состоит в том, чтобы выполнить квантование цветов Kmeans, чтобы сгруппировать изображение в различное количество цветов. После этого мы можем преобразовать изображение в формат HSV и выполнить пороговое значение цвета, используя cv2.inRange с нижним / верхним цветовым порогом, чтобы получить двоичную маску. Наконец, мы применяем эту маску к исходному изображению, используя cv2.bitwise_and.


Исходное изображение -> Квантование цвета Kmeans с clusters=5

image image

Обратите внимание на небольшую разницу в том, что все изображение сегментировано в пять цветов. Вот визуализация каждого цветового кластера и процент распределения цвета. Основываясь на сегментации цвета, мы можем оценить, что в первых трех цветах (без учета черного) есть бактерии.

enter image description here

[ 67.70980019  86.19251507 121.19410086] 0.87%
[120.61108133 146.00169267 159.48142297] 9.78%
[0.18113609 0.22505063 0.25559479] 21.40%
[134.06236381 170.04397205 167.3696234 ] 23.44%
[140.53640479 189.4275781  171.19319177] 44.50%

Далее мы выполняем пороговое значение цвета для получения маски с этим нижним / верхним цветовым диапазоном

lower = np.array([84, 0, 0])
upper = np.array([179, 255, 255])

image

Мы применяем маску к исходному изображению, чтобы получить наш результат

image

Помните, как было три цветовых распределения, которые мы использовали, чтобы определить, были ли бактерии? Если мы изменим диапазон цветового порога, мы можем еще больше разделить изображение на большие, средние и маленькие области бактерий.

Мы можем выделить только крупные области бактерий, используя эту цветовую гамму

lower = np.array([104, 0, 0])
upper = np.array([179, 255, 255])

Маска -> Результат

image image

Для средних регионов

lower = np.array([90, 0, 0])
upper = np.array([102, 255, 255])

image image

Наконец, для получения небольших регионов

lower = np.array([84, 0, 0])
upper = np.array([98, 255, 255])

image image

Код

import cv2
import numpy as np

# Kmeans color segmentation
def kmeans_color_quantization(image, clusters=8, rounds=1):
    h, w = image.shape[:2]
    samples = np.zeros([h*w,3], dtype=np.float32)
    count = 0

    for x in range(h):
        for y in range(w):
            samples[count] = image[x][y]
            count += 1

    compactness, labels, centers = cv2.kmeans(samples,
            clusters, 
            None,
            (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10000, 0.0001), 
            rounds, 
            cv2.KMEANS_RANDOM_CENTERS)

    centers = np.uint8(centers)
    res = centers[labels.flatten()]
    return res.reshape((image.shape))

# Load original image
original = cv2.imread('2.png')

# Perform kmeans color segmentation
kmeans = kmeans_color_quantization(original, clusters=5)

# Color threshold on kmeans image
hsv = cv2.cvtColor(kmeans, cv2.COLOR_BGR2HSV)
lower = np.array([84, 0, 0])
upper = np.array([179, 255, 255])
mask = cv2.inRange(hsv, lower, upper)

# Apply mask onto original image
result = cv2.bitwise_and(original, original, mask=mask)
result[mask==0] = (255,255,255)

# Display
cv2.imshow('kmeans', kmeans)
cv2.imshow('result', result)
cv2.imshow('mask', mask)
cv2.waitKey()

Этот скрипт HSV для определения цветового разрешения использовался для определения нижнего / верхнего цветовых диапазонов

import cv2
import numpy as np

def nothing(x):
    pass

# Load image
image = cv2.imread('1.png')

# Create a window
cv2.namedWindow('image')

# Create trackbars for color change
# Hue is from 0-179 for Opencv
cv2.createTrackbar('HMin', 'image', 0, 179, nothing)
cv2.createTrackbar('SMin', 'image', 0, 255, nothing)
cv2.createTrackbar('VMin', 'image', 0, 255, nothing)
cv2.createTrackbar('HMax', 'image', 0, 179, nothing)
cv2.createTrackbar('SMax', 'image', 0, 255, nothing)
cv2.createTrackbar('VMax', 'image', 0, 255, nothing)

# Set default value for Max HSV trackbars
cv2.setTrackbarPos('HMax', 'image', 179)
cv2.setTrackbarPos('SMax', 'image', 255)
cv2.setTrackbarPos('VMax', 'image', 255)

# Initialize HSV min/max values
hMin = sMin = vMin = hMax = sMax = vMax = 0
phMin = psMin = pvMin = phMax = psMax = pvMax = 0

while(1):
    # Get current positions of all trackbars
    hMin = cv2.getTrackbarPos('HMin', 'image')
    sMin = cv2.getTrackbarPos('SMin', 'image')
    vMin = cv2.getTrackbarPos('VMin', 'image')
    hMax = cv2.getTrackbarPos('HMax', 'image')
    sMax = cv2.getTrackbarPos('SMax', 'image')
    vMax = cv2.getTrackbarPos('VMax', 'image')

    # Set minimum and maximum HSV values to display
    lower = np.array([hMin, sMin, vMin])
    upper = np.array([hMax, sMax, vMax])

    # Convert to HSV format and color threshold
    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    mask = cv2.inRange(hsv, lower, upper)
    result = cv2.bitwise_and(image, image, mask=mask)

    # Print if there is a change in HSV value
    if((phMin != hMin) | (psMin != sMin) | (pvMin != vMin) | (phMax != hMax) | (psMax != sMax) | (pvMax != vMax) ):
        print("(hMin = %d , sMin = %d, vMin = %d), (hMax = %d , sMax = %d, vMax = %d)" % (hMin , sMin , vMin, hMax, sMax , vMax))
        phMin = hMin
        psMin = sMin
        pvMin = vMin
        phMax = hMax
        psMax = sMax
        pvMax = vMax

    # Display result image
    cv2.imshow('image', result)
    if cv2.waitKey(10) & 0xFF == ord('q'):
        break

cv2.destroyAllWindows()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...