Introducing "Posterization", the basic technology of image processing. Posterization is a conversion using a tone curve on the stairs, which limits the output pixel value to several levels.
As shown in the figure below, the pixel value of the input image is set to n levels (4 levels in the figure below) to limit the pixel value of the output image. By doing so, the borders become clearer and you can express colors like art.
Posterization is a book ["Digital Image Processing"](https://www.amazon.co.jp/%E3%83%87%E3%82%A3%E3%82%B8%E3%82%BF%E3% 83% AB% E7% 94% BB% E5% 83% 8F% E5% 87% A6% E7% 90% 86-% E6% 94% B9% E8% A8% 82% E7% AC% AC% E4% BA % 8C% E7% 89% 88-% E3% 83% 87% E3% 82% A3% E3% 82% B8% E3% 82% BF% E3% 83% AB% E7% 94% BB% E5% 83% 8F% E5% 87% A6% E7% 90% 86% E7% B7% A8% E9% 9B% 86% E5% A7% 94% E5% 93% A1% E4% BC% 9A / dp / 490347464X / ref = asc_df_490347464X /? tag = jpgo-22 & linkCode = df0 & hvadid = 342595526565 & hvpos = & hvnetw = g & hvrand = 5492134153117811443 & hvpone = & hvptwo = & hvqmt = & hvdev = c & hvdvcmdl = & hvlocint = & hvlocphy = 1937 It follows the processing method that is used. Since the tone curve that leaves pixel values 0 and 255 in the processed image is used, the image has a clear contrast.
The environment in which the posterization process was tried is as follows.
Python 3.6.8 numpy 1.18.1 matplotlib 3.1.2 opencv-python 18.104.22.168
Since OpenCV is used in the library, please install it in advance.
pip install opencv-python
When I looked at various sites about posterization, many sites used LUTs that did not reflect white with a pixel value of 255 in the output image.
This process also reflects the pixel value of 255 "white" in the output image, so I devised a LUT creation. The input and output of bins are separated, but please refer to the comment section of the code for details.
#coding: utf-8 import cv2 import numpy as np import matplotlib.pyplot as plt def main(): img = cv2.imread('image.jpg') #Loading images gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) #Grayscale n = 4 #Number of pixel value divisions pos = posterization(gray, n) cv2.imwrite('pos.jpg', pos) #Output of posterized image def posterization(img, n): x = np.arange(256) #0,1,2...An array of integers up to 255 ibins = np.linspace(0, 255, n+1) #Input from LUT is 255/(n+1)Split with obins = np.linspace(0,255, n) #Output from LUT is 255/Split by n num=np.digitize(x, ibins)-1 #Number the input pixel values to posterize num = n-1 #Correct the number of pixel value 255 that is off by digitize processing y = np.array(obins[num], dtype=int) #Create a posterizing LUT pos_LUT(n, y) #Create LUT diagram pos = cv2.LUT(img, y) #Perform posterization return pos #Posterization LUT diagram creation def pos_LUT(n, y): x = np.arange(0,256,1) plt.plot(x,y) plt.savefig("pos_LUT.png ") if __name__=='__main__': main()
★ Books ・ [Digital Image Processing [Revised Second Edition](Public Interest Incorporated Foundation Image Information Education Promotion Association (CG-ARTS))]  :https://www.amazon.co.jp/%E3%83%87%E3%82%A3%E3%82%B8%E3%82%BF%E3%83%AB%E7%94%BB%E5%83%8F%E5%87%A6%E7%90%86-%E6%94%B9%E8%A8%82%E7%AC%AC%E4%BA%8C%E7%89%88-%E3%83%87%E3%82%A3%E3%82%B8%E3%82%BF%E3%83%AB%E7%94%BB%E5%83%8F%E5%87%A6%E7%90%86%E7%B7%A8%E9%9B%86%E5%A7%94%E5%93%A1%E4%BC%9A/dp/490347464X/ref=asc_df_490347464X/?tag=jpgo-22&linkCode=df0&hvadid=342595526565&hvpos=&hvnetw=g&hvrand=5492134153117811443&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1009247&hvtargid=pla-889374643658&psc=1&th=1&psc=1
★ Site -[OpenCV-How to use cv2.LUT, gamma correction, negative / positive inversion, posterization]  :https://pystyle.info/opencv-tone-transform/#outline__6 ・ [How to use digitize (numpy)]  :http://arduinopid.web.fc2.com/Q3-36.html