我正在尝试在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):
我收到以下错误消息:
追溯(最近的呼叫最后):
文件“C:\ Python31 \ grayscale.py”,第31行,中
主()
文件“C:\ Python31 \ grayscale.py”,第22行,在主体中
r,g,b = image.getPixel(row,column)
在getPixel中文件“C:\ Python31 \ lib \ graphics.py”,第810行
value = self.img.get(x,y)
文件“C:\ Python31 \ lib \ tkinter_ init _。py”,第3301行,在获取中
return self.tk.call(self.name,'get',x,y)
_tkinter.TclError:pyimage1 get:坐标超出范围
据我所知,我可能需要将图像的锚点更改为中心。但我只能通过图像的宽度和高度来确定,我必须先上传图像才能获得这些值。有解决方法吗?
答案 0 :(得分:3)
您没有保存图像。请注意,永远不会使用变量outfileName。你应该将它传递给某种保存功能。快速浏览一下graphics.py,我认为这就是你需要的:
修改强>
要解决仅转换一个角落的问题,请执行此操作,旧代码仅转换前200x200像素。我也将范围改为xrange,没有必要,但效率更高。
for row in xrange(height):
for column in xrange(windth):
答案 1 :(得分:1)
我知道这是一个老帖子但是。我认为你的问题是你正在使用的实际图像。将图像分辨率更改为每英寸200像素。
答案 2 :(得分:0)
在设置之后我没有看到outfileName
的使用 - 换句话说,你似乎永远不会将结果保存到该文件(或任何其他文件,就此而言)。
答案 3 :(得分:0)
最好保持简单。该程序要求保存最后忘记的文件,并使用getMouse()来获取当前像素"你使用getX()和getY()。这是使用graphics.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()