11

I have a very simple program on Ubuntu 14.04 LTS to read and display an image using OpenCV:

import cv2 #import OpenCV

img = cv2.imread('picture.jpg') #read a picture using OpenCV
cv2.imshow('image',img) # Display the picture
cv2.waitKey(0) # wait for closing
cv2.destroyAllWindows() # Ok, destroy the window

My problem:

How can I keep reading the picture in OpenCV but display it using Tkinter ?

I ask this because I want to make an interface for my program but OpenCV is not able to do it so I need Tkinter for this. However, all the image processing I must do it on the background using OpenCV. Only displaying the results must be done using Tkinter.

EDIT:

From the answer above, I change the line:

im = Image.open('slice001.hrs').convert2byte()

To:

im=cv2.imread() # (I imported cv2) 

But I got an error.

I would appreciate any hints.

Christoph Rackwitz
  • 11,317
  • 4
  • 27
  • 36

3 Answers3

21

You might want to take a look at this one. Here is something works for me:

import numpy as np
import cv2
import Tkinter 
from PIL import Image, ImageTk

# Load an color image
img = cv2.imread('img.png')

#Rearrang the color channel
b,g,r = cv2.split(img)
img = cv2.merge((r,g,b))

# A root window for displaying objects
root = Tkinter.Tk()  

# Convert the Image object into a TkPhoto object
im = Image.fromarray(img)
imgtk = ImageTk.PhotoImage(image=im) 

# Put it in the display window
Tkinter.Label(root, image=imgtk).pack() 

root.mainloop() # Start the GUI
Andreas Haferburg
  • 5,189
  • 3
  • 37
  • 63
Ha Dang
  • 1,218
  • 1
  • 10
  • 12
  • Thank you. But I do not see where did you read the image using OpenCV ? –  Feb 23 '15 at 10:39
  • 1
    Just edit the answer. But guys, why don't you give it a try yourself? DIY - that's the best way of learning. – Ha Dang Feb 23 '15 at 11:27
  • I tried (see my edit). Your second solution works almost perfectly. Only one drawback, however: my image is almost orange, but now it is displayed almost in blue :( –  Feb 23 '15 at 11:33
  • I added the RGB mode for reading it like this `im = Image.fromarray(img,'RGB')`, but same result :( –  Feb 23 '15 at 11:37
  • it's because color channel order is BBGR, not RGB. You can add the two following lines into the code: b,g,r = cv2.split(img) img = cv2.merge((b,g,r)) – Ha Dang Feb 23 '15 at 11:40
  • Still same result even if your intention, I think, is right (to split and merge the colors). You made so much efforts for me. –  Feb 23 '15 at 11:47
  • Hey, pay attention to the order of the cv2.merge parameters. In my comment, it's not in good order. Try with the code in my answer. – Ha Dang Feb 23 '15 at 11:48
  • Yes, I did an error in ordering the colors. I do not not know how to thank you man. –  Feb 23 '15 at 11:51
  • Instead of using `cv2.merge`, you can simply use `numpy` indexing to rearrange the third dimension of the image: `out = img[:,:,::-1]`. Just a suggestion, but merge is the accepted way when referring to the OpenCV docs. – rayryeng Feb 23 '15 at 17:30
  • 1
    It's `from PIL import Image, ImageTk`, not `import Image, ImageTk`. – makeworld Jul 14 '21 at 13:22
2

For me both answers above did not work but were close. The following code did the trick for me (I also want to use place instead of pack):

from PIL import ImageTk, Image

image = cv2.cvtColor(self.image, cv2.COLOR_BGR2RGB)
image = ImageTk.PhotoImage(image=Image.fromarray(image))
label_image = Label(self.detection, image=image)
label_image.image = image
label_image.place(x=0, y=0, anchor="w")
Christoph Rackwitz
  • 11,317
  • 4
  • 27
  • 36
Jop Knoppers
  • 676
  • 1
  • 10
  • 22
  • 2
    this is obviously the most up to date and working answer :) and please remember to add the library imports too: from PIL import ImageTk,Image – SoajanII Jul 24 '22 at 17:00
1

For Python3 I had to modify @Ha Dang answer:

from tkinter import *
from PIL import Image, ImageTk
import cv2
import numpy as np

image_name = 'bla.jpg'

image = cv2.imread(image_name)

#Rearrang the color channel
b,g,r = cv2.split(image)
img = cv2.merge((r,g,b))

# A root window for displaying objects
root = Tk()  

# Convert the Image object into a TkPhoto object
im = Image.fromarray(img)
imgtk = ImageTk.PhotoImage(image=im) 

# Put it in the display window
Label(root, image=imgtk).pack() 

root.mainloop() # Start the GUI

Requirements were:

pip3

numpy==1.13.1
opencv-python==3.3.0.9
Pillow==4.2.1

brew

python3
tcl-tk
lony
  • 6,733
  • 11
  • 60
  • 92