Created
December 19, 2023 06:51
-
-
Save Anthony-Hoo/b1630f320f990444d485ca0de6a52c10 to your computer and use it in GitHub Desktop.
Converts image input to CIE xy chromaticity coordinates with original pixel colour
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from PIL import Image | |
import numpy as np | |
import matplotlib.pyplot as plt | |
import time | |
from colour.plotting import * | |
def plot_xy_coordinates_with_color(xy_and_rgb_np, output_png_path): | |
start_time = time.time() | |
xy = xy_and_rgb_np[:, :2] | |
RGB = xy_and_rgb_np[:, 2:5] | |
if RGB.max() > 1: | |
RGB = RGB / 255.0 | |
plot_chromaticity_diagram_CIE1931(show = False, show_diagram_colours = False) | |
ax = plt.gca() | |
ax.set_title('CIE 1931 Chromaticity Diagram') | |
ax.scatter(xy[:, 0], xy[:, 1], color=RGB, s=0.01, edgecolors=None, linewidths=0) | |
plt.savefig(output_png_path, format='png', dpi=500) | |
plt.close() | |
print('Drawing Chromaticity Diagram spent: {:.2f} seconds'.format(time.time() - start_time)) | |
def image_to_cie_xy_and_rgb(image_path): | |
start_time = time.time() | |
with Image.open(image_path) as img: | |
img = img.convert('RGB') | |
image_data = np.array(img, dtype=np.float16) | |
pixels = image_data.reshape(-1, 3) | |
sum_xyz = np.sum(pixels, axis=1, keepdims=True) | |
xy_coordinates = np.divide(pixels[:, :2], sum_xyz, out=np.zeros_like(pixels[:, :2], dtype=np.float16), where=sum_xyz!=0) | |
xy_and_rgb = np.hstack([xy_coordinates, pixels]) | |
print('Computing XYZ and RGB spent: {:.2f} seconds'.format(time.time() - start_time)) | |
return xy_and_rgb | |
if __name__ == "__main__": | |
''' | |
The Python script converts image RGB data to CIE xy chromaticity coordinates and RGB values | |
using PIL and NumPy (function image_to_cie_xy_and_rgb). | |
It then visualizes these coordinates on the CIE 1931 Chromaticity Diagram | |
with Matplotlib and colour.plotting, coloring each point according to | |
its RGB value (function plot_xy_coordinates_with_color). | |
The development focused on optimizing data processing and visualization, | |
utilizing vectorized operations for efficiency, | |
ensuring accurate color representation, and producing visual output. | |
''' | |
image_path = './test.jpg' | |
xy_and_rgb = image_to_cie_xy_and_rgb(image_path) | |
output_png_path = 'cie_diagram.png' | |
plot_xy_coordinates_with_color(xy_and_rgb, output_png_path) | |
I had to change the plotting code to put it on the same figure in Jupyter notebook
fig, ax = plt.subplots()
ax.set_title('CIE 1931 Chromaticity Diagram')
ax.scatter(xy[:, 0], xy[:, 1], color=RGB, s=0.01, edgecolors=None, linewidths=0)
plot_chromaticity_diagram_CIE1931(show=False, show_diagram_colours=False, figure=fig, axes=ax)
# plt.savefig(output_png_path, format='png', dpi=100)
fig.show()
plt.close(fig)
@Dawars There are significant logic issues in this code version, causing the graph it generates to inaccurately represent the pixel distribution in the photo within the CIE color space.
My friend @Rachel030219 pointed out these issues and provided the fixed code. You can view the version of the code he modified here. If you want to learn more, please visit his blog (please note that the blog is in Chinese).
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The following is a set of image samples, for input images:
After processing, you can get: