如何使用图像中每个像素的颜色绘制图形?

5

我正在进行图像颜色识别,因此我将RGB图像转换为Lab,因为它是最接近人类视觉的颜色空间。之后,我得到了每个Lab的三个通道,并希望在3D图形中绘制我在转换后的图像中识别出的颜色变化。如何使用图像的颜色来绘制图形?

import cv2
import numpy as np
import urllib
import mpl_toolkits.mplot3d.axes3d as p3
import matplotlib.pyplot as plt

# Load an image that contains all possible colors.
request = urllib.urlopen('IMD021.png')
image_array = np.asarray(bytearray(request.read()), dtype=np.uint8)
image = cv2.imdecode(image_array, cv2.CV_LOAD_IMAGE_COLOR)

lab_image = cv2.cvtColor(image, cv2.COLOR_BGR2LAB)
l_channel,a_channel,b_channel = cv2.split(lab_image)

fig = plt.figure()
ax = p3.Axes3D(fig)
ax.scatter(l_channel, a_channel, b_channel, marker='o',  facecolors=cv2.cvtColor(image, cv2.COLOR_BGR2RGB).reshape(-1,3)/255.)

ax.set_xlabel('L')
ax.set_ylabel('A')
ax.set_zlabel('B')
fig.add_axes(ax)
#plt.savefig('plot-15.png')
plt.show()

退出: 点击此处查看图片描述

这样就可以正确绘制---假设你只想让标记颜色对应其位置表示的颜色。是这样吗?如果是的话,请参见这里 - alkasm
是的,但在发送给我的链接中,它使用随机颜色,我想要加载图像的颜色。 - Tecnologia da Net
1个回答

4

以下是如何获得Alexander建议您在您的情况下工作的答案:

# only change to question's code is the ax.scatter() line:
ax.scatter(l_channel, a_channel, b_channel, marker='o',
  facecolors=cv2.cvtColor(image, cv2.COLOR_BGR2RGB).reshape(-1,3)/255.)

注意:facecolors参数需要RGB,而不是OpenCV的BGR,并且对颜色数据的形状和类型非常挑剔,因此需要进行reshape和 division操作。
应用该代码到这张图片后生成的结果如下:enter image description here

2
简单明了。而且,用这张照片来展示真是太好了!它如此统一!在这里我喜欢做的另一件事是将标记的不透明度和大小映射到具有该值的像素数量上——通过不透明度给内部分布增加一点维度,并通过大小看到颜色密度。虽然这个答案不需要这个补充,但对于任何实现演示或其他东西的人来说,这是一个不错的想法。 - alkasm
1
@CarlosDiego,我用你更新后的代码运行了你问题中的图像,得到了这个彩色图 - Ulrich Stern
1
我唯一的猜测是,也许在生成图表时,你不小心运行了旧代码(或者包含c='b'的代码)。但我假设你已经检查过了。 - Ulrich Stern
1
我之前运行了你的代码的第2个版本(“更新代码”)。我刚刚运行了你的代码的第3个版本,再次获得了正确着色的绘图。我的Matplotlib版本是2.1.2。注释掉你的 fig.add_axes(ax) 可以消除我的 MatplotlibDeprecationWarning。 - Ulrich Stern
@UlrichStern 你能在 https://dev59.com/q1IH5IYBdhLWcg3wGZC5 帮我吗? - Carlos Diego
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接