Add Pixelize
parent
616cb6c677
commit
680e7d00d2
|
|
@ -0,0 +1 @@
|
||||||
|
__pycache__/
|
||||||
|
|
@ -0,0 +1,183 @@
|
||||||
|
from typing import Any
|
||||||
|
from numpy.typing import NDArray
|
||||||
|
|
||||||
|
import cv2
|
||||||
|
from PIL import Image
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
INFLATE_FILTER = [
|
||||||
|
None,
|
||||||
|
np.array(
|
||||||
|
[[0, 1, 0],
|
||||||
|
[1, 1, 1],
|
||||||
|
[0, 1, 0]], np.uint8
|
||||||
|
),
|
||||||
|
np.array(
|
||||||
|
[[1, 1, 1],
|
||||||
|
[1, 1, 1],
|
||||||
|
[1, 1, 1]], np.uint8
|
||||||
|
),
|
||||||
|
np.array(
|
||||||
|
[[0, 0, 1, 0, 0],
|
||||||
|
[0, 1, 1, 1, 0],
|
||||||
|
[1, 1, 1, 1, 1],
|
||||||
|
[0, 1, 1, 1, 0],
|
||||||
|
[0, 0, 1, 0, 0]], np.uint8
|
||||||
|
),
|
||||||
|
np.array(
|
||||||
|
[[1, 1, 1, 1, 1],
|
||||||
|
[1, 1, 1, 1, 1],
|
||||||
|
[1, 1, 1, 1, 1],
|
||||||
|
[1, 1, 1, 1, 1],
|
||||||
|
[1, 1, 1, 1, 1]], np.uint8
|
||||||
|
),
|
||||||
|
np.ones((7, 7), np.uint8),
|
||||||
|
np.ones((9, 9), np.uint8),
|
||||||
|
np.ones((11, 11), np.uint8),
|
||||||
|
np.ones((13, 13), np.uint8),
|
||||||
|
np.ones((15, 15), np.uint8),
|
||||||
|
np.ones((17, 17), np.uint8)
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def read_img_as_array(
|
||||||
|
img
|
||||||
|
) -> NDArray[Any]:
|
||||||
|
'''Convert image to RGBA and read to ndarray'''
|
||||||
|
img = Image.fromarray(img)
|
||||||
|
img = img.convert('RGBA')
|
||||||
|
img_arr = np.asarray(img)
|
||||||
|
return img_arr
|
||||||
|
|
||||||
|
|
||||||
|
def preprocess(
|
||||||
|
img: NDArray[Any],
|
||||||
|
blur: int = 0,
|
||||||
|
erode: int = 0,
|
||||||
|
) -> NDArray[Any]:
|
||||||
|
'''
|
||||||
|
Process for
|
||||||
|
* outline inflation (erode)
|
||||||
|
* smoothing (blur)
|
||||||
|
* saturation
|
||||||
|
* contrast
|
||||||
|
'''
|
||||||
|
# outline process
|
||||||
|
if erode:
|
||||||
|
img = cv2.erode(
|
||||||
|
img, INFLATE_FILTER[erode],
|
||||||
|
iterations = 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
# blur process
|
||||||
|
if blur:
|
||||||
|
img = cv2.bilateralFilter(
|
||||||
|
img, 15, blur*20, 20
|
||||||
|
)
|
||||||
|
img = img.astype(np.float32)
|
||||||
|
return img
|
||||||
|
|
||||||
|
|
||||||
|
def pixelize(
|
||||||
|
img: NDArray[Any],
|
||||||
|
k: int, c: int,
|
||||||
|
d_w: int, d_h: int,
|
||||||
|
o_w: int, o_h: int,
|
||||||
|
precise: int,
|
||||||
|
) -> tuple[NDArray[Any], NDArray[Any]]:
|
||||||
|
'''
|
||||||
|
Use down scale and up scale to make pixel image.
|
||||||
|
|
||||||
|
And use k-means to confine the num of colors.
|
||||||
|
'''
|
||||||
|
img = cv2.resize(
|
||||||
|
img, (d_w, d_h),
|
||||||
|
interpolation = cv2.INTER_NEAREST
|
||||||
|
)
|
||||||
|
|
||||||
|
# reshape to 1-dim array(for every color) for k-means
|
||||||
|
# use k-means to abstract the colors to use
|
||||||
|
img_cp = img.reshape(-1, c)
|
||||||
|
criteria = (
|
||||||
|
cv2.TERM_CRITERIA_EPS+cv2.TERM_CRITERIA_MAX_ITER,
|
||||||
|
precise*5, 0.01
|
||||||
|
)
|
||||||
|
_, label, center = cv2.kmeans(
|
||||||
|
img_cp, k, None,
|
||||||
|
criteria, 1, cv2.KMEANS_PP_CENTERS
|
||||||
|
)
|
||||||
|
result = center[label.flatten()]
|
||||||
|
result = result.reshape((img.shape))
|
||||||
|
|
||||||
|
result = cv2.resize(
|
||||||
|
result,
|
||||||
|
(o_w, o_h),
|
||||||
|
interpolation=cv2.INTER_NEAREST
|
||||||
|
)
|
||||||
|
return result.astype(np.uint8), center.astype(np.uint8)
|
||||||
|
|
||||||
|
|
||||||
|
def run(
|
||||||
|
src: Image.Image,
|
||||||
|
k: int = 3,
|
||||||
|
scale: int = 2,
|
||||||
|
blur: int = 0,
|
||||||
|
erode: int = 0,
|
||||||
|
precise: int = 10,
|
||||||
|
) -> tuple[Image.Image, list[list[str|float]]]:
|
||||||
|
#print('Start process.')
|
||||||
|
#print('Read raw image... ', end='', flush=True)
|
||||||
|
img = read_img_as_array(src)
|
||||||
|
|
||||||
|
#convert color space
|
||||||
|
alpha_channel = img[:, :, 3]
|
||||||
|
img = cv2.cvtColor(img, cv2.COLOR_BGRA2RGB)
|
||||||
|
h, w, c = img.shape
|
||||||
|
d_h = h // scale
|
||||||
|
d_w = w // scale
|
||||||
|
o_h = d_h * scale
|
||||||
|
o_w = d_w * scale
|
||||||
|
#print('done!')
|
||||||
|
|
||||||
|
#print('Image preprocess... ', end='', flush=True)
|
||||||
|
# preprocess(erode, blur, saturation, contrast)
|
||||||
|
img = preprocess(
|
||||||
|
img,
|
||||||
|
blur, erode
|
||||||
|
)
|
||||||
|
#print('done!')
|
||||||
|
|
||||||
|
#print('Pixelize... ', end='', flush=True)
|
||||||
|
# pixelize(using k-means)
|
||||||
|
result, colors = pixelize(
|
||||||
|
img, k, c,
|
||||||
|
d_w, d_h,
|
||||||
|
o_w, o_h,
|
||||||
|
precise
|
||||||
|
)
|
||||||
|
#print('done!')
|
||||||
|
|
||||||
|
#print('Process output image... ', end='', flush=True)
|
||||||
|
# add alpha channel
|
||||||
|
a = cv2.resize(
|
||||||
|
alpha_channel, (d_w, d_h),
|
||||||
|
interpolation = cv2.INTER_NEAREST
|
||||||
|
)
|
||||||
|
a = cv2.resize(
|
||||||
|
a, (o_w, o_h),
|
||||||
|
interpolation = cv2.INTER_NEAREST
|
||||||
|
)
|
||||||
|
a[a!=0]=255
|
||||||
|
if 0 not in a:
|
||||||
|
a[0, 0] = 0
|
||||||
|
r, g, b = cv2.split(result)
|
||||||
|
result = cv2.merge((r, g, b, a))
|
||||||
|
|
||||||
|
# for saving to png
|
||||||
|
result = cv2.cvtColor(
|
||||||
|
result, cv2.COLOR_RGBA2BGRA
|
||||||
|
)
|
||||||
|
#print('done!')
|
||||||
|
|
||||||
|
return Image.fromarray(result)
|
||||||
|
|
@ -64,4 +64,10 @@ function switch_to_haku_blend(){
|
||||||
}
|
}
|
||||||
function switch_to_haku_eff(){
|
function switch_to_haku_eff(){
|
||||||
return switch_to_inner_tab('haku_eff')
|
return switch_to_inner_tab('haku_eff')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function switch_to_inpaint_upload(){
|
||||||
|
switch_to_img2img_tab(4);
|
||||||
|
return args_to_array(arguments);
|
||||||
}
|
}
|
||||||
|
|
@ -18,10 +18,4 @@ function change_img_height(id, height){
|
||||||
function get_change_height(id){
|
function get_change_height(id){
|
||||||
id = "div[id*='" + id + "']"
|
id = "div[id*='" + id + "']"
|
||||||
return (height)=>{change_img_height(id, height)}
|
return (height)=>{change_img_height(id, height)}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function switch_to_inpaint_upload(){
|
|
||||||
switch_to_img2img_tab(4);
|
|
||||||
return args_to_array(arguments);
|
|
||||||
}
|
}
|
||||||
|
|
@ -9,10 +9,13 @@ from PIL import Image, ImageFilter, ImageEnhance, ImageColor
|
||||||
import cv2
|
import cv2
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
from hakuimg import blend
|
from hakuimg import(
|
||||||
from hakuimg import color
|
blend,
|
||||||
from hakuimg import blur
|
blur,
|
||||||
from hakuimg import sketch
|
color,
|
||||||
|
sketch,
|
||||||
|
pixel
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
@ -120,6 +123,13 @@ def add_tab():
|
||||||
sk_color = gr.Radio(['gray', 'rgb'], value='gray', label='color mode')
|
sk_color = gr.Radio(['gray', 'rgb'], value='gray', label='color mode')
|
||||||
sk_scale = gr.Checkbox(False, label='use scale')
|
sk_scale = gr.Checkbox(False, label='use scale')
|
||||||
sketch_btn = gr.Button("refresh", variant="primary")
|
sketch_btn = gr.Button("refresh", variant="primary")
|
||||||
|
|
||||||
|
with gr.TabItem('Pixelize', elem_id='haku_Pixelize'):
|
||||||
|
p_colors = gr.Slider(2, 128, 16, step=1, label='colors')
|
||||||
|
p_dot_size = gr.Slider(2, 32, 8, step=1, label='dot size')
|
||||||
|
p_outline = gr.Slider(0, 10, 5, step=1, label='outline inflating')
|
||||||
|
p_smooth = gr.Slider(0, 10, 0, step=1, label='Smoothing')
|
||||||
|
pixel_btn = gr.Button("refresh", variant="primary")
|
||||||
|
|
||||||
with gr.TabItem('Other'):
|
with gr.TabItem('Other'):
|
||||||
with gr.Tabs(elem_id='function list'):
|
with gr.Tabs(elem_id='function list'):
|
||||||
|
|
@ -178,6 +188,15 @@ def add_tab():
|
||||||
component.change(sketch.run, all_sk_input, image_out)
|
component.change(sketch.run, all_sk_input, image_out)
|
||||||
sketch_btn.click(sketch.run, all_sk_input, image_out)
|
sketch_btn.click(sketch.run, all_sk_input, image_out)
|
||||||
|
|
||||||
|
#pixelize
|
||||||
|
all_p_set = [
|
||||||
|
p_colors, p_dot_size, p_smooth, p_outline
|
||||||
|
]
|
||||||
|
all_p_input = [image_eff] + all_p_set
|
||||||
|
for component in all_p_set:
|
||||||
|
component.change(pixel.run, all_p_input, image_out)
|
||||||
|
pixel_btn.click(pixel.run, all_p_input, image_out)
|
||||||
|
|
||||||
#send
|
#send
|
||||||
for btns, btn3, img_src in all_btns:
|
for btns, btn3, img_src in all_btns:
|
||||||
for btn, img in zip(btns, all_layers):
|
for btn, img in zip(btns, all_layers):
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue