Image processing with Python & OpenCV [Tone Curve]

Introduction

This article mainly introduces image processing by ** Tone Curve **. The textbook has a Tone Curve, but no code ... It may be for those who are wondering what kind of code can be achieved.

If you don't know Tone Curve and read this article It would be nice if you could easily find out by "Introduction" in [] tc.

Tone curve, output image (color, grayscale), conversion function I will introduce them in the order of.

Operating environment

Terminal: Windows 10
Console: cmd(command prompt)
python:3.6.8
Virtual environment: venv

table of contents

-[** Negative / Positive Inversion ](#Negative / Positive Inversion) -[ Line-shaped tone curve ](# Line-shaped tone curve) -[Line-shaped tone curve 1](# Line-shaped tone curve 1) -[Line-shaped tone curve 2](# Line-shaped tone curve 2) -[ S-shaped tone curve ](#s-shaped tone curve) -[ Gamma conversion tone curve ](# Gamma conversion tone curve) -[ Solarization ](# Solarization) -** Posterization ** -[ 2 Threshold **](# 2 Threshold)

Introduction

There are two input images as follows.

Color Grayscale
original.jpg grayScale.jpg

For grayscale, I used OpenCV's cv2.cvtColor ().

How color and grayscale images change I will introduce it.

Also, if the return value from the function is read by the cv2.imwrite () function etc. You can save it.

▷ Negative / positive reversal

Invert the pixel value as its name suggests. (* From this, * x * in the formula is the pixel value.)

f(x) = 255 - x

Tone curve

nega_posi.png

Output image

input output
input output

--Grayscale

input output
input output

function

Conversion function


def negaPosi(frame):
    return 255 - frame

▷ Line-shaped tone curve

I'm suffering from the previously introduced article ... If you want to see more details, I would appreciate it if you read the article.

Here, the tone curve for n = 2 is output. (* N is the value of how many times the pixel value is multiplied.)

◆ Line-shaped tone curve 1

A conversion that increases the contrast of the image.

f(x) = \begin{cases} 2 \cdot x & (x < 128) \\ 255 & (otherwise)
  \end{cases}

Tone curve

tone_curve1.png

Output image

input output
input output

--Grayscale

input output
input output

function

Conversion function


def toneCurve1(frame, n = 1):
    look_up_table = np.zeros((256,1), dtype = 'uint8')
    for i in range(256):
        if i < 256 / n:
            look_up_table[i][0] = i * n
        else:
            look_up_table[i][0] = 255
    return cv2.LUT(frame, look_up_table)

◆ Line-shaped tone curve 2

This is a conversion that lowers the contrast with respect to the top.

f(x) = \begin{cases} 0 & (x < 128) \\ 2 \cdot x - 255 & (otherwise)
  \end{cases}

Tone curve

tone_curve2.png

Output image

input output
input output

--Grayscale

input output
input output

function

Conversion function


def toneCurve2(frame, n = 1):
    look_up_table = np.zeros((256,1), dtype = 'uint8')
    for i in range(256):
        if i < 256 - 256 / n :
            look_up_table[i][0] = 0
        else:
            look_up_table[i][0] = i * n - 255 * (n - 1)
    return cv2.LUT(frame, look_up_table)

▷ S-shaped tone curve

This S Tone Curve is brighter in bright areas Dark areas are transformations that emphasize darker.

f(x) = \frac {255}{2} \cdot \left\{\sin\left(\frac {x}{255} - \frac {1}{2}\right)\pi + 1\right\}

Tone curve

s_tone_curve.png

Output image

input output
input output

--Grayscale

input output
input output

The image is clear somewhere.

function

Conversion function


def sToneCurve(frame):
    look_up_table = np.zeros((256,1), dtype = 'uint8')
    for i in range(256):
        look_up_table[i][0] = 255 * (np.sin(np.pi * (i/255 - 1/2)) + 1) / 2
    return cv2.LUT(frame, look_up_table)

▷ Gamma conversion tone curve

In the line-shaped tone curve I mentioned earlier There is a part where the shading information is lost after being converted to a constant value (0, 255). In gamma conversion, conversion can be performed while leaving the shading information of that part.

f(x) = 255 \cdot \left(\frac {x}{255}\right)^\frac{1}{\gamma}

Tone curve

Here are some gamma value patterns.

gamma_curve.png

Output image

input γ = 3 γ = 2
input output output
γ = 1 γ = 0.5 γ = 1 / 3
output output output

--Grayscale

input γ = 3 γ = 2
input output output
γ = 1 γ = 0.5 γ = 1 / 3
output output output

Obviously, the image of γ = 1 and input will be the same.

function

Conversion function


def gammaCurve(frame, gamma = 1):
    look_up_table = np.zeros((256,1), dtype = 'uint8')
    for i in range(256):
        look_up_table[i][0] = pow(i / 255, 1 / gamma) * 255
    return cv2.LUT(frame, look_up_table)

▷ Solarization

The image looks like a mixture of negative and positive images.

The conversion formula used in my solarization is as follows.

f(x) = \frac {255}{2} \cdot \sin\left\{3\pi\left(\frac {x}{255} - \frac {1}{2}\right)\right\}

Tone curve

soralization.png

Output image

input output
input output

--Grayscale

input output
input output

function

Conversion function


def soralization(frame):
    look_up_table = np.zeros((256,1), dtype = 'uint8')
    for i in range(256):
        look_up_table[i][0] = (np.sin(3 * np.pi * (i / 255 + 1 / 2 )) + 1) * 255 / 2
    return cv2.LUT(frame, look_up_table)

▷ Posterization

Pixel values are gradually made constant. The image will look like a painting.

As an output, a pattern in which the pixel value is divided into 2, 3 and 4 stages is output.

Tone curve

posterization2.png posterization3.png
posterization.png posterization5.png

Output image

input step = 2
input output
step = 3 step = 4
output output

--Grayscale

input step = 2
input output
step = 3 step = 4
output output

It looks like a postcard.

function

Conversion function


def posterization(frame, step = 4):
    if 1 < step and step <= 256:
        look_up_table = np.zeros((256, 1), dtype = 'uint8')
        split = int(256 / (step - 1))
        up = int(256 / step)
        for i in range(256):
            if np.trunc(i / up) * split >= 255:
                look_up_table[i][0] = 255
            else:
                look_up_table[i][0] = np.trunc(i / up) * split
        return cv2.LUT(frame, look_up_table)
    else:
        return frame

Probably the hardest part of coming up with this code ... If you have a better way, please teach me.

▷ Binarization

From the threshold n ** Value when small is 0 (minimum value) ** ** A conversion that changes the value when it is large to 255 (maximum value) **.

I haven't used it this time, but in the cv2 library, [Binarization Function](http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_imgproc /py_thresholding/py_thresholding.html). There are cv2.adaptiveThreshold () and cv2.threshold ().

f(x) = \begin{cases}
       0 & (x < n) \\ 255 &(otherwise)
\end{cases}

Tone curve

This time, the output is for the threshold n = {50, 128, 200}.

thre_50.png thre_128.png thre_200.png

Output image

input n = 50
input output
n = 128 n = 200
output output

--Grayscale

input n = 50
input output
n = 128 n = 200
output output

function

Conversion function


def threshold(frame, threshold_v = 50):
    frame[frame < threshold_v] = 0
    frame[frame >= threshold_v] = 255
    return frame

Main function

ex.py


import cv2
import numpy as np

#Functions(abridgement)

def main():
    img_path = '.\\image\\castle.jpg' #Specify the image arbitrarily
    img = cv2.imread(img_path)
    frame = grayScale(img)
    #Call a function,Please practice.
    #Example:
    # cv2.imwrite('tone_changed.jpg', negaPosi(img))

if __name__ == '__main__':
    main()

in conclusion

This time, I introduced the gradation conversion by some tone curves. Next, I'm thinking of doing image processing with filters.

You can add a UI to make it more practical.

Then: wave:

reference

-[Computer Graphics] cv -[Image source](https://pixabay.com/en/photos/%E5%9F%8E-%E3%82%B9%E3%82%B3%E3%83%83%E3%83%88 % E3% 83% A9% E3% 83% B3% E3% 83% 89-3619698 /) (Pixabay)

Related article

-[Let's talk about the tone curve of image processing ~ LUT is amazing ~] tc

Recommended Posts

Image processing with Python & OpenCV [Tone Curve]
Image processing with Python
Light image processing with Python x OpenCV
"Apple processing" with OpenCV3 + Python3
Image editing with python OpenCV
Image processing with Python (Part 1)
Image processing with Python (Part 3)
[Python] Image processing with scikit-image
Real-time image processing basics with opencv
[Python] Using OpenCV with Python (Image Filtering)
[Python] Using OpenCV with Python (Image transformation)
Image processing with Python 100 knocks # 3 Binarization
Find image similarity with Python + OpenCV
Image processing with Python 100 knocks # 2 Grayscale
python image processing
Basics of binarized image processing with Python
Image processing with Python 100 knock # 10 median filter
Image processing with Python 100 knocks # 8 Max pooling
Image processing with Python 100 knock # 12 motion filter
Image acquisition from camera with Python + OpenCV
Drawing with Matrix-Reinventor of Python Image Processing-
Easy image processing in Python with Pillow
Image processing with Python 100 knocks # 7 Average pooling
Image processing with Lambda + OpenCV (gray image creation)
Image processing with Python 100 knocks # 9 Gaussian filter
Image processing with MyHDL
Binarization with OpenCV / Python
First Python image processing
Image Processing with PIL
I tried "smoothing" the image with Python + OpenCV
I tried "differentiating" the image with Python + OpenCV
Image processing from scratch with python (5) Fourier transform
Image processing from scratch with python (4) Contour extraction
Image Processing with Python Environment Setup for Windows
I tried "binarizing" the image with Python + OpenCV
[Small story] Test image generation with Python / OpenCV
100 Language Processing with Python Knock 2015
Image processing with PIL (Pillow)
Notes on HDR and RAW image processing with Python
Camera capture with Python + OpenCV
Acoustic signal processing with Python (2)
[Python] Using OpenCV with Python (Basic)
[OpenCV / Python] I tried image analysis of cells with OpenCV
Acoustic signal processing with Python
Sorting image files with Python (3)
Tweet with image in Python
Sorting image files with Python
Face detection with Python + OpenCV
Image processing by python (Pillow)
[Python] Curve fitting with polynomial
Image Processing Collection in Python
JPEG image generation by specifying quality with Python + OpenCV
Create miscellaneous Photoshop videos with Python + OpenCV ② Create still image Photoshop
Get image features with OpenCV
Using OpenCV with Python @Mac
Image recognition with Keras + OpenCV
Paste png with alpha channel as transparent image with Python / OpenCV
[Let's play with Python] Image processing to monochrome and dots
[Python] Easy reading of serial number image files with OpenCV
Shining life with Python and OpenCV
Cut out an image with python