我正在尝试分析假单胞菌生物膜的图像,这样做是为了找到其生长与分布之间的某种相关性以及一些自变量。我已经应用了分割以获得感兴趣的圆形区域,现在我正在考虑将某些颜色分割应用于具有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
将该蒙版应用于原始图像。
原始图像->
使用clusters=5
进行Kmeans颜色量化
请注意,细微的差别在于整个图像被分为五种颜色。这是每个颜色簇和颜色分布百分比的可视化。根据颜色分割,我们可以估计前三种颜色(忽略黑色)上有细菌。
[ 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()