27

Is there a way to use and plot with opencv2 with ipython notebook?

I am fairly new to python image analysis. I decided to go with the notebook work flow to make nice record as I process and it has been working out quite well using matplotlib/pylab to plot things.

An initial hurdle I had was how to plot things within the notebook. Easy, just use magic:

%matplotlib inline

Later, I wanted to perform manipulations with interactive plots but plotting in a dedicated window would always freeze. Fine, I learnt again that you need to use magic. Instead of just importing the modules:

%pylab

Now I have moved onto working with opencv. I am now back to the same problem, where I either want to plot inline or use dedicated, interactive windows depending on the task at hand. Is there similar magic to use? Is there another way to get things working? Or am I stuck and need to just go back to running a program from IDLE?

As a side note: I know that opencv has installed correctly. Firstly, because I got no errors either installing or importing the cv2 module. Secondly, because I can read in images with cv2 and then plot them with something else.

snoob dogg
  • 2,491
  • 3
  • 31
  • 54
Fire
  • 323
  • 1
  • 3
  • 5
  • I have found that the command "cv2.waitKey()" after the "cv2.imshow()" command gets around the freezing issue for external windows - but do not know why. I have also seen a few other commands mentioned here: http://txt.arboreus.com/2012/07/11/highgui-opencv-window-from-ipython.html – Fire Jan 07 '16 at 14:33
  • I am not sure if you can embed cv2 namedWindow in IPython notebook as it is a C++ frame. Probably there is no backend written for cv2.imshow. I would use imshow from pylab for embedding. Did this cv2.startWindowThread() work for notebook? I am curious. – otterb Jan 14 '16 at 23:41
  • It didn't work for me. A blank external window pops up and freezes. – Fire Jan 18 '16 at 14:52

3 Answers3

40

This is my empty template:

import cv2
import matplotlib.pyplot as plt
import numpy as np
import sys
%matplotlib inline

im = cv2.imread('IMG_FILENAME',0)
h,w = im.shape[:2]
print(im.shape)
plt.imshow(im,cmap='gray')
plt.show()

See online sample

themadmax
  • 2,344
  • 1
  • 31
  • 36
  • What can h,w be used for? – Moondra May 06 '17 at 20:57
  • h and w corresponding to Height and Width image size – themadmax May 15 '17 at 16:02
  • 2
    Be careful if you are reading images using *`cv2`* and displaying the image using *`plt`*. *`cv2`* reads images as BGR by default, where as *`plt`* uses RGB format. So your Blue and Red color will get flipped. Here, you're reading the image in grayscale with `0` parameter in `cv2.imread`, so you won't see this issue. – Maunesh Ahir Jan 07 '19 at 05:56
  • 2
    You're right, we must use `cv2.cvtColor(image, cv2.COLOR_BGR2RGB)` to display color image – themadmax Jan 07 '19 at 16:51
6

For a Jupyter notebook running on Python 3.5 I had to modify this to:

import io
import cv2
import numpy as np
from IPython.display import clear_output, Image, display
import PIL.Image

def showarray(a, fmt='jpeg'):
    a = np.uint8(np.clip(a, 0, 255))
    f = io.BytesIO()
    PIL.Image.fromarray(a).save(f, fmt)
    display(Image(data=f.getvalue()))
2

There is also that little function that was used into the Google Deepdream Notebook:

import cv2
import numpy as np
from IPython.display import clear_output, Image, display
from cStringIO import StringIO
import PIL.Image

def showarray(a, fmt='jpeg'):
    a = np.uint8(np.clip(a, 0, 255))
    f = StringIO()
    PIL.Image.fromarray(a).save(f, fmt)
    display(Image(data=f.getvalue()))

Then you can do :

img = cv2.imread("an_image.jpg") 

And simply :

showarray(img)

Each time you need to render the image in a cell

snoob dogg
  • 2,491
  • 3
  • 31
  • 54
  • 2
    this is a great way to avoid [problems in `pyplot`s rendering](https://stackoverflow.com/q/33174359/786559). Just [be mindful](https://stackoverflow.com/a/18284900/786559) of Python 3 compatibility – Ciprian Tomoiagă Jul 10 '18 at 15:00