[PYTHON] Use ipywidgets in jupyter notebook to interactively manipulate parameters and also try image processing

It's nice to plot the graph of the function in jupyter notebook with matplotlib, but it's annoying to change the value and press Ctrl + Enter every time you try and error. It's commonplace to want to dynamically reflect value changes in results with the reactive (old?)-Like trend that is popular these days. When I searched for it, it seems that a library called ipywidgets was developed for jupyter notebook, so I decided to use it.

https://github.com/ipython/ipywidgets

It also seems to allow interactive behavior through UI components such as so-called sliders and text boxes.

environment

I tried it in the following environment.

Preparation

First, build a virtual environment with venv. If you are a virtualenv person or a bash person, please read as appropriate.

$ python3 -m venv ipywidgets_env
$ source ipywidgets_env/bin/activate.fish #For fish

Installation

Install jupyter normally.

(ipywidgets_env) $ pip install jupyter

Lightly confirm that ipywidgets came in together as a dependency. If you don't have it, you can just put it in with pip install.

(ipywidgets_env) $ pip list | grep ipywidgets
ipywidgets (5.2.2)

In addition, execute the following command for jupyter to enable the drawing extension function.

(ipywidgets_env) $ jupyter nbextension enable --py widgetsnbextension --sys-prefix

Behavior check

Now that the environment is ready to try ipywidgets, I will try it on jupyter notebook immediately.

(ipywidgets_env) $ jupyter notebook

After starting, create a new notebook in the opened browser and write a function that returns the calculation result ʻa * x + b` in a new cell.

def f(x, a, b):
    return a * x + b

To operate the parameters in this function with the UI component of the slider, change the range of the above function f and the parameters x, ʻa, b to the ʻinteract function as shown below. I'll give it to you.

from ipywidgets import interact
interact(f, x=(-10,10, 1), a=(-10,10, 1), b=(-10,10, 1))

The execution result on the browser is as follows.

スクリーンショット 2017-01-04 0.52.27.png

A slider appeared on the screen. Play around with the knobs.

スクリーンショット 2017-01-04 0.54.12.png

Initially x = 0, a = 0, b = 0 and the result was 0, but if you set x = 10, a = 4, b = -10, it will be immediately reflected in the result as 30. Is displayed. In this way, we were able to confirm the dynamic reflection of the value by ipywigdets.

Reflect in the result while adjusting the binarization threshold of the image with the slider

As a small application, I would like to try to reflect the threshold value of binarization, which is a standard image processing, in the result while operating it by myself. I use my own icon image.

my_github.jpeg

For the time being, I will use Pillow, an image processing tool in Python. If you have already installed it, you do not need to execute the following command.

(ipywidgets_env) $ pip install Pillow

First, import Pillow and load the grayscale 255 gradation image into the global variable ʻimg`.

from PIL import Image
img = Image.open('picture.jpeg').convert('L')

my_github_gray.png

@interact
def binarize(th: (0, 255, 1)):
    return img.point(lambda p: 255 if p > th else 0)

You can also use ipywidgets by defining a function binarize that is dynamically operated by ipywidgets, creating a function that returns the binarized image by the threshold variable th, and adding a ʻinteract` decorator. can. When you execute the above cell,

スクリーンショット 2017-01-08 22.23.49.png スクリーンショット 2017-01-08 22.24.08.png

In this way, you can dynamically binarize while moving the threshold slider on the jupyter notebook.

By the way, I will try the image diff of GitHub

Now that I know how to use the slider, I'll try to imitate the famous GitHub image difference confirmation method. I wasn't very familiar with Pillow yet and didn't know how to adjust the saturation of a partial image, so I ended up doing it in vain way of overlaying the image on top of it.

orig = Image.open('picture.jpeg')

@interact
def github_diff(percentage: (0, 100, 1)):
    orig_copied = orig.copy()
    box = (int(img.width / 100 * percentage), 0, img.width, img.height)
    img_cropped = img.crop(box)
    orig_copied.paste(img_cropped, box)
    return orig_copied

After loading the original image into ʻorig, the original image is dynamically displayed on the left side and the grayscale image is drawn on the right side based on the ratio specified by the slider. paste` seems to be a destructive method, taking a copy of the original image for each value change. I would like to know if there is a better way.

スクリーンショット 2017-01-09 14.14.56.png スクリーンショット 2017-01-09 14.15.11.png

Summary

The jupyter notebook, which is already suitable for experiments and verifications, will be even easier to use!

Recommended Posts

Use ipywidgets in jupyter notebook to interactively manipulate parameters and also try image processing
How to use Jupyter Notebook
processing to use notMNIST data in Python (and tried to classify it)
Easy to use Jupyter notebook (Python3.5)
Easy way to enter and execute AtCoder test cases in Jupyter Notebook
I wanted to use jupyter notebook with docker in pip environment (opticspy)
Specify the browser to use with Jupyter Notebook. Especially Mac. (And Vivaldi)
Use Jupyter Lab and Jupyter Notebook with EC2
How to execute commands in jupyter notebook
How to use jupyter notebook with ABCI
Jupyter Notebook Basics of how to use
How to use Jupyter notebook [Super Basic]
How to use is and == in Python
Build a PYNQ environment on Ultra96 V2 and log in to Jupyter Notebook
How to use Python Image Library in python3 series
How to use PyTorch-based image processing library "Kornia"
Jupyter Notebook Settings-How to use (EC2 Amazon Linux 2)
Automatically save .py and .html files in Jupyter notebook.
How to use jupyter lab in Windows 10 local environment
How to use Decorator in Django and how to make it
It may be a problem to use Japanese for folder names and notebook names in Databricks