如何根据像素颜色值(R、G、B)创建图像

huangapple go评论82阅读模式
英文:

How to create an image from pixel color values (R, G, B)

问题

I am new to python (also to stackoverflow) and I need help with combining pixel color values into an image.

After searching through the web and playing around with the codes mentioned, I eventually used the following code to get the color values from a given image:

from PIL import Image  

filename = "INSERT_PATH_OF_IMAGE"  
image = Image.open(filename)  

t = list(image.getdata())  
r = list(image.getdata(0))  
g = list(image.getdata(1))  
b = list(image.getdata(2))  

print(r)  
print(g)  
print(b)  
print(image)  

This outputs the numerical values of the given pixels of the given image like so:

[r_value1, r_value2, ..]
[g_value1, g_value2, ..]
[b_ , b_..]

How from here would the pixel-coordinates of the colors be identified and how could they be put together into an image?

How can the print-command be structured such that

[(r_value1, g_value1, b_value1), 
(r_value2, g_value2, ..)]

would be the output shown?

Because (depending on image size) the amount of values shown can exceed the output terminal record (Using Pycharm), how could the printed result instead be saved in a text file? (Like: Editor on Windows OS)

The eventual goal is to create an algorithm to use with opencv (probably) with which to process images, I thought I should start with understanding how to process just standard images from pixeldata first and progress from there.

Thanks for reading!

P.S. I welcome any and every advice on what sources I should read up on, so feel free to share. =)

英文:

I am new to python (also to stackoverflow) and I need help with combining pixel color values into an image.

After searching through the web and playing around with the codes mentioned, I eventually used the following code to get the color values from a given image:

    from PIL import Image  

    filename = "INSERT_PATH_OF_IMAGE"  
    image = Image.open(filename)  

    t = list(image.getdata())  
    r = list(image.getdata(0))  
    g = list(image.getdata(1))  
    b = list(image.getdata(2))  

    print(r)  
    print(g)  
    print(b)  
    print(image)  

This outputs the numerical values of the given pixels of the given image like so:

    [r_value1, r_value2, ..]
    [g_value1, g_value2, ..]
    [b_ , b_..]

How from here would the pixel-coordinates of the colors be identified and how could they be put together into an image?

How can the print-command be structured such that

    [(r_value1, g_value1, b_value1), 
    (r_value2, g_value2, ..)]

would be the output shown?

Because (depending on image size) the amount of values shown can exceed the output terminal record (Using Pycharm), how could the printed result instead be saved in a text file? (Like: Editor on Windows OS)

The eventual goal is to create an algorithm to use with opencv (probably) with which to process images, I thought I should start with understanding how to process just standard images from pixeldata first and progress from there.

Thanks for reading!

P.S. I welcome any and every advice on what sources I should read up on, so feel free to share. =)

答案1

得分: 2

在评论中提到,尽量避免使用Python列表来存储图像像素 - 它们速度慢且效率低下。最好使用NumPy数组和NumPy或OpenCV进行矢量化处理。

from PIL import Image
import numpy as np

# 创建线性渐变并调整大小为8x8,以便查看
gradient = Image.linear_gradient('L').resize((8, 8))

如何根据像素颜色值(R、G、B)创建图像

# 旋转以使其有趣
gradient90 = gradient.rotate(90)

如何根据像素颜色值(R、G、B)创建图像

# 创建一个尺寸相同的纯黑色图像
black = Image.new('L', (8, 8))

# 将3个通道合并为RGB
rgb = Image.merge('RGB', (gradient, gradient90, black))
rgb.show()

如何根据像素颜色值(R、G、B)创建图像

# 转换为NumPy数组
na = np.array(rgb)

# 调整形状为8x8x3的RGB数组,变成64x3的三元组
triplets = na.reshape((-1, 3))
print(triplets)
[[ 16  16   0]
 [ 16  47   0]
 [ 16  80   0]
 [ 16 112   0]
 [ 16 144   0]
 [ 16 176   0]
 [ 16 208   0]
 [ 16 239   0]
 [ 47  16   0]
 [ 47  47   0]
 [ 47  80   0]
 [ 47 112   0]
 [ 47 144   0]
 [ 47 176   0]
 [ 47 208   0]
 [ 47 239   0]
 [ 80  16   0]
 [ 80  47   0]
 [ 80  80   0]
 [ 80 112   0]
 [ 80 144   0]
 [ 80 176   0]
 [ 80 208   0]
 [ 80 239   0]
 [112  16   0]
 [112  47   0]
 [112  80   0]
 [112 112   0]
 [112 144   0]
 [112 176   0]
 ...
 ...
 [239 208   0]
 [239 239   0]]

保存为CSV

np.savetxt('image.csv', triplets, fmt='%i', delimiter=',')

16,16,0
16,47,0
16,80,0
16,112,0
16,144,0
16,176,0
16,208,0
16,239,0
47,16,0
47,47,0
47,80,0
...
...

如果您想将CSV输出到PyCharm终端,即stdout,您可以使用:

import sys

np.savetxt(sys.stdout, triplets, fmt='%i', delimiter=',')

如果您想要从CSV加载图像,您需要知道其原始形状,因为它不存储在CSV中。请注意,将图像存储在CSV中通常不是一个好主意,因为它既不高效,也不可压缩,也无法查看。

加载图像的步骤如下:

# 从CSV加载像素到NumPy数组并调整形状为原始形状
pixels = np.loadtxt('image.csv', delimiter=',', dtype=np.uint8).reshape((8, 8, 3))

# 将NumPy数组转换为PIL图像
im = Image.fromarray(pixels)

# 在屏幕上显示
im.show()

# 保存到磁盘
im.save('result.png')
英文:

As mentioned in the comments, try to avoid Python lists of image pixels - they are slow and inefficient. Prefer instead Numpy arrays and vectorised processing by Numpy or OpenCV.

from PIL import Image
import Numpy as np

# Make a linear gradient and resize to 8x8 so we can see it
gradient = Image.linear_gradient('L').resize((8,8))

如何根据像素颜色值(R、G、B)创建图像

# Rotate to make interesting
gradient90 = gradient.rotate(90)

如何根据像素颜色值(R、G、B)创建图像

# Make a solid black image same size
black = Image.new('L', (8,8))

# Merge the 3 channels into RGB
rgb = Image.merge('RGB',(gradient, gradient90, black))
rgb.show()

如何根据像素颜色值(R、G、B)创建图像

# Make into Numpy array
na = np.array(rgb)

# Reshape as 8x8x3 RGB array into 64x3 triplets
triplets = na.reshape((-1,3))
print(triplets)

[[ 16  16   0]
 [ 16  47   0]
 [ 16  80   0]
 [ 16 112   0]
 [ 16 144   0]
 [ 16 176   0]
 [ 16 208   0]
 [ 16 239   0]
 [ 47  16   0]
 [ 47  47   0]
 [ 47  80   0]
 [ 47 112   0]
 [ 47 144   0]
 [ 47 176   0]
 [ 47 208   0]
 [ 47 239   0]
 [ 80  16   0]
 [ 80  47   0]
 [ 80  80   0]
 [ 80 112   0]
 [ 80 144   0]
 [ 80 176   0]
 [ 80 208   0]
 [ 80 239   0]
 [112  16   0]
 [112  47   0]
 [112  80   0]
 [112 112   0]
 [112 144   0]
 [112 176   0]
 ...
 ...
 [239 208   0]
 [239 239   0]]

# Save as CSV
np.savetxt('image.csv', triplets, fmt='%i', delimiter=',')

16,16,0
16,47,0
16,80,0
16,112,0
16,144,0
16,176,0
16,208,0
16,239,0
47,16,0
47,47,0
47,80,0
...
...

If you want to output the CSV to your PyCharm terminal, i.e. stdout, you can use:

import sys

np.savetxt(sys.stdout, triplets, fmt='%i', delimiter=',')

If you want to load the image back from the CSV, you will need to know its original shape because that is not stored in the CSV. Note that it is generally a poor idea to store an image in a CSV because it is neither efficient, nor compressible, nor viewable.

It would go like this:

# Load pixels from CSV into Numpy array and reshape to original shape
pixels = np.loadtxt('image.csv', delimiter=',', dtype=np.uint8).reshape((8,8,3))

# Convert Numpy array into PIL Image
im = Image.fromarray(pixels)

# Display on screen
im.show()

# Save to disk
im.save('result.png')

huangapple
  • 本文由 发表于 2023年7月24日 17:54:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/76753310.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定