如何通过直方图从蒙版图像中提取颜色特征?
How to extract color features via histogram from a masked image?
我从图像中提取了一个对象,所以现在我有 a masked image with a tennis ball and a black background。
我想通过直方图单独从网球中提取颜色特征。这是我到目前为止的代码,但是从直方图的外观来看,黑色背景支配着任何其他颜色,这使得直方图无效:
from PIL import Image
from pylab import *
# Import image and convert to gray
image = Image.open("res_300.png")
im = image.convert('L')
im_array = array(im)
# Create a new figure
figure()
gray()
# Show contours with origin upper left corner
contour(im, origin='image')
axis('equal')
axis('off')
# Create histogram
figure()
hist(im_array.flatten(), 128)
show()
有没有办法在忽略黑色背景的情况下,根据网球BGR颜色特征绘制直方图?
我是 python 菜鸟。谢谢。
您可以 neglect/remove 所有 3 个 RGB 通道的低强度值(对应于黑色)。然后在所有3个通道中取平均值,得到所需物体对应的RGB值。
要将颜色通道拆分为 BGR
,我们可以使用 cv2.split()
然后使用 cv2.calcHist()
使用直方图提取颜色特征。要删除占主导地位的黑色背景,我们可以将范围设置为 [1, 256]
.
from matplotlib import pyplot as plt
import cv2
image = cv2.imread('1.png')
channels = cv2.split(image)
colors = ("b", "g", "r")
plt.figure()
plt.title("Color Histogram")
plt.xlabel("Bins")
plt.ylabel("# of Pixels")
features = []
# Loop over the image channels (B, G, R)
for (channel, color) in zip(channels, colors):
# Calculate histogram
hist = cv2.calcHist([channel], [0], None, [255], [1, 256])
features.extend(hist)
# Plot histogram
plt.plot(hist, color = color)
plt.xlim([0, 256])
plt.show()
也有 np.histogram
这样做。与 nathancy 的回答类似,可以从 1
设置限制以忽略黑色背景:
image = cv2.imread('8fk43.png')
plt.figure(figsize=(10,6))
for i, c in zip(range(3), 'bgr'):
hist,bins = np.histogram(image[:,:,i], bins=range(0,256))
plt.plot(bins[1:-1], hist[1:], c=c)
plt.show()
输出:
注意:上面的做法有些不对。想想纯绿色(0,255,0)
会在red/blue频道被忽略。正确的方法是先将网球蒙版,然后将蒙版作为权重传给np.histogram
。
例如,在这种情况下,可以简单地将 mask
视为所有通道都非零的位置:
mask = (image>0).sum(-1)
mask = np.array(mask>0, dtype=np.uint8)
给出掩码:
然后,
plt.figure(figsize=(10,6))
for i, c in zip(range(3), 'bgr'):
hist,bins = np.histogram(image[:,:,i], bins=range(0,256), weights=mask)
plt.plot(bins[:-1], hist, c=c)
plt.show()
给出了一个相对于球的实际大小更合理的直方图:
我从图像中提取了一个对象,所以现在我有 a masked image with a tennis ball and a black background。
我想通过直方图单独从网球中提取颜色特征。这是我到目前为止的代码,但是从直方图的外观来看,黑色背景支配着任何其他颜色,这使得直方图无效:
from PIL import Image
from pylab import *
# Import image and convert to gray
image = Image.open("res_300.png")
im = image.convert('L')
im_array = array(im)
# Create a new figure
figure()
gray()
# Show contours with origin upper left corner
contour(im, origin='image')
axis('equal')
axis('off')
# Create histogram
figure()
hist(im_array.flatten(), 128)
show()
有没有办法在忽略黑色背景的情况下,根据网球BGR颜色特征绘制直方图?
我是 python 菜鸟。谢谢。
您可以 neglect/remove 所有 3 个 RGB 通道的低强度值(对应于黑色)。然后在所有3个通道中取平均值,得到所需物体对应的RGB值。
要将颜色通道拆分为 BGR
,我们可以使用 cv2.split()
然后使用 cv2.calcHist()
使用直方图提取颜色特征。要删除占主导地位的黑色背景,我们可以将范围设置为 [1, 256]
.
from matplotlib import pyplot as plt
import cv2
image = cv2.imread('1.png')
channels = cv2.split(image)
colors = ("b", "g", "r")
plt.figure()
plt.title("Color Histogram")
plt.xlabel("Bins")
plt.ylabel("# of Pixels")
features = []
# Loop over the image channels (B, G, R)
for (channel, color) in zip(channels, colors):
# Calculate histogram
hist = cv2.calcHist([channel], [0], None, [255], [1, 256])
features.extend(hist)
# Plot histogram
plt.plot(hist, color = color)
plt.xlim([0, 256])
plt.show()
也有 np.histogram
这样做。与 nathancy 的回答类似,可以从 1
设置限制以忽略黑色背景:
image = cv2.imread('8fk43.png')
plt.figure(figsize=(10,6))
for i, c in zip(range(3), 'bgr'):
hist,bins = np.histogram(image[:,:,i], bins=range(0,256))
plt.plot(bins[1:-1], hist[1:], c=c)
plt.show()
输出:
注意:上面的做法有些不对。想想纯绿色(0,255,0)
会在red/blue频道被忽略。正确的方法是先将网球蒙版,然后将蒙版作为权重传给np.histogram
。
例如,在这种情况下,可以简单地将 mask
视为所有通道都非零的位置:
mask = (image>0).sum(-1)
mask = np.array(mask>0, dtype=np.uint8)
给出掩码:
然后,
plt.figure(figsize=(10,6))
for i, c in zip(range(3), 'bgr'):
hist,bins = np.histogram(image[:,:,i], bins=range(0,256), weights=mask)
plt.plot(bins[:-1], hist, c=c)
plt.show()
给出了一个相对于球的实际大小更合理的直方图: