Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overlaying a box on label image using Tkinter

I am using Tkinter and the grid() layout manager to create a GUI. I am showing the image in my GUI using a label, on a tabbed window:

label2 = ttk.Label(tab2)
image2 = PhotoImage(file="lizard.gif")
label2['image'] = image2
label2.grid(column=0, row=0, columnspan=3)

For illustration, let's say the image is 300 x 900. If I know a set of coordinates within the image, how can I overlay a shaded box on the image, defined by the known (A,B,C,D which are shown just for the illustration purpose) coordinates?

Illustration of concept

like image 379
AaronJPung Avatar asked Nov 17 '25 11:11

AaronJPung


1 Answers

Let me give you a step by step solution.

You can use a tkinter.Label() to display your image as you did, you can also choose other widgets. But for situation, let's choose tkinter.Canvas() widget instead (but same reasoning is valid if you choose to use tkinter.Label())

Technical issues:

Your problem contains 2 main sub-problems to resolve:

  • How to overlay 2 images the way you want.
  • How to display an image using tkinter.Canvas()

To be able to read an image of jpg format , you need to use a specific PIL (or its Pillow fork) method and a class:

  • PIL.Image.open()
  • PIL.ImageTk.PhotoImage()

This is done by 3 lines in the below program:

self.im = Image.open(self.saved_image)
self.photo = ImageTk.PhotoImage(self.im)

And then display self.photo in the self.canvas widget we opted for:

self.canvas.create_image(0,0, anchor=tk.N+tk.W, image = self.photo)

Second, to reproduce the effect you desire, use cv2.addWeighted() OpenCV method. But I feel you have already done that. So I just show you the portion of code of the program that does it:

self.img = cv2.imread(self.image_to_read)
self.overlay = self.img.copy()
cv2.rectangle(self.overlay, (500,50), (400,100), (0, 255, 0), -1)
self.opacity = 0.4
cv2.addWeighted(self.overlay, self.opacity, self.img, 1 - self.opacity, 0, self.img)
cv2.imwrite( self.saved_image, self.img)

Program design:

I use 2 methods: - __init__(): Prepare the frame and call the GUI initialization method. - initialize_user_interface(): Draw the GUI and perform the previous operations.

But for scalability reasons, it is better to create a separate method to handle the different operations of the image.

Full program (OpenCV + tkinter)

Here is the source code (I used Python 3.4):

'''
Created on Apr 05, 2016

@author: Bill Begueradj
'''
import tkinter as tk
from PIL import Image, ImageTk
import cv2
import numpy as np
import PIL



class Begueradj(tk.Frame):
    '''
    classdocs
    '''


    def __init__(self, parent):
        '''
        Prepare the frame and call the GUI initialization method.
        '''
        tk.Frame.__init__(self, parent)
        self.parent=parent
        self.initialize_user_interface()

    def initialize_user_interface(self):
        """Draw a user interface allowing the user to type        
        """
        self.parent.title("Bill BEGUERADJ: Image overlay with OpenCV + Tkinter")       
        self.parent.grid_rowconfigure(0,weight=1)
        self.parent.grid_columnconfigure(0,weight=1)

        self.image_to_read = 'begueradj.jpg'      
        self.saved_image = 'bill_begueradj.jpg'

        self.img = cv2.imread(self.image_to_read)
        self.overlay = self.img.copy()
        cv2.rectangle(self.overlay, (500,50), (400,100), (0, 255, 0), -1)
        self.opacity = 0.4
        cv2.addWeighted(self.overlay, self.opacity, self.img, 1 - self.opacity, 0, self.img)
        cv2.imwrite( self.saved_image, self.img)

        self.im = Image.open(self.saved_image)
        self.photo = ImageTk.PhotoImage(self.im)     

        self.canvas = tk.Canvas(self.parent, width = 580, height = 360)         

        self.canvas.grid(row = 0, column = 0)
        self.canvas.create_image(0,0, anchor=tk.N+tk.W, image = self.photo)


def main():
    root=tk.Tk()
    d=Begueradj(root)
    root.mainloop()

if __name__=="__main__":
    main()

Demo:

This is a screenshot of the running program:

enter image description here

like image 65
Billal Begueradj Avatar answered Nov 20 '25 03:11

Billal Begueradj



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!