I'm working on image color recognition, so I'm converting the RGB image to Lab because it's the closest color space to human vision. After that, I get each one of the Lab's 3 channels and I want to plot in the 3D graphic the color variations that I identified in the converted image. How do I plot the graphic with the colors of the image?
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()
Exit:
A pixel plot of raw data can be generated by using the cmap and interpolation parameters of the imshow() method in matplot. pyplot module.
With the get() function we can read the color of any pixel in our program window. We can specify which pixel we are interested in by using x and y coordinates as parameters. For example, color mycolor = get(100, 200); would grab the color of pixel 100, 200 and put that color into the mycolor variable.
Using this scheme to represent all the pixels of an image takes one third of the number of bits required for 24-bit colour, but it is not as good at showing smooth changes of colours or subtle shades, because there are only 256 possible colors for each pixel.
A digital color image pixel is just numbers representing a RGB data value (Red, Green, Blue). Each pixel's color sample has three numerical RGB components (Red, Green, Blue) to represent the color of that tiny pixel area.
Here how to get the answer Alexander suggested to work in your case:
# 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.)
Note: The facecolors
argument requires RGB, not OpenCV's BGR, and is picky about the shape and type of the color data, hence the reshape and division.
Here the result when the code is applied to this image:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With