So as the title says, I'm working on a very basic image editor project using Tkinter and openCV with the ability to rotate the image left and right, do a histogram equalization, apply a median filter, etc, so far the only thing that works is displaying 2 images in the appropriate panels and an option to import it in greyscale.
The panelSRC should display the input image and panelDST should display the output image
The "gray?" checkbox works fine.
I think the errors I get are function related errors but they are so presistent, for example:
rotanticlk = tk.Button(root, text="RotLeft", command=rotate_left)
would give an error of
Unresolved reference
Well that would get fixed if I remove the indentations, BUT that will not make it work upon pressing the button which is the goal I want to reach
Even if the function is right there above it, it still marks the rotate_right with an error, fix it by putting no indentations for the rotate_right function and write it without spaces? Well, that will not make the button do its work when it is pressed.
Do I put the parameter image in the function (e.g: def rotateleft(image):
)? No still errors
*line 1883, in call return self.func(args)
TypeError: rotate_left() missing 1 required positional argument: 'image'
Changing the places of functions? Same problem.
Here is the full code
import tkinter as tk
from PIL import Image
from PIL import ImageTk
from tkinter import filedialog
import cv2
import numpy as np
def select_image():
# grab a reference to the image panels
global panelSRC, panelDST
path = filedialog.askopenfilename()
# ensure a file path was selected
if len(path) > 0:
# load the image from disk, convert it to grayscale, and detect
# edges in it
image = cv2.imread(path)
edited = image*1
if vargray.get() == 1:
image = cv2.imread(path, 0)
# OpenCV represents images in BGR order; however PIL represents
# images in RGB order, so we need to swap the channels
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# convert the images to PIL format...
image = Image.fromarray(image)
edited = Image.fromarray(edited)
# ...and then to ImageTk format
image = ImageTk.PhotoImage(image)
edited = ImageTk.PhotoImage(edited)
# if the panels are None, initialize them
if panelSRC is None or panelDST is None:
# the first panel will store our original image
panelSRC = tk.Label(image=image)
panelSRC.image = image
panelSRC.pack(side="left", padx=10, pady=10)
# while the second panel will store the edge map
panelDST = tk.Label(image=edited)
panelDST.image = edited
panelDST.pack(side="right", padx=10, pady=10)
# otherwise, update the image panels
else:
# update the pannels
panelSRC.configure(image=image)
panelDST.configure(image=edited)
panelSRC.image = image
panelDST.image = edited
def rotate_left(image):
panelDST = None
edited=cv2.rotate(image,90)
panelDST = tk.Label(image=edited)
# initialize the window toolkit along with the two image panels
root = tk.Tk()
panelSRC = None
panelDST = None
# create a button, then when pressed, will trigger a file chooser
# dialog and allow the user to select an input image; then add the
# button the GUI
btn = tk.Button(root, text="Select an image", command=select_image)
vargray = tk.IntVar()
chkbtn = tk.Checkbutton(root, text="gray?", variable=vargray)
btn.pack(side="bottom", fill="y", expand="yes", padx="10", pady="10")
chkbtn.pack()
root.title('toolbox') # window title is toolbox
w = tk.Label(root, text="Hi, Welcome to Zeiad's toolbox !")
rotclk = tk.Button(root, text="RotRight", command="rotate_right")
brightup = tk.Button(root, text="RotLeft", command="buttonpressed")
brightdown = tk.Button(root, text="RotLeft", command="buttonpressed")
Exit1 = tk.Button(root, text="Exit", command="exitbutton")
w.pack() # Packs the elements (widgets) so that the window takes thesize of them only, so it ensures that the widget stays exactly where it issupposed to be
btn.pack(side="bottom", fill="both", expand="yes", padx="10", pady="10")
rotclk.pack(side='right')
rokanticlk.pack(side='left')
Exit1.pack(side='bottom')
root.mainloop() # similar to cv2.waitKey(0)
##FLIP##
'''def flip():
cv2.imshow("original",image)
fl=cv2.flip(image,-1)
cv2.imshow("flip",fl)
cv2.waitKey(0)'''
I was told to change:
rokanticlk = tk.Button(root, text="RotLeft", command="rotate_left")
into
rokanticlk = tk.Button(root, text="RotLeft", command=rotate_left)
but still didn't work (and I don't quite understand why he said that, something about nested functions but I don't know
`
Note that out of despair, I stripped down the roate_left function to a minimal form for the convenience of reading and helping, before that, I really filled it with all types of stuff
I tried to make the GUI part as an object (class) and without too, nothing
I've been through a loop of trial and error for days and still not work, I've tried everything, putting panelSRC and panelDST as parameters in the rotate_left function, copy-pasting the entire select_image function into the rotate_left function, and so on
And as an extra try to be ensured, how do I make the flip work upon button press?
TL;DR: How do I make the button in Tkinter reach a function that would be put (where do I use it?) and after that the function displays the edited value in panelDST