【问题标题】:TypeError: function takes exactly 2 arguments (1 given)TypeError:函数只需要 2 个参数(给定 1 个)
【发布时间】:2018-07-17 13:48:10
【问题描述】:

尝试了不同的可能性,终于要发帖了:

此程序将向用户显示图像。用户将使用鼠标单击来单击图像的不同区域。每次鼠标点击时,点都会被收集到 list_of_points 列表中。在鼠标右键单击时,我想从 list_of_points 列表中生成一个多边形。多边形库必须是

PIL.ImageDraw.Draw.polygon(xy, fill=None, outline=None)

我反复收到以下错误:

TypeError: 函数只需要 2 个参数(给定 1 个)

这个错误:

self.draw.draw_polygon(xy, ink, 0) SystemError: new style getargs format but argument is not a tuple

代码如下:

from Tkinter import *
import Image, ImageTk, ImageDraw
import numpy as np

coord=[]  # for saving coord of each click position
Dict_Polygon={}   # Dictionary for saving polygon
list_of_points=[]
flag=True
label=0

# Input image
img = Image.open("test.jpg")
draw = ImageDraw.Draw(img)
def draw_lines(event):

    mouse_xy = (event.x, event.y)
    func_Draw_lines(mouse_xy)


def func_Draw_lines(mouse_xy):

    center_x, center_y = mouse_xy
    if canvas.old_coords:
            x1, y1 = canvas.old_coords
            canvas.create_line(center_x, center_y, x1, y1)

    # add clicked positions to list
    if flag==True:
        list_of_points.append(mouse_xy)
        canvas.old_coords = center_x, center_y

def draw_poly(event):

    numberofPoint=len(list_of_points)
    if numberofPoint>2:

        #draw =ImageDraw.Draw(img)
        poly=zip(list_of_points)
        print(poly)

        draw.polygon(poly, fill=None, outline=(255, 0, 0))
     #   label= canvas.create_polygon(list_of_points, fill='', outline='green', width=2)
        canvas.old_coords=None
        list_of_points[:]=[]

# Main function
if __name__ == '__main__':

    root = Tk()    

# Draw canvas for iput image to pop up image for clicks
    filename = ImageTk.PhotoImage(img)
    canvas = Canvas(root,height=img.size[0],width=img.size[0])
    canvas.image = filename
    canvas.create_image(0,0,anchor='nw',image=filename)
    canvas.pack()
    canvas.old_coords = None
# bind function to canvas to generate event
    canvas.bind("<Button 3>", draw_lines)
    canvas.bind("<Button 1>", draw_poly)
    root.mainloop()

`

【问题讨论】:

  • 你做了一个print (poly),我们可以得到这个变量的内容吗?
  • zip(list_of_points) 那么 poly 中的值是:[((411, 113),), ((158, 169),), ((344, 364),)]
  • poly=tuple(list_of_points) poly 中的值是:((432, 224), (196, 245), (268, 379)) 没有错误,但我没有绘制多边形。
  • @john 多边形是在 PIL 图像上绘制的,而不是在画布上显示的 PhotoImage 上,这就是我们看不到它的原因。
  • 如何在 PhotoImage 上为我处理画布和 PIL 的这个特定程序获取它?

标签: python tkinter python-imaging-library


【解决方案1】:

你需要一种格式,比如 -

[(411, 113), (158, 169), (344, 364)]

但是你传递的是元组的元组-

((411, 113),), ((158, 169),), ((344, 364),)]

试试这个结构 -

[(432, 224), (196, 245), (268, 379)]

或者直接列出也可以 -

[432, 224, 196, 245, 268, 379]

查看文档here

当函数期望两个元组时,元组的元组成为函数的一个参数。您不需要zip(poly),只需传递numberofPoint 就可以了。让我知道这是否有帮助

【讨论】:

  • 当我打印 list_of_points 的内容时,我得到了结果:[[266, 126], [154, 238], [350, 266]],如何将它转换成这个结构:[( 432, 224), (196, 245), (268, 379)]
  • 这样的事情会做[(i[0], i[1]) for i in x]
【解决方案2】:

当我直接将list_of_points 传递给draw.polygon 时,它工作正常,所以不需要任何转换。

但是,多边形是在 PIL 图像上绘制的,而不是在画布中显示的 PhotoImage 上。因此,要查看多边形,您需要更新 PhotoImage。这样做的方法是使用ImageTk.PhotoImage.paste 方法。

这里是 draw_poly 函数的变化:

def draw_poly(event):
    numberofPoint = len(list_of_points)
    if numberofPoint>2:
        draw.polygon(list_of_points, outline=(255, 0, 0))  # replaced poly by list_of_points
        canvas.old_coords = None
        canvas.image.paste(img)   # update displayed image
        list_of_points[:]=[]

【讨论】:

    猜你喜欢
    • 2018-08-20
    • 1970-01-01
    • 1970-01-01
    • 2017-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-04
    相关资源
    最近更新 更多