簡體   English   中英

Python 3:將圖像轉換為灰度

[英]Python 3: Converting image to grayscale

我正試着在John Zelle的“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類中的像素操作相當慢,因此您需要使用相對較小的圖像( 不是 1200萬像素)來測試您的程序。


我這幾個小時都在研究這個問題。 這是我的代碼的最新版本:

# 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行,in
主要()
文件“C:\\ Python31 \\ grayscale.py”,第22行,在main中
r,g,b = image.getPixel(row,column)
在getPixel中的文件“C:\\ Python31 \\ lib \\ graphics.py”,第810行
value = self.img.get(x,y)
在get中輸入文件“C:\\ Python31 \\ lib \\ tkinter_ init _.py”,第3301行
return self.tk.call(self.name,'get',x,y)
_tkinter.TclError:pyimage1 get:坐標超出范圍

我知道我可能需要將圖像的錨點更改為中心。 但我只能通過圖像的寬度和高度來確定,我必須先上傳圖像才能獲得這些值。 有解決方法嗎?

您沒有保存圖像。 請注意,永遠不會使用變量outfileName。 你應該將它傳遞給某種保存功能。 快速瀏覽一下graphics.py,我想這就是你需要的:

編輯

要解決它只轉換一個角落的問題,請改為執行此操作,舊代碼僅轉換前200x200像素。 我也將范圍改為xrange,沒有必要,但效率更高。

for row in xrange(height):
        for column in xrange(windth):

我知道這是一個老帖子但是。 我認為你的問題是你正在使用的實際圖像。 將圖像分辨率更改為每英寸200像素。

在設置之后我沒有看到outfileName任何使用 - 換句話說,你似乎永遠不會結果保存到該文件(或任何其他文件)。

最好保持簡單。 程序要求保存最后忘記的文件,並使用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()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM