Python'da belirli bir pikselin RGB değeri nasıl okunur?


141

Bir görüntüyü ile open("image.jpg")açarsam, pikselin koordinatlarına sahip olduğumu varsayarak bir pikselin RGB değerlerini nasıl alabilirim?

Peki, bunun tersini nasıl yapabilirim? Boş bir grafikle başlayarak, belirli bir RGB değerine sahip bir piksel 'yaz' mı?

Başka kitaplık indirmek zorunda kalmamayı tercih ederim.

Yanıtlar:


214

Korkarım ki bunu yapmak için Python Image Library'yi kullanmak en iyisidir .

İstediğinizi yapmanın en kolay yolu , Image nesnesinde bir dizi gibi işleyebileceğiniz bir piksel erişim nesnesini döndüren load () yöntemidir :

from PIL import Image

im = Image.open('dead_parrot.jpg') # Can be many different formats.
pix = im.load()
print im.size  # Get the width and hight of the image for iterating over
print pix[x,y]  # Get the RGBA Value of the a pixel of an image
pix[x,y] = value  # Set the RGBA Value of the image (tuple)
im.save('alive_parrot.png')  # Save the modified pixels as .png

Alternatif olarak, görüntü oluşturmak için çok daha zengin bir API sağlayan ImageDraw'a bakın .


1
Neyse ki
PIL'i

6
@ArturSapek, pipoldukça kolay olan PIL'i kurdum .
michaelliu

1
Bunu Mac'imde (Pypi) kullandım:easy_install --find-links http://www.pythonware.com/products/pil/ Imaging
Mazyod

15
Gelecekteki okuyucular için: pip install pillowPIL'i başarıyla ve oldukça hızlı bir şekilde kuracaktır ( sudobir sanal ortamda değilse gerekebilir ).
Christopher Shroba

pillow.readthedocs.io/en/latest/… , windows kurulum adımlarında bash komutlarını gösterir. Nasıl ilerleyeceğinden emin değilim.
Musixauce3000

31

Yastık kullanarak (Python 3.X ve Python 2.7+ ile çalışır) aşağıdakileri yapabilirsiniz:

from PIL import Image
im = Image.open('image.jpg', 'r')
width, height = im.size
pixel_values = list(im.getdata())

Artık tüm piksel değerlerine sahipsiniz. RGB ise veya başka bir mod tarafından okunabilir im.mode. Sonra piksel alabilirsiniz (x, y):

pixel_values[width*y+x]

Alternatif olarak, Numpy'yi kullanabilir ve diziyi yeniden şekillendirebilirsiniz:

>>> pixel_values = numpy.array(pixel_values).reshape((width, height, 3))
>>> x, y = 0, 1
>>> pixel_values[x][y]
[ 18  18  12]

Eksiksiz, kullanımı kolay bir çözüm

# Third party modules
import numpy
from PIL import Image


def get_image(image_path):
    """Get a numpy array of an image so that one can access values[x][y]."""
    image = Image.open(image_path, "r")
    width, height = image.size
    pixel_values = list(image.getdata())
    if image.mode == "RGB":
        channels = 3
    elif image.mode == "L":
        channels = 1
    else:
        print("Unknown mode: %s" % image.mode)
        return None
    pixel_values = numpy.array(pixel_values).reshape((width, height, channels))
    return pixel_values


image = get_image("gradient.png")

print(image[0])
print(image.shape)

Duman testi kodu

Genişlik / yükseklik / kanal sırası konusunda emin olamayabilirsiniz. Bu nedenle bu degradeyi oluşturdum:

resim açıklamasını buraya girin

Görüntünün genişliği 100 piksel ve yüksekliği 26 pikseldir. #ffaa00(Sarı) - #ffffff(beyaz) arasında değişen bir renk gradyanı vardır . Çıktı:

[[255 172   5]
 [255 172   5]
 [255 172   5]
 [255 171   5]
 [255 172   5]
 [255 172   5]
 [255 171   5]
 [255 171   5]
 [255 171   5]
 [255 172   5]
 [255 172   5]
 [255 171   5]
 [255 171   5]
 [255 172   5]
 [255 172   5]
 [255 172   5]
 [255 171   5]
 [255 172   5]
 [255 172   5]
 [255 171   5]
 [255 171   5]
 [255 172   4]
 [255 172   5]
 [255 171   5]
 [255 171   5]
 [255 172   5]]
(100, 26, 3)

Dikkat edilmesi gerekenler:

  • Şekil (genişlik, yükseklik, kanallar)
  • Bu image[0]nedenle, ilk satırda aynı renkten 26 üçlü var

Yastık sadece PIL'de python 2.5 desteği bulurken macosx üzerinde python 2.7'yi destekliyor. Teşekkürler!
Kanguru

2
Dikkatli olun, 'yeniden şekillendir' parametreler listesi (yükseklik, genişlik, kanallar) olmalıdır. ve rgba görüntüleri için image.mode = kanallı RGBA = 4
gmarsi

@Gmarsi'nin noktası genişlik ve yükseklik açısından doğru mu? Her ikisinin de geçerli olması gerçekten geçerli mi? Çıktı dizisinin hangi şekle sahip olacağını ve görüntünün satır ve sütun piksel verilerinin nerede olacağını bilmek için verilerin nasıl çıktı aldığını bilmeniz gerekir.
Kioshiki

@Kioshiki Cevabıma bir "duman testi" bölümü ekledim, bu yüzden anlatmak daha kolay.
Martin Thoma

24

PyPNG - Hafif PNG kod çözücü / kodlayıcı

Soru JPG'ye işaret etse de, umarım cevabım bazı insanlar için faydalı olacaktır.

PyPNG modülünü kullanarak PNG piksellerini nasıl okuyacağınız ve yazacağınız aşağıda açıklanmıştır :

import png, array

point = (2, 10) # coordinates of pixel to be painted red

reader = png.Reader(filename='image.png')
w, h, pixels, metadata = reader.read_flat()
pixel_byte_width = 4 if metadata['alpha'] else 3
pixel_position = point[0] + point[1] * w
new_pixel_value = (255, 0, 0, 0) if metadata['alpha'] else (255, 0, 0)
pixels[
  pixel_position * pixel_byte_width :
  (pixel_position + 1) * pixel_byte_width] = array.array('B', new_pixel_value)

output = open('image-with-red-dot.png', 'wb')
writer = png.Writer(w, h, **metadata)
writer.write_array(output, pixels)
output.close()

PyPNG, testler ve yorumlar da dahil olmak üzere 4000 satırdan daha kısa tek bir saf Python modülüdür.

PIL daha kapsamlı bir görüntüleme kütüphanesidir, ancak aynı zamanda önemli ölçüde daha ağırdır.


12

Dave Webb'in dediği gibi:

İşte bir görüntüden piksel renklerini yazdırmak için çalışma kodu snippet'im:

import os, sys
import Image

im = Image.open("image.jpg")
x = 3
y = 4

pix = im.load()
print pix[x,y]

6
photo = Image.open('IN.jpg') #your image
photo = photo.convert('RGB')

width = photo.size[0] #define W and H
height = photo.size[1]

for y in range(0, height): #each pixel has coordinates
    row = ""
    for x in range(0, width):

        RGB = photo.getpixel((x,y))
        R,G,B = RGB  #now you can use the RGB value

3

Görüntü manipülasyon karmaşık bir konudur ve eğer en iyisi yapmak kütüphane kullanın. Ben tavsiye edebilir gdmodule Python içinden birçok farklı görüntü formatları kolay erişim sağlar.


Bunun neden indirildiğini bilen var mı? Libgd veya başka bir şeyle ilgili bilinen bir sorun var mı? (Daha önce hiç bakmamıştım, ama PiL'ye bir alternatif olduğunu bilmek her zaman güzeldir)
Peter Hanley

3

Wiki.wxpython.org sitesinde Görüntülerle Çalışma başlıklı gerçekten iyi bir makale var . Makale, wxWidgets (wxImage), PIL veya PythonMagick kullanma olasılığından bahsetmektedir. Şahsen, PIL ve wxWidgets kullandım ve her ikisi de görüntü manipülasyonunu oldukça kolaylaştırıyor.


3

Sen kullanabilirsiniz pygame 'ın surfarray modülü. Bu modül, pixel3d (yüzey) adı verilen bir 3d piksel dizi döndürme yöntemine sahiptir. Aşağıda kullanımı gösterdim:

from pygame import surfarray, image, display
import pygame
import numpy #important to import

pygame.init()
image = image.load("myimagefile.jpg") #surface to render
resolution = (image.get_width(),image.get_height())
screen = display.set_mode(resolution) #create space for display
screen.blit(image, (0,0)) #superpose image on screen
display.flip()
surfarray.use_arraytype("numpy") #important!
screenpix = surfarray.pixels3d(image) #pixels in 3d array:
#[x][y][rgb]
for y in range(resolution[1]):
    for x in range(resolution[0]):
        for color in range(3):
            screenpix[x][y][color] += 128
            #reverting colors
screen.blit(surfarray.make_surface(screenpix), (0,0)) #superpose on screen
display.flip() #update display
while 1:
    print finished

Umarım yardımcı olmuştur. Son sözcük: ekran, ekranın ömrü boyunca kilitlendi


2

"sudo apt-get install python-imaging" komutunu kullanarak PIL'i kurun ve aşağıdaki programı çalıştırın. Görüntünün RGB değerlerini basacaktır. Görüntü büyükse, çıktıyı '>' kullanarak bir dosyaya yönlendirin, daha sonra RGB değerlerini görmek için dosyayı açın

import PIL
import Image
FILENAME='fn.gif' #image can be in gif jpeg or png format 
im=Image.open(FILENAME).convert('RGB')
pix=im.load()
w=im.size[0]
h=im.size[1]
for i in range(w):
  for j in range(h):
    print pix[i,j]

2

Tk GUI araç setinin standart Python arabirimi olan Tkinter modülünü kullanabilirsiniz ve fazladan indirmenize gerek yoktur. Bkz. Https://docs.python.org/2/library/tkinter.html .

(Python 3 için Tkinter, tkinter olarak yeniden adlandırılmıştır)

RGB değerlerini nasıl ayarlayacağınız aşağıda açıklanmıştır:

#from http://tkinter.unpythonic.net/wiki/PhotoImage
from Tkinter import *

root = Tk()

def pixel(image, pos, color):
    """Place pixel at pos=(x,y) on image, with color=(r,g,b)."""
    r,g,b = color
    x,y = pos
    image.put("#%02x%02x%02x" % (r,g,b), (y, x))

photo = PhotoImage(width=32, height=32)

pixel(photo, (16,16), (255,0,0))  # One lone pixel in the middle...

label = Label(root, image=photo)
label.grid()
root.mainloop()

Ve RGB'yi edinin:

#from http://www.kosbie.net/cmu/spring-14/15-112/handouts/steganographyEncoder.py
def getRGB(image, x, y):
    value = image.get(x, y)
    return tuple(map(int, value.split(" ")))

2
from PIL import Image
def rgb_of_pixel(img_path, x, y):
    im = Image.open(img_path).convert('RGB')
    r, g, b = im.getpixel((x, y))
    a = (r, g, b)
    return a

1
Bu kod snippet'i çözüm olsa da, bir açıklama da dahil olmak üzere mesajınızın kalitesini artırmaya yardımcı olur. Gelecekte okuyucular için soruyu cevapladığınızı ve bu kişilerin kod önerinizin nedenlerini bilmeyebileceğini unutmayın.
Narendra Jadhav

1
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

img=mpimg.imread('Cricket_ACT_official_logo.png')
imgplot = plt.imshow(img)

1

RGB renk kodu biçiminde üç basamağa sahip olmak istiyorsanız, aşağıdaki kod tam olarak bunu yapmalıdır.

i = Image.open(path)
pixels = i.load() # this is not a list, nor is it list()'able
width, height = i.size

all_pixels = []
for x in range(width):
    for y in range(height):
        cpixel = pixels[x, y]
        all_pixels.append(cpixel)

Bu sizin için işe yarayabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.