将叶子与其背景分开
Separating the leaf from it's background
我有一组图片,所有图片看起来都和这里的这片叶子差不多:
我想从背景中提取叶子,为此我使用了 GrabCut
算法 here。
作为一种不同的方法,我还使用了基于 r、g 和 b 值比率的阈值,如下所示:
import numpy as np
import cv2
import matplotlib.pyplot as plt
testImg = cv2.imread('path_to_the_image')
testImg = cv2.resize(testImg, (256, 256))
#bgImg = cv2.imread('')
#blurBg = cv2.GaussianBlur(bgImg, (5, 5), 0)
#blurBg = cv2.resize(blurBg, (256, 256))
#testImg = cv2.GaussianBlur(testImg, (5, 5), 0)
cv2.imshow('testImg', testImg)
#plt.imshow(bgImg)
cv2.waitKey(0)
#plt.show()
modiImg = testImg.copy()
ht, wd = modiImg.shape[:2]
print(modiImg[0][0][0])
for i in range(ht):
for j in range(wd):
r = modiImg[i][j][0]
g = modiImg[i][j][1]
b = modiImg[i][j][2]
r1 = r/g
r2 = g/b
r3 = r/b
r4 = round((r1+r2+r3)/3, 1)
if g > r and g > b:
modiImg[i][j] = [255, 255, 255]
elif r4 >= 1.2:
modiImg[i][j] = [255, 255, 255]
else:
modiImg[i][j] = [0, 0, 0]
# if r4 <= 1.1:
# modiImg[i][j] = [0, 0, 0]
# elif g > r and g > b:
# modiImg[i][j] = [255, 255, 255]
# else:
# modiImg[i][j] = [255, 255, 255]
# elif r4 >= 1.2:
# modiImg[i][j] = [255, 255, 255]
# else:
# modiImg[i][j] = [0, 0, 0]
plt.imshow(modiImg)
plt.show()
testImg = testImg.astype(float)
alpha = modiImg.astype(float) / 255
testImg = cv2.multiply(alpha, testImg)
cv2.imshow('final', testImg/255)
cv2.waitKey(0)
但是叶子上的黑点总是在提取的叶子图像中消失,如下所示:
是否有任何其他方法可以将叶子与其背景分开,假设每张图像只有一片叶子,并且背景与我拍摄的其他图像几乎相同有并且叶子的位置 almost 与此处类似。
您可能想使用深度学习方法。 U-Net 在 https://lmb.informatik.uni-freiburg.de/people/ronneber/u-net/ 这样的任务上做得很好。正如我所见,他们还提供了训练有素的模型。如果您安装了 Matlab 和 Caffee,您应该能够将文件复制到正确的文件夹中,运行 程序并收到您正在寻找的结果。
对于这类任务,阈值不是一个好主意。您的方法应该能够识别图案,而不仅仅是查看像素的颜色。
深度学习方法的一个问题是棘手的,你要么需要一个已经训练过叶的 RBG 图像分割的预训练网络,要么你需要数据(叶的 RGB 图像和相应的分割)。
您可以尝试使用 HSV 颜色图进行图像分割。
代码:
img = cv2.imread('leaf.jpg')
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# find the green color
mask_green = cv2.inRange(hsv, (36,0,0), (86,255,255))
# find the brown color
mask_brown = cv2.inRange(hsv, (8, 60, 20), (30, 255, 200))
# find the yellow color in the leaf
mask_yellow = cv2.inRange(hsv, (21, 39, 64), (40, 255, 255))
# find any of the three colors(green or brown or yellow) in the image
mask = cv2.bitwise_or(mask_green, mask_brown)
mask = cv2.bitwise_or(mask, mask_yellow)
# Bitwise-AND mask and original image
res = cv2.bitwise_and(img,img, mask= mask)
cv2.imshow("original", img)
cv2.imshow("final image", res)
cv2.waitKey(0)
cv2.destroyAllWindows()
输出:
此外,如果将较低范围的黄色从 (21, 39, 64)
更改为 (14, 39, 64)
,那么您会看到叶子上的小黑点开始填充,并且会进一步改善结果.
我有一组图片,所有图片看起来都和这里的这片叶子差不多:
我想从背景中提取叶子,为此我使用了 GrabCut
算法 here。
作为一种不同的方法,我还使用了基于 r、g 和 b 值比率的阈值,如下所示:
import numpy as np
import cv2
import matplotlib.pyplot as plt
testImg = cv2.imread('path_to_the_image')
testImg = cv2.resize(testImg, (256, 256))
#bgImg = cv2.imread('')
#blurBg = cv2.GaussianBlur(bgImg, (5, 5), 0)
#blurBg = cv2.resize(blurBg, (256, 256))
#testImg = cv2.GaussianBlur(testImg, (5, 5), 0)
cv2.imshow('testImg', testImg)
#plt.imshow(bgImg)
cv2.waitKey(0)
#plt.show()
modiImg = testImg.copy()
ht, wd = modiImg.shape[:2]
print(modiImg[0][0][0])
for i in range(ht):
for j in range(wd):
r = modiImg[i][j][0]
g = modiImg[i][j][1]
b = modiImg[i][j][2]
r1 = r/g
r2 = g/b
r3 = r/b
r4 = round((r1+r2+r3)/3, 1)
if g > r and g > b:
modiImg[i][j] = [255, 255, 255]
elif r4 >= 1.2:
modiImg[i][j] = [255, 255, 255]
else:
modiImg[i][j] = [0, 0, 0]
# if r4 <= 1.1:
# modiImg[i][j] = [0, 0, 0]
# elif g > r and g > b:
# modiImg[i][j] = [255, 255, 255]
# else:
# modiImg[i][j] = [255, 255, 255]
# elif r4 >= 1.2:
# modiImg[i][j] = [255, 255, 255]
# else:
# modiImg[i][j] = [0, 0, 0]
plt.imshow(modiImg)
plt.show()
testImg = testImg.astype(float)
alpha = modiImg.astype(float) / 255
testImg = cv2.multiply(alpha, testImg)
cv2.imshow('final', testImg/255)
cv2.waitKey(0)
但是叶子上的黑点总是在提取的叶子图像中消失,如下所示:
是否有任何其他方法可以将叶子与其背景分开,假设每张图像只有一片叶子,并且背景与我拍摄的其他图像几乎相同有并且叶子的位置 almost 与此处类似。
您可能想使用深度学习方法。 U-Net 在 https://lmb.informatik.uni-freiburg.de/people/ronneber/u-net/ 这样的任务上做得很好。正如我所见,他们还提供了训练有素的模型。如果您安装了 Matlab 和 Caffee,您应该能够将文件复制到正确的文件夹中,运行 程序并收到您正在寻找的结果。
对于这类任务,阈值不是一个好主意。您的方法应该能够识别图案,而不仅仅是查看像素的颜色。
深度学习方法的一个问题是棘手的,你要么需要一个已经训练过叶的 RBG 图像分割的预训练网络,要么你需要数据(叶的 RGB 图像和相应的分割)。
您可以尝试使用 HSV 颜色图进行图像分割。
代码:
img = cv2.imread('leaf.jpg')
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# find the green color
mask_green = cv2.inRange(hsv, (36,0,0), (86,255,255))
# find the brown color
mask_brown = cv2.inRange(hsv, (8, 60, 20), (30, 255, 200))
# find the yellow color in the leaf
mask_yellow = cv2.inRange(hsv, (21, 39, 64), (40, 255, 255))
# find any of the three colors(green or brown or yellow) in the image
mask = cv2.bitwise_or(mask_green, mask_brown)
mask = cv2.bitwise_or(mask, mask_yellow)
# Bitwise-AND mask and original image
res = cv2.bitwise_and(img,img, mask= mask)
cv2.imshow("original", img)
cv2.imshow("final image", res)
cv2.waitKey(0)
cv2.destroyAllWindows()
输出:
此外,如果将较低范围的黄色从 (21, 39, 64)
更改为 (14, 39, 64)
,那么您会看到叶子上的小黑点开始填充,并且会进一步改善结果.