Python 3: преобразование изображения в оттенки серого - PullRequest
1 голос
/ 28 сентября 2010

Я пытаюсь выполнить упражнение в книге Джона Зелле «Программирование на Python: введение в информатику». Я скачал специальный графический пакет для его книги ( graphics.py , который находится на связанном веб-сайте). Вопрос звучит так:

Напишите программу, которая преобразует цветное изображение в оттенки серого. Пользователь указывает имя файла, содержащего изображение в формате GIF или PPM, а программа загружает изображение и отображает файл. По щелчку мыши программа преобразует изображение в оттенки серого. Затем пользователю предлагается указать имя файла для сохранения изображения в градациях серого.

Возможно, вы захотите вернуться и просмотреть объект Image из графической библиотеки (раздел 4.8.4). Основная идея для преобразования изображения состоит в том, чтобы пройти его по пикселям и преобразовать каждое из цветов в соответствующий оттенок серого. Серый пиксель создается путем установки его красной, зеленой и синей составляющих, чтобы они имели одинаковую яркость. Итак, color_rgb(0, 0, 0) - это черный, color_rgb(255, 255, 255) - это белый, а color_rgb(127, 127, 127) - это серый "посередине". Вы должны использовать средневзвешенное значение исходных значений RGB для определения яркости серого. Вот псевдокод для алгоритма серой шкалы [по какой-то причине отступ в четыре пробела не работает при предварительном просмотре]:

for each row in the image:  
    for each column in the image:  
        r, g, b = get pixel information for current row and column  
        brightness = int(round(0.299r + 0.587g + 0.114b))  
    update the image # to see progress row by row

Примечание: операции с пикселями в классе Image довольно медленные, поэтому вы можете использовать относительно маленькие изображения ( не 12 мегапикселей) для тестирования вашей программы.


Я работал над этим часами. Это последняя версия моего кода:

# grayscale.py

from graphics import *

def main():  
    infileName = input("File name: ")  
    outfileName = input("Save to: ")

    image = Image(Point(100,100), infileName)
    width = image.getWidth()
    height = image.getHeight()
    win = GraphWin("rgb")
    image.draw(win)

    row = 0
    column = 0

    win.getMouse()

    for row in range(200):
        for column in range(200):
            r, g, b = image.getPixel(row, column)
            brightness = int(round(0.299 * r + 0.587 * g + 0.114 * b))
            image.setPixel(row, column, color_rgb(brightness, brightness, brightness))
            win.update()

    win.getMouse()
    win.close()

main()

Наконец-то я понял, что Python не дает мне никаких сообщений об ошибках. Но все, что делает программа, это загружает изображение, делает пару щелчков мышью и затем закрывается. Я вводил входной файл как U: \ My Pictures \ yay.gif, а выходной файл как U: \ My Pictures \ yay2.gif. Но я только что искал свой компьютер и U: \ My Pictures \ yay2.gif не существует. Что я делаю неправильно? Кстати, это НЕ для класса - у меня нет инструктора, чтобы спросить.

Может быть, я должен следить за этим сообщением. Я добавил функцию сохранения, но получил изображение с полутоновым окном 200x200 и остальным цветом. Итак, вот некоторые строки, которые я изменил:

win = GraphWin("rgb", width, height)
for row in range(height):
    for column in range(width):

И я получаю следующее сообщение об ошибке: Traceback (последний вызов был последним):
Файл "C: \ Python31 \ grayscale.py", строка 31, в
Основной ()
Файл "C: \ Python31 \ grayscale.py", строка 22, в основном
r, g, b = image.getPixel (строка, столбец)
Файл "C: \ Python31 \ lib \ graphics.py", строка 810, в getPixel
значение = self.img.get (x, y)
Файл "C: \ Python31 \ lib \ tkinter_ init _. Py", строка 3301, в get
вернуть self.tk.call (self.name, 'get', x, y)
_tkinter.TclError: pyimage1 get: координаты вне диапазона

Я понимаю, что мне, вероятно, нужно изменить точку привязки изображения к центру. Но я могу определить это только по ширине и высоте изображения, и мне нужно сначала загрузить изображение, чтобы получить эти значения. Есть ли обходной путь?

Ответы [ 4 ]

3 голосов
/ 28 сентября 2010

Вы не сохраняете изображение. Обратите внимание, что переменная outfileName никогда не используется. Вы должны передать его какой-то функции сохранения. бросил быстрый взгляд на graphics.py, думаю, это то, что вам нужно:

EDIT

Чтобы решить проблему с преобразованием только одного угла, сделайте это, вместо этого ваш старый код преобразовывал только первые 200x200 пикселей. Я также изменил диапазон на xrange, не обязательно, но более эффективно.

for row in xrange(height):
        for column in xrange(windth):
1 голос
/ 24 октября 2017

Я знаю, что это старый пост, но.Я думаю, что ваша проблема - это фактическое изображение, которое вы используете.Измените разрешение изображения до 200 пикселей на дюйм.

0 голосов
/ 28 октября 2017

Лучше, чтобы все было просто.Программа просит сохранить файл, который был забыт в конце, и использовать getMouse (), чтобы получить «текущий пиксель», который вы используете getX () и getY ().Вот лучший пример с использованием graphics.py

grayscale.py

from graphics import*

print("This program grayscales images\n")# intro 

def grayscale(): # Obtaining file
    infile = input('In what file is the image?: ')
    outfile = input('What file do you want it saved?: ')

#   Using image file to get dynamics of window. You don't have to create a window either to obtain it. 

    file = Image(Point(0,0), infile)
    width = file.getWidth()
    height = file.getHeight()

#   Getting center point of photo
    cWidth = width / 2
    cHeight = height / 2
    cen = Point(cWidth, cHeight)

#   Ready for window
    image = Image(cen,infile)
    win = GraphWin("Grayscale Image", width, height)
    image.draw(win)


#   Getting current Pixel for loop
    p = win.getMouse()
    x = p.getX()
    y = p.getY()

    for x in range(height):
        for y in range(width):
            r, g, b = image.getPixel(x, y)
            gray = int(round(.299*r + .587*g + .114*b))
            image.setPixel(x,y, color_rgb(gray, gray, gray))
        # i accidentally mixed my x and y variable and it spit
        # out a two-headed cyclops tee hee 
            win.update()

# Click to exit 
    image.save(outfile)
    win.getMouse()
    win.close()

grayscale()
0 голосов
/ 28 сентября 2010

Я не вижу никакого использования outfileName после его установки - другими словами, вы, кажется, никогда, никогда не сохраняете результат в этот файл (или любой другой файл, в этом отношении ).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...