简体   繁体   English

Tkinter:更改像素的颜色

[英]Tkinter:change a pixel's color

I load an image in a TkInter canvas to allow the user to draw a point by a mouse right lick button. 我将图像加载到TkInter画布中,以允许用户通过鼠标右键单击来绘制点。 After saving the coordinates of the pixel where the mouse button was pressed, I change the pixel in question to red color using OpenCV. 在保存了按下鼠标按钮的像素的坐标之后,我使用OpenCV将相关像素更改为红色。

No error occurs, however there is no effect on the picture. 没有错误发生,但是对图像没有影响。 I mean, I do not have the expected result. 我的意思是,我没有预期的结果。

may be someone could tell me what's wrong ? 也许有人可以告诉我怎么了?

import PIL.Image
import Image
import ImageTk
from Tkinter import *    
import numpy as np
import cv2    

class ExampleApp(Frame):
   def __init__(self,master):
        Frame.__init__(self,master=None)
        self.x = self.y = 0
        self.imcv=None
        self.canvas=None   

   def dessiner(self):
       # Load the imge and allow user to scroll it if it is large.
       self.canvas=Canvas(self,cursor="cross",width=600,height=600)
       self.canvas.bind("<ButtonPress-1>",self.on_button_press)
       self.sbarv=Scrollbar(self,orient=VERTICAL)
       self.sbarh=Scrollbar(self,orient=HORIZONTAL)
       self.sbarv.config(command=self.canvas.yview)
       self.sbarh.config(command=self.canvas.xview)

       self.canvas.config(yscrollcommand=self.sbarv.set)
       self.canvas.config(xscrollcommand=self.sbarh.set)

       self.canvas.grid(row=0,column=0,sticky=N+S+E+W)
       self.sbarv.grid(row=0,column=1,stick=N+S)
       self.sbarh.grid(row=1,column=0,sticky=E+W)
       self.im = PIL.Image.open("image.jpg")
       self.widt,self.heigt=self.im.size
       self.canvas.config(scrollregion=(0,0,self.widt,self.heigt))
       self.tk_im = ImageTk.PhotoImage(self.im)
       self.canvas.create_image(0,0,anchor="nw",image=self.tk_im)   


   def on_button_press(self,event):
       self.lecanvas=event.widget
       self.x=self.lecanvas.canvasx(event.x)
       self.y=self.lecanvas.canvasy(event.y)
       self.canvas.create_oval(self.x,self.y, self.x+1,self.y+1,outline='red')
       print self.x,self.y


   def resumer(self):
       self.imcv=cv2.imread("image.jpg")
       self.imcv[self.x,self.y,0]=0
       self.imcv[self.x,self.y,1]=0
       self.imcv[self.x,self.y,2]=255
       cv2.imwrite("result.jpg",self.imcv)
       cv2.namedWindow("gl",cv2.WINDOW_NORMAL)
       cv2.imshow("gl",self.imcv)
       cv2.waitKey(0)
       cv2.destroyAllWindows()






if __name__ == "__main__":
    root=Tk()
    app = ExampleApp(root)
    app.dessiner()
    app.resumer()    
    app.pack()
    root.mainloop()

Note that I also get the cv2 window displayed before the Tkinter window is displayed. 请注意,在显示Tkinter窗口之前,我还会显示cv2窗口。

EDIT: 编辑:

Following the comments of the users below, I guess I can get the coordinates of that pixel I draw on TkInter interface using a red color. 根据以下用户的评论,我想我可以使用红色获得在TkInter界面上绘制的像素的坐标。 So I want to recolor that pixel into red using OpenCV but I guess it does not take effect using OpenCV. 因此,我想使用OpenCV将像素重新着色为红色,但是我猜想它在使用OpenCV时不会生效。 Note that I must do this in OpenCV for further image processing: 请注意,我必须在OpenCV中执行此操作以进行进一步的图像处理:

def resumer(self):
       print"inside Resumer function:"
       print"Resume: ({},{})".format(self.x,self.y)
       self.imcv=cv2.imread("image.jpg")
       self.imcv[self.x,self.y,0]=0
       self.imcv[self.x,self.y,1]=0
       self.imcv[self.x,self.y,2]=255
       cv2.imwrite("result.jpg",self.imcv)
       cv2.namedWindow("gl",cv2.WINDOW_NORMAL)
       cv2.imshow("gl",self.imcv)
       cv2.waitKey(0)
       cv2.destroyAllWindows()

The order of calling the is this one now: 调用的顺序现在是这个:

if __name__ == "__main__":
    root=Tk()
    app = ExampleApp(root)
    app.pack()
    app.dessiner()
    root.mainloop()
    app.afficher_pixel()
    app.resumer() 

Any help is appreciated Thank you in advance. 感谢您的任何帮助,谢谢。

您需要更改映像的内存副本( self.tk_im )。

You mention two problems, one about changing the image and another about the cv2 window displayed before the Tkinter window. 您提到了两个问题,一个问题是更改图像,另一个问题是在Tkinter窗口之前显示的cv2窗口。

The second item is easy, so I'll address it first. 第二项很简单,所以我先解决。 It's caused by the fact that you call root.mainloop() after the call to app.resumer() (which displays the cv2 window). 它是由您致电造成的事实root.mainloop()的调用 app.resumer()它显示CV2窗口)。 You can fix either by executing app.resumer() in response to some event — say from clicking a new button you add — or more simply by moving the call to it to after root.mainloop() returns (which happens when the Tkinter window is closed by default). 您可以通过响应某些事件执行app.resumer()来解决问题app.resumer()例如,单击添加的新按钮),也可以通过 root.mainloop()返回后将调用移至(Tkinter窗口时发生)默认情况下处于关闭状态)。

The other problem about changing the pixel to red in the OpenCV window may have something to do with the self.x and self.y image coordinates you got from the Tkinter event being incorrect somehow, so I would check those and make sure you're getting the proper values and using them correctly — for example do you have them in the right order? 在OpenCV窗口中将像素更改为红色的另一个问题可能与您从Tkinter event获得的self.xself.y图像坐标不正确有关,因此我将对其进行检查并确保您获取正确的值并正确使用它们-例如,您是否按正确的顺序排列它们?

Try using canvas.update() after you change it. 更改后,尝试使用canvas.update() It could be that the code works but just doesn't show the changes on the screen. 可能是该代码可以工作,但在屏幕上没有显示更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM