how to create LAB color chart using opencv?

Question:

I am developing a project that has as a starting point to identify the colors of certain spots, for this I am plotting 3D graphics with the RGB colors of these images. With this I have identified some striking colors of these spots, as seen below.

enter image description here

Color is a matter of perception and subjectivity of interpretation. The purpose of this step is to identify so that you can find a pattern of color without differences of interpretation. With this, I have been searching the internet and for this, it is recommended to use the color space L * a * b *.

With this, can someone help me to obtain this graph with the colors LAB, or indicate another way to better classify the colors of these spots?

Code used to plot 3d graph

import numpy as np
import mpl_toolkits.mplot3d.axes3d as p3
import matplotlib.pyplot as plt
import colorsys
from PIL import Image

# (1) Import the file to be analyzed!
img_file = Image.open("IMD405.png")
img = img_file.load()

# (2) Get image width & height in pixels
[xs, ys] = img_file.size
max_intensity = 100
hues = {}

# (3) Examine each pixel in the image file
for x in xrange(0, xs):
  for y in xrange(0, ys):
    # (4)  Get the RGB color of the pixel
    [r, g, b] = img[x, y]

# (5)  Normalize pixel color values
r /= 255.0
g /= 255.0
b /= 255.0

# (6)  Convert RGB color to HSV
[h, s, v] = colorsys.rgb_to_hsv(r, g, b)

# (7)  Marginalize s; count how many pixels have matching (h, v)
if h not in hues:
  hues[h] = {}
if v not in hues[h]:
  hues[h][v] = 1
else:
  if hues[h][v] < max_intensity:
    hues[h][v] += 1

# (8)   Decompose the hues object into a set of one dimensional arrays we can use with matplotlib
h_ = []
v_ = []
i = []
colours = []

for h in hues:
  for v in hues[h]:
    h_.append(h)
    v_.append(v)
    i.append(hues[h][v])
    [r, g, b] = colorsys.hsv_to_rgb(h, 1, v)
    colours.append([r, g, b])

# (9)   Plot the graph!
fig = plt.figure()
ax = p3.Axes3D(fig)
ax.scatter(h_, v_, i, s=5, c=colours, lw=0)

ax.set_xlabel('Hue')
ax.set_ylabel('Value')
ax.set_zlabel('Intensity')
fig.add_axes(ax)
plt.savefig('plot-IMD405.png')
plt.show()
Asked By: Tecnologia da Net

||

Answers:

Using OpenCV for Python is really straightforward. Here I created a function to plot a sample image. Note that for this function the image must be RGB or BGR.

import cv2
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

image_BGR = np.uint8(np.random.rand(50,50,3) * 255)
#this image above is just an example. To load a real image use the line below
#image_BGR = cv2.imread('path/to/image')

def toLAB(image, input_type = 'BGR'):
  conversion = cv2.COLOR_BGR2LAB if input_type == 'BGR' else cv2.COLOR_RGB2LAB
  image_LAB = cv2.cvtColor(image, conversion)

  y,x,z = image_LAB.shape
  LAB_flat = np.reshape(image_LAB, [y*x,z])

  colors = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) if input_type == 'BGR' else image
  colors = np.reshape(colors, [y*x,z])/255.

  fig = plt.figure()
  ax = fig.add_subplot(111, projection='3d')
  ax.scatter(xs=LAB_flat[:,2], ys=LAB_flat[:,1], zs=LAB_flat[:,0], s=10,  c=colors, lw=0)
  ax.set_xlabel('A')
  ax.set_ylabel('B')
  ax.set_zlabel('L')

  plt.show()

  return image_LAB 

lab_image = toLAB(image_BGR)

The result is something like this:

LBA scatter plot

I hope it helped!

Answered By: Guilherme Uzeda
# load the input image 
image = cv2.imread(image_file)

# Change to RGB space
image_RGB = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

#plt.imshow(image_RGB)
#plt.show()

# get pixel color
pixel_colors = image_RGB.reshape((np.shape(image_RGB)0]*np.shape(image_RGB)[1], 3))

norm = colors.Normalize(vmin=-1.,vmax=1.)

norm.autoscale(pixel_colors)

pixel_colors = norm(pixel_colors).tolist()

# Change to lab space
image_LAB = cv2.cvtColor(image, cv2.COLOR_BGR2LAB )


(L_chanel, A_chanel, B_chanel) = cv2.split(image_LAB)

fig = plt.figure(figsize=(8.0, 6.0))

axis = fig.add_subplot(1, 1, 1, projection="3d")

axis.scatter(L_chanel.flatten(), A_chanel.flatten(), B_chanel.flatten(), facecolors = pixel_colors, marker = ".")
axis.set_xlabel("L:ightness")
axis.set_ylabel("A:red/green coordinate")
axis.set_zlabel("B:yellow/blue coordinate")

plt.show()
Answered By: user11294361