2

I am using python 3, opencv, and tkinter to create a GUI where I can upload an image and then display the image in a panel next to the final image which is the stacked version of all images in the same folder as the inputted image. The stacker() function simply stacks the images in the folder.

For some reason, when running this program, the image that is supposed to be in the panelA is displaying, while the image from panelB is not.

How can I display both images- the input and the output? Also is there any way to speed up this code?

def select_image():
 # grab a reference to the image panels
 global panelA, panelB

 # open a file chooser dialog and allow the user to select an input
 # image
 path = tkinter.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)
    edged = stacker(os.path.dirname(os.path.dirname(path)))


    # 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)
    edged = Image.fromarray(edged)

    # ...and then to ImageTk format
    image = ImageTk.PhotoImage(image)
    edged = ImageTk.PhotoImage(edged)

    # if the panels are None, initialize them
    if panelA is None or panelB is None:
        # the first panel will store our original image
        panelA = tk.Label(image=image)
        panelA.image = image
        panelA.pack(side="left", padx=10, pady=10)

        # while the second panel will store the edge map
        panelB = tk.Label(image=edged)
        panelB.image = edged
        panelB.pack(side="right", padx=10, pady=10)

    # otherwise, update the image panels
    else:
        # update the pannels
        panelA.configure(image=image)
        panelB.configure(image=edged)
        panelA.image = image
        panelB.image = edged

# initialize the window toolkit along with the two image panels
root = tk.Tk()
panelA = None
panelB = None
print("done")

# 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)
print("done1")
btn.pack(side="bottom", fill="both", expand="yes", padx="10", pady="10")
print("done2")

# kick off the GUI
root.mainloop()
print("done3")
6
  • 3
    Your code looks ok to me. Obviously I can't test it since you didn't provide a minimal reproducible example and some test images. Therefore I'd guess the problem is in your stacker() function; perhaps it's returning an empty array? Commented Jul 9, 2018 at 21:18
  • 1
    Did you mean to use os.path.dirname twice? That would put you in the parent folder, not "the same folder as the inputted image". Commented Jul 9, 2018 at 21:21
  • @Novel Thanks for catching that mistake, I fixed it. I am not allowed to provide the stacker() function at this time, but the program does not even work if I try to display the input image twice in the different panels. Commented Jul 9, 2018 at 21:40
  • 3
    Your code works for me if both Labels use "image". Show us a minimal reproducible example that demonstrates your problem. Commented Jul 9, 2018 at 21:49
  • Does it display the image twice? In the left panel and the right panel? @Novel Commented Jul 9, 2018 at 21:54

2 Answers 2

2

Your code works as intended, but both the images are probably not displaying due to the size of image. I would suggest a resize on the image.

edged = cv2.resize(edged, dsize=(500, 600), interpolation=cv2.INTER_CUBIC)
Sign up to request clarification or add additional context in comments.

1 Comment

In addition, you might want to check for compatibility of image types or numpy vs python array.
1

The reason both images may not be displayed is due to the size of the images. I would recommend using the resize function to ensure the images display regardless of the input image size.

I have provided a code snippet of how it should look below.

        edged = cv2.resize(edged, dsize=(500, 600), interpolation=cv2.INTER_CUBIC)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.