簡體   English   中英

如何使用opencv和python在屬於生物樣本的圖像中分割相似的區域(顏色明智)?

[英]How to segment similar looking areas (color wise) inside a image that belong to biosamples with opencv and python?

我正在嘗試分析假單胞菌生物膜的圖像,我這樣做是為了找到它的生長和分布與一些自變量之間的某種相關性。 我已經應用了一個分割來獲得一個感興趣的圓形區域,現在我正在考慮對帶有 HSV 值的圖像應用一些顏色分割,以只留下帶有生物膜的區域。 我試圖以一種完全隔離所有重要區域的方式思考,我對圖像應用了 bitwise_not 以查看負片,並發現在視覺上更容易區分,所有黃色區域都有細菌它。

原圖:

原來的

消極的:

消極的

使用我編寫的代碼,我必須分割出大部分細菌點,但不是所有真正有細菌的區域。

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)

我已經知道代碼真的很簡單,所以當我無法隔離所有感興趣的區域時,我並沒有感到驚訝,您認為如果應用更多的遮罩我可以提取所有黃色區域嗎? 或者也許有人可以說一種與我正在尋找的算法有些相似的算法。 提前感謝任何感興趣的人。

結果:

結果

一種想法是執行 Kmeans 顏色量化以將圖像聚類為不同數量的顏色。 之后,我們可以將圖像轉換為 HSV 格式,並使用具有下/上顏色閾值的cv2.inRange執行顏色閾值處理以獲得二值掩碼。 最后,我們使用cv2.bitwise_and將此掩碼應用於原始圖像。


原始圖像-> Kmeans 顏色量化, clusters=5

注意整個圖像被分割成五種顏色的細微差別。 這是每個顏色簇和顏色分布百分比的可視化。 根據顏色分割,我們可以估計前三種顏色(忽略黑色)上面有細菌。

在此處輸入圖片說明

[ 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])

我們將蒙版應用到原始圖像上以獲得我們的結果

還記得我們是如何使用三種顏色分布來確定是否存在細菌的嗎? 如果我們改變顏色閾值范圍,我們可以進一步將圖像分割成大、中、小細菌區域。

我們可以使用此顏色范圍僅隔離大細菌區域

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

蒙版->結果

對於中等地區

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

最后得到小區域

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

代碼

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()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM