파이썬에서 주어진 픽셀의 RGB 값을 읽는 방법은 무엇입니까?


140

로 이미지를 열면 open("image.jpg")픽셀의 좌표가 있다고 가정하면 픽셀의 RGB 값을 어떻게 얻을 수 있습니까?

그런 다음 어떻게 반대로 할 수 있습니까? 빈 그래픽으로 시작하여 특정 RGB 값으로 픽셀을 '쓰기'하시겠습니까?

추가 라이브러리를 다운로드 할 필요가없는 경우 선호합니다.

답변:


213

파이썬 이미지 라이브러리 를 사용 하여이 작업을 수행 하는 것이 가장 좋습니다 . 별도의 다운로드입니다.

원하는 것을 수행하는 가장 쉬운 방법 은 배열과 같이 조작 할 수있는 픽셀 액세스 객체를 반환하는 Image 객체load () 메서드를 사용 하는 것입니다.

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

또는 이미지 생성을위한 훨씬 풍부한 API를 제공하는 ImageDraw 를 보십시오 .


1
다행스럽게도 PIL 설치는 Linux와 Windows에서 매우 간단합니다 (Mac에 대해 잘 모름)
heltonbiker

6
@ArturSapek, 나는 pip매우 쉬운 PIL을 설치했습니다 .
michaelliu

1
나는 이것을 나의 Mac (Pypi)에서 사용했다 :easy_install --find-links http://www.pythonware.com/products/pil/ Imaging
Mazyod

15
향후 독자를 위해 : pip install pillowPIL을 성공적으로 그리고 신속하게 설치 sudo합니다 (virtuenv가 아닌 경우 필요할 수 있음 ).
Christopher Shroba 1

pillow.readthedocs.io/en/latest/… 는 Windows 설치 단계에서 bash 명령을 보여줍니다. 진행 방법을 잘 모르겠습니다.
Musixauce3000

31

사용 베개 (2.7 이상 파이썬뿐만 아니라 파이썬 3.X와 함께 작동), 다음을 수행 할 수 있습니다 :

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

이제 모든 픽셀 값이 있습니다. RGB이거나 다른 모드이면로 읽을 수 있습니다 im.mode. 그러면 다음을 통해 픽셀 (x, y)을 얻을 수 있습니다 .

pixel_values[width*y+x]

또는 Numpy를 사용하여 배열을 재구성 할 수 있습니다.

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

완전하고 사용하기 쉬운 솔루션은

# 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)

코드 연기 테스트

너비 / 높이 / 채널 순서가 확실하지 않을 수 있습니다. 이런 이유로 나는이 그라디언트를 만들었습니다 :

여기에 이미지 설명을 입력하십시오

이미지의 너비는 100px, 높이는 26px입니다. #ffaa00(노란색)에서 #ffffff(흰색) 까지 색상 그라데이션이 있습니다 . 출력은 다음과 같습니다.

[[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)

참고 사항 :

  • 모양은 (너비, 높이, 채널)
  • image[0], 따라서 첫 번째 행은 동일한 색상을 가지고 26 루타

필로우는 macosx에서 python 2.7을 지원하지만 PIL에서는 python 2.5 만 지원합니다. 감사!
Kangaroo.H

2
'모양'매개 변수 목록은 높이, 너비, 채널이어야합니다. rgba 이미지의 경우 image.mode = RGBA (채널 = 4)
gmarsi

너비와 높이에서 @gmarsi의 포인트가 true입니까? 실제로 둘 다 유효합니까? 데이터가 어떻게 출력되는지 알고 있어야 출력 배열의 모양과 이미지의 행 및 열 픽셀 데이터의 위치를 ​​알 수 있습니다.
키오 시키

@Kioshiki 대답하기 쉽게 "연기 테스트"섹션을 추가했습니다.
마틴 토마

24

PyPNG-경량 PNG 디코더 / 인코더

질문은 JPG에 암시되지만 내 답변이 일부 사람들에게 도움이되기를 바랍니다.

PyPNG 모듈을 사용하여 PNG 픽셀을 읽고 쓰는 방법은 다음과 같습니다 .

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는 테스트 및 주석을 포함하여 4000 줄 미만의 단일 순수 Python 모듈입니다.

PIL 은보다 포괄적 인 이미징 라이브러리이지만 훨씬 더 무겁습니다.


12

Dave Webb가 말했듯이 :

다음은 이미지에서 픽셀 색상을 인쇄하는 작업 코드 스 니펫입니다.

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

이미지 조작은 복잡한 주제이며, 당신이 경우 가장있어 않는 라이브러리를 사용합니다. 파이썬에서 다양한 이미지 형식에 쉽게 액세스 할 수있는 gdmodule 을 추천 할 수 있습니다 .


왜 이것이 다운 다운되었는지 아는 사람이 있습니까? libgd 또는 기타 알려진 문제가 있습니까? (나는 그것을 보지 못했지만 PiL에 대한 대안이 있다는 것을 항상 아는 것이 좋습니다)
Peter Hanley

3

wiki.wxpython.org 에는 이미지 작업 이라는 제목의 기사가 있습니다. 이 기사에서는 wxWidgets (wxImage), PIL 또는 PythonMagick의 사용 가능성에 대해 언급합니다. 개인적으로 PIL과 wxWidgets를 사용했으며 이미지 조작이 상당히 쉬워졌습니다.


3

pygame 의 surfarray 모듈을 사용할 수 있습니다 . 이 모듈에는 pixels3d (surface)라는 3D 픽셀 배열 반환 방법이 있습니다. 아래에 사용법이 나와 있습니다.

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

도움이 되었기를 바랍니다. 마지막 단어 : screenpix의 수명 동안 화면이 잠겨 있습니다.


2

"sudo apt-get install python-imaging"명령을 사용하여 PIL을 설치하고 다음 프로그램을 실행하십시오. 이미지의 RGB 값을 인쇄합니다. 이미지가 큰 경우 '>'를 사용하여 출력을 파일로 리디렉션하고 나중에 파일을 열어 RGB 값을 확인하십시오.

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 툴킷에 대한 표준 Python 인터페이스 인 Tkinter 모듈을 사용할 수 있으며 추가 다운로드가 필요하지 않습니다. https://docs.python.org/2/library/tkinter.html을 참조 하십시오 .

(파이썬 3의 경우 Tkinter의 이름이 tkinter로 변경됨)

RGB 값을 설정하는 방법은 다음과 같습니다.

#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()

그리고 RGB를 얻으십시오 :

#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
이 코드 스 니펫은 설명을 포함 하여 해결책이 될 수 있지만 게시물의 품질을 향상시키는 데 실제로 도움이됩니다. 앞으로 독자들에게 질문에 대한 답변을 제공하므로 해당 사람들이 코드 제안의 이유를 모를 수도 있습니다.
Narendra Jadhav 2012 년

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 색상 코드의 형태로 3 자리 숫자를 찾으려면 다음 코드를 사용하십시오.

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)

이것은 당신을 위해 일할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.