Spaces:
Sleeping
Sleeping
File size: 6,957 Bytes
78c8c21 091b39e 8f269fd 78c8c21 c198cf5 8f269fd 78c8c21 c198cf5 11c4504 c198cf5 8f269fd |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
import streamlit as st
import os
import streamlit_authenticator as stauth
from code.functions import pipeline_svg
from PIL import Image
import cv2
import numpy as np
from io import BytesIO
import copy
logo = Image.open("seguinmoreau.png")
st.set_page_config(
page_title="Moulinette Logos",
page_icon=logo,
layout="wide",
initial_sidebar_state="expanded"
)
inch_value = 2.54
logo = Image.open('seguinmoreau.png')
st.image(logo, width=200)
st.markdown(
"""
# Boîte à Outils de correction de logos :wrench:
Bienvenue dans la boîte à outils de correction de logos de Seguin Moreau.
### :hammer: Les outils
Dans cette boîte à outils, vous trouverez:
* Un outil de Correction automatique de logo (enlever les petits défauts, lissage, vectorisation, grossissement des traits trop fins).
### :bulb: Mode d'emploi
* Cliquer sur 'Browse files'
* Sélectionner un logo
* La correction est automatique. Si la correction ne vous convient pas, il est possible de régler les paramètres en cliquant sur 'Paramétrage' à droite de l'image.
* Les deux paramètres permettent de corriger les défauts liés à la présence de gris sur le logo ou la 'pixélisation' du logo trop importante.
"""
)
uploaded_files = st.file_uploader("Choisir un logo", accept_multiple_files=True)
image_width = 500
size_value = st.slider("Largeur de trait minimum", min_value=1, max_value=21, value=7, step=2)
size_value = (size_value - 1) // 2
# kernel_type_str = st.selectbox("Kernel type", ["Ellipse", "Rectangle", "Cross"])
kernel_type_str = "Ellipse"
dict_kernel_type = {"Ellipse": cv2.MORPH_ELLIPSE, "Rectangle": cv2.MORPH_RECT, "Cross": cv2.MORPH_CROSS}
kernel_type = dict_kernel_type[kernel_type_str]
for uploaded_file in uploaded_files:
col1, col2, col3 = st.columns([1, 1, 1])
col3.markdown("---")
image = Image.open(uploaded_file).convert('L')
image_input = np.array(image)
image = copy.deepcopy(image_input)
col1.image(image_input / 255.0, caption="Image d'entrée", use_column_width='auto')
with col3:
with st.expander(":gear: Paramétrage"):
st.write("Si l'image contient du gris, faire varier le seuil ci-dessous:")
threshold = st.slider("Seuil pour convertir l'image en noir&blanc.", min_value=0, max_value=255,
value=0,
step=1, key=f"{uploaded_file}_slider_threshold")
st.write("Si l'image est pixelisée, ou contient trop de détails, "
"augmenter la valeur ci-dessous:")
blur_value = st.slider("Seuil pour lisser l'image", min_value=1, max_value=11, value=1, step=2,
key=f"{uploaded_file}_slider_gaussian_sigma")
st.write("Si l'image contient des traits très fin (de l'odre du pixel),"
" augmenter le seuil ci-dessous, de 1 par 1:")
dilate_lines_value = st.slider("Dilatation de l'image d'origine: (en pixels)", min_value=0, max_value=5,
value=0, step=1, key=f"{uploaded_file}_slider_dilation_image")
st.write("Taille d'exportation d'image:")
dpi_value = st.number_input("Valeur dpi:", key=f"{uploaded_file}_number_dpi_value", value=200)
st.write("---")
st.write("Spécifier la taille maximum d'un côté, en cm:")
side_width_value = st.number_input("Taille max de côté cible (cm):",
key=f"{uploaded_file}_number_target_value", value=20.0)
new_largest_side_value = int(side_width_value / inch_value * dpi_value)
h, w, *_ = image.shape
# Resize image
ratio = w / h
if ratio > 1:
width = new_largest_side_value
height = int(width / ratio)
else:
height = new_largest_side_value
width = int(ratio * height)
st.write("---")
st.write("Ou, spécifier la largeur OU la hauteur cible, en cm:")
target_width_value = st.number_input("Largeur cible (cm):", key=f"{uploaded_file}_number_width_value",
value=0.0)
target_height_value = st.number_input("Hauteur cible (cm):", key=f"{uploaded_file}_number_height_value",
value=0.0)
if target_width_value > 0 and target_height_value == 0:
width = int(target_width_value / inch_value * dpi_value)
height = int(width / ratio)
elif target_height_value > 0 and target_width_value == 0:
height = int(target_height_value / inch_value * dpi_value)
width = int(height * ratio)
elif target_height_value > 0 and target_width_value > 0:
st.warning("Vous ne pouvez pas modifier la largeur et la hauteur simultanément.")
st.info(f"Le logo sera redimensionné de :")
st.info(f"hauteur={h} pixels et largeur={w} pixels vers "
f"hauteur={height} pixels et largeur={width} pixels.")
if threshold > 0:
image = (image > threshold) * 255
image = image.astype('uint8')
if blur_value > 0:
image = cv2.GaussianBlur(image, (blur_value, blur_value), blur_value - 1)
# Process image cv32f ==> cv32f
img_final = pipeline_svg(image, size_value=size_value, level=1, threshold=threshold, kernel_type=kernel_type,
dilate_lines_value=dilate_lines_value)
col2.image(img_final, caption="Image corrigée", use_column_width='auto')
# Check for grayscale
tolerance = 10
ratio_of_gray_pixels = int(np.sum((tolerance < image) * (image < 255 - tolerance)) / np.size(image) * 100)
if ratio_of_gray_pixels > 1:
col3.warning(f":warning: Le nombre de pixels gris est élevé: {ratio_of_gray_pixels} % > 1%")
# Check reconstruction fidelity
distance = np.mean((np.array(image) - img_final) ** 2)
if distance > 10:
col3.warning(
f":warning: Le logo est peut-être trop dégradé (MSE={distance:.2f} > 10).\nVérifier visuellement.")
dim = (width, height)
# resize image
resized_img_final = cv2.resize(img_final, dim, interpolation=cv2.INTER_AREA)
resized_image_input = cv2.resize(image_input, dim, interpolation=cv2.INTER_AREA)
buf = BytesIO()
# img_stacked = np.hstack((resized_image_input, resized_img_final))
img_final = Image.fromarray(resized_img_final).convert("L")
img_final.save(buf, format="PNG", dpi=(dpi_value, dpi_value))
byte_im = buf.getvalue()
btn = col3.download_button(
label=":inbox_tray: Télécharger l'image",
data=byte_im,
file_name=f"corrected_{uploaded_file.name}",
mime="image/png"
)
|