add palette module

This commit is contained in:
Vladimir Mandic
2023-02-05 20:04:11 -05:00
parent aee4823e26
commit f4a3ee056f
4 changed files with 156 additions and 168 deletions
+92
View File
@@ -0,0 +1,92 @@
#!/bin/env python
# based on <https://towardsdatascience.com/image-color-extraction-with-python-in-4-steps-8d9370d9216e>
import os
import sys
import pandas as pd
import numpy as np
import extcolors
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import matplotlib.image as mpimg
from matplotlib.offsetbox import OffsetImage, AnnotationBbox
from colormap import rgb2hex
from PIL import Image
def color_to_df(input):
colors_pre_list = str(input).replace('([(','').split(', (')[0:-1]
df_rgb = [i.split('), ')[0] + ')' for i in colors_pre_list]
df_percent = [i.split('), ')[1].replace(')','') for i in colors_pre_list]
#convert RGB to HEX code
df_color_up = [rgb2hex(int(i.split(", ")[0].replace("(","")),
int(i.split(", ")[1]),
int(i.split(", ")[2].replace(")",""))) for i in df_rgb]
df = pd.DataFrame(zip(df_color_up, df_percent), columns = ['c_code','occurence'])
return df
def color_wheel(input_image, resize, tolerance, zoom):
#resize
img = Image.open(input_image)
if img.size[0] >= resize:
wpercent = (resize / float(img.size[0]))
hsize = int((float(img.size[1]) * float(wpercent)))
img = img.resize((resize, hsize))
#crate dataframe
colors_x = extcolors.extract_from_image(img, tolerance = tolerance, limit = 13)
df_color = color_to_df(colors_x)
#annotate text
list_color = list(df_color['c_code'])
list_precent = [int(i) for i in list(df_color['occurence'])]
text_c = [c + ' ' + str(round(p * 100 / sum(list_precent), 1)) +'%' for c, p in zip(list_color, list_precent)]
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(120,60), dpi=10)
#donut plot
wedges, _text = ax1.pie(list_precent, labels= text_c, labeldistance= 1.05, colors = list_color, textprops={'fontsize': 140, 'color':'black'})
plt.setp(wedges, width=0.3)
#add image in the center of donut plot
data = np.asarray(img)
imagebox = OffsetImage(data, zoom=zoom)
ab = AnnotationBbox(imagebox, (0, 0))
ax1.add_artist(ab)
#color palette
x_posi, y_posi, y_posi2 = 160, -200, -200
for c in list_color:
if list_color.index(c) <= 5:
y_posi += 220
rect = patches.Rectangle((x_posi, y_posi), 480, 200, facecolor = c)
ax2.add_patch(rect)
ax2.text(x = x_posi + 40, y = y_posi + 120, s = c, fontdict={'fontsize': 140})
else:
y_posi2 += 220
rect = patches.Rectangle((x_posi + 600, y_posi2), 480, 200, facecolor = c)
ax2.add_artist(rect)
ax2.text(x = x_posi + 640, y = y_posi2 + 120, s = c, fontdict={'fontsize': 140})
#background
tmp_file = 'tmp.png'
fig, _ax = plt.subplots(figsize=(200,140),dpi=10)
fig.set_facecolor('white')
plt.savefig(tmp_file)
plt.close(fig)
fig.set_facecolor('white')
ax2.axis('off')
tmp = plt.imread(tmp_file)
plt.imshow(tmp)
plt.tight_layout()
plt.savefig('palette.jpg')
plt.close()
os.remove(tmp_file)
return
if __name__ == '__main__':
sys.argv.pop(0)
for arg in sys.argv:
color_wheel(arg, 512, 10, 2)
+40 -3
View File
@@ -20,14 +20,16 @@ process people images
import os
import sys
import io
import filetype
import math
import base64
import pathlib
import filetype
import numpy as np
import mediapipe as mp
from PIL import Image, ImageOps
from skimage.metrics import structural_similarity as ssim
from scipy.stats import beta
from util import log, Map
from sdapi import postsync
@@ -45,13 +47,15 @@ params = Map({
'face_score': 0.7, # min face detection score
'face_pad': 0.07, # pad face image percentage
'face_model': 1, # which face model to use 0/close-up 1/standard
'face_blur_score': 1.4, # max score for face blur detection
'face_blur_score': 1.5, # max score for face blur detection
'face_range_score': 0.5, # min score for face dynamic range detection
'body_score': 0.9, # min body detection score
'body_visibility': 0.5, # min visibility score for each detected body part
'body_parts': 15, # min number of detected body parts with sufficient visibility
'body_pad': 0.2, # pad body image percentage
'body_model': 2, # body model to use 0/low 1/medium 2/high
'body_blur_score': 1.6, # max score for body blur detection
'body_blur_score': 1.8, # max score for body blur detection
'body_range_score': 0.5, # min score for body dynamic range detection
'segmentation_face': True, # segmentation enabled
'segmentation_body': False, # segmentation enabled
'segmentation_model': 0, # segmentation model 0/general 1/landscape
@@ -76,6 +80,25 @@ def detect_blur(image):
return mean
def detect_dynamicrange(image):
# based on <https://towardsdatascience.com/measuring-enhancing-image-quality-attributes-234b0f250e10>
data = np.asarray(image)
image = np.float32(data)
RGB = [0.299, 0.587, 0.114]
height, width = image.shape[:2]
brightness_image = np.sqrt(image[..., 0] ** 2 * RGB[0] + image[..., 1] ** 2 * RGB[1] + image[..., 2] ** 2 * RGB[2])
hist, _ = np.histogram(brightness_image, bins=256, range=(0, 255))
img_brightness_pmf = hist / (height * width)
dist = beta(2, 2)
ys = dist.pdf(np.linspace(0, 1, 256))
ref_pmf = ys / np.sum(ys)
dot_product = np.dot(ref_pmf, img_brightness_pmf)
squared_dist_a = np.sum(ref_pmf ** 2)
squared_dist_b = np.sum(img_brightness_pmf ** 2)
res = dot_product / math.sqrt(squared_dist_a * squared_dist_b)
return round(res, 2)
images = []
def detect_simmilar(image):
img = image.resize((params.similarity_size, params.similarity_size))
@@ -149,6 +172,13 @@ def extract_face(img):
else:
log.debug({ 'extract face blur': blur })
range = detect_dynamicrange(squared)
if range < params.face_range_score:
log.info({ 'extract face': 'dynamic range check fail', 'range': range })
return None, True
else:
log.debug({ 'extract face dynamic range': range })
similarity = detect_simmilar(squared)
if similarity > params.similarity_score:
log.info({ 'extract face': 'similarity check fail', 'score': round(similarity, 2) })
@@ -202,6 +232,13 @@ def extract_body(img):
else:
log.debug({ 'extract body blur': blur })
range = detect_dynamicrange(squared)
if range < params.body_range_score:
log.info({ 'extract body': 'dynamic range check fail', 'range': range })
return None, True
else:
log.debug({ 'extract body dynamic range': range })
similarity = detect_simmilar(squared)
if similarity > params.similarity_score:
log.info({ 'extract body': 'similarity check fail', 'score': similarity })