PC-2017.3.2 <Dell@XPS_13_9343 Merge branch 'master'

This commit is contained in:
Zofia Zientek 2024-01-08 22:27:38 +01:00
commit 0bab6a7dd6
10 changed files with 195 additions and 94 deletions

BIN
assets/background.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
assets/flower.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -42,8 +42,26 @@ Dziękujemy za korzystanie z **BlurMe**!
@template(route="/about", title="O autorach", image = "/about-icon.png")
def about() -> rx.Component:
return rx.vstack(
#rx.heading("O autorach", font_size="3em"),
rx.markdown(about_authors_text),
)
return rx.vstack(rx.heading("O autorach", font_size="3em", margin_bottom="10px", background_image="linear-gradient( 64.5deg, rgba(245,116,185,1) 14.7%, rgba(89,97,223,1) 88.7% )", background_clip="text", padding = "10px"),
rx.box(
rx.text("Jesteśmy grupą studentek kierunku Przetwarzania i Analizy Danych, które postanowiły połączyć swoje różnorodne umiejętności w ramach wspólnego projektu. Zależy nam nie tylko na zdobywaniu wiedzy na uczelni, ale także na praktycznym wykorzystaniu naszych umiejętności w realnych projektach.", margin_right="5%", margin_left="5%", margin_bottom = "10px"),
rx.list(
rx.list_item( rx.icon(tag="arrow_forward")," W naszym zespole każda z nas wnosi unikalne perspektywy i pomysły, co sprawia, że nasza współpraca jest inspirująca.",),
rx.list_item(rx.icon(tag="arrow_forward"), " Nasza pasja do analizy danych oraz zrozumienie dziedziny przetwarzania danych stanowią fundamenty naszego projektu."),
rx.list_item( rx.icon(tag="arrow_forward")," Naszym głównym celem jest stworzenie innowacyjnego rozwiązania, które nie tylko będzie spełniać potrzeby dzisiejszych czasów, ale również przyczyni się do ochrony prywatności w kontekście współdzielenia zdjęć online.",),
margin_left = "18%", margin_right = "18%"),
rx.text("Dzięki zaufaniu naszych użytkowników oraz naszemu zangażowaniu, wierzymy, że nasz projekt przyczyni się do tworzenia bezpieczniejszej przestrzeni dla współdzielenia zdjęć w sieci. Cieszymy się, że możemy być częścią tej fascynującej podróży.", margin_right="5%", margin_left="5%", margin_top="10px"), text_align = "center",),
rx.list(
rx.list_item(rx.text("Nasza Misja",padding = "10px", text_align="center",background_image="linear-gradient( 64.5deg, rgba(245,116,185,1) 14.7%, rgba(89,97,223,1) 88.7% )", background_clip="text", font_size="2em", font_weight="bold", margin_top="30px", margin_bottom="5px"),
rx.text("Nasza grupa powstała z fascynacji technologią oraz z troską o prywatność w dzisiejszym świecie online. Świadomi wyzwań związanych z udostępnianiem fotografii publicznie, postanowiliśmy stworzyć aplikację, która umożliwi użytkownikom ochronę swojej prywatności, jednocześnie pozwalając na swobodne udostępnianie chwil z życia."),margin_right = "40%"),
rx.list_item(rx.text("Jak Powstała Nasza Grupa",padding = "10px", text_align="center",background_image="linear-gradient( 64.5deg, rgba(245,116,185,1) 14.7%, rgba(89,97,223,1) 88.7% )", background_clip="text", font_size="2em", font_weight="bold", margin_top="30px", margin_bottom="5px"),
rx.text("Nasza grupa skupia się na różnorodnych dziedzinach, takich jak sztuczna inteligencja, przetwarzanie obrazów i programowanie. Nasza wspólna pasja do technologii oraz zaangażowanie w projekt zrodziły kreatywną współpracę. Spotkaliśmy się na naszych studiach, gdzie zauważyliśmy potrzebę stworzenia narzędzia, które połączy technologię z ochroną prywatności."),margin_left = "40%"),
rx.list_item(rx.text("Dlaczego BlurMe?",padding = "10px", text_align="center",background_image="linear-gradient( 64.5deg, rgba(245,116,185,1) 14.7%, rgba(89,97,223,1) 88.7% )", background_clip="text", font_size="2em", font_weight="bold", margin_top="30px", margin_bottom="5px"),
rx.text("BlurMe to wynik naszej wspólnej wizji, aby uczynić proces ochrony prywatności prostym i dostępnym dla każdego. Chcemy, aby ludzie czuli się pewnie dzieląc się zdjęciami, nie martwiąc się o potencjalne naruszenia prywatności.",), margin_right = "40%"),
rx.list_item(rx.text("O Naszych Umiejętnościach",padding = "10px", text_align="center",background_image="linear-gradient( 64.5deg, rgba(245,116,185,1) 14.7%, rgba(89,97,223,1) 88.7% )", background_clip="text", font_size="2em", font_weight="bold", margin_top="30px", margin_bottom="5px"),
rx.text("Nasza grupa składa się z pasjonatów programowania, inżynierii oprogramowania i sztucznej inteligencji. Dzięki naszym umiejętnościom oraz współpracy zdobyliśmy doświadczenie w tworzeniu zaawansowanych algorytmów przetwarzania obrazów, które pozwalają na automatyczne wykrywanie twarzy i rejestracji samochodowych na zdjęciach." ),margin_left = "40%"),
rx.list_item(rx.text("Kontakt",padding = "10px", text_align="center",background_image="linear-gradient( 64.5deg, rgba(245,116,185,1) 14.7%, rgba(89,97,223,1) 88.7% )", background_clip="text", font_size="2em", font_weight="bold", margin_top="30px", margin_bottom="5px"),
rx.text("Jeśli masz pytania, sugestie lub chciałbyś dowiedzieć się więcej o naszej grupie, skontaktuj się z nami poprzez naszą stronę kontaktową. Jesteśmy otwarci na współpracę i ciekawe pomysły!"),margin_right = "40%"),
text_align = "center"), margin_right= "65px", margin_left = "65px")

View File

@ -40,31 +40,24 @@ def dashboard() -> rx.Component:
The UI for the dashboard page.
"""
container_style = {"background-color": "#f5f5f5", "padding": "10px", "margin-bottom": "20px", "display": "flex", "align-items": "center"}
icon_style = {"width": "20px", "height": "20px", "margin-right": "10px"}
icon_style = {"width": "20px", "height": "30px", "margin-right": "10px"}
heading_style = {"font-weight": "bold", "font-family": "Arial, sans-serif"}
return rx.fragment(
rx.heading("Kontakt", font_size="3em"),
rx.text("Witaj na stronie Kontaktowej w aplikacji BlurMe!"),
rx.heading("Kontakt", font_size="3em", margin_bottom="10px", background_image="linear-gradient( 64.5deg, rgba(245,116,185,1) 14.7%, rgba(89,97,223,1) 88.7% )", background_clip="text", padding = "10px", text_align = "center"),
rx.text("Witaj na stronie Kontaktowej w aplikacji BlurMe!", text_align = "center", margin_right = "15%", margin_left="15%"),
rx.text(
"Jesteśmy dostępni dla Ciebie na różnych platformach. "
"Skontaktuj się z nami, gdy tylko masz pytania, sugestie lub "
"po prostu chcesz porozmawiać o naszej aplikacji."
"po prostu chcesz porozmawiać o naszej aplikacji.", text_align = "center", margin_right = "15%", margin_left="15%"
),
rx.fragment(
rx.fragment(
rx.image(src=ICON_EMAIL, alt="Email icon", style=icon_style),
rx.heading("E-mail", level=3, style=heading_style),
rx.wrap(rx.hstack(rx.vstack(rx.fragment(
rx.hstack(rx.icon(tag="email",style=icon_style),
rx.heading("E-mail", level=3, style=heading_style), margin_top="20px"),
rx.text("Zapraszamy do napisania do nas na adres: contact@blurme.com"),
style=container_style
)
),
rx.fragment(
rx.fragment(
rx.image(src=ICON_PHONE, alt="Phone icon", style=icon_style),
rx.heading("Telefon", level=3, style=heading_style),
style=container_style,text_align = "center")),
rx.vstack(rx.fragment(
rx.hstack(rx.icon(tag="phone", style=icon_style),rx.heading("Telefon", level=3, style=heading_style), margin_top="20px"),
rx.text("Możesz także zadzwonić pod numer: +48 123 456 789"),
style=container_style
)
)
)
style=container_style, text_align = "center"),),
),style={"align-self": "flex-center"}),)

View File

@ -10,20 +10,66 @@ color = "rgb(107,99,246)"
@template(route="/settings", title="Zdjęcie", image = "/image-icon.png")
def settings() -> rx.Component:
return rx.vstack(
return rx.vstack(
rx.heading("BlurMe", font_size="3em", margin_bottom="25px", background_image="linear-gradient(271.68deg, #7566fe 0.75%, #f96caf 88.52%)", background_clip="text", padding = "10px"),
rx.text("Dodaj zdjęcie, które chcesz zanonimizować", font_size="1.2em"),
rx.upload(
rx.vstack(rx.text("Drag and drop files here or click to select files"),),
rx.vstack(rx.text("Przeciągnij albo kliknij, aby wybrać pliki"),),
border=f"1px dotted {color}",
padding="5em",),
padding="5em",
multiple=True,
accept={
"image/png": [".png"],
"image/jpeg": [".jpg", ".jpeg"],
"image/webp": [".webp"],
"image/tiff": [".tif", ".tiff"], },
max_files=5,
),
rx.hstack(rx.foreach(rx.selected_files, rx.text)),
rx.button( "Upload",
rx.button( "Załaduj zdjęcie",
on_click=lambda: State.handle_upload(
rx.upload_files()),),
rx.button("Clear",
on_click=rx.clear_selected_files),
rx.foreach(
State.img, lambda img: rx.image(src=f'/{img}')),
padding="5em",
)
rx.upload_files()),color = "rgba(47, 187, 74,255)"),
rx.responsive_grid(
rx.foreach(
State.img,
lambda img: rx.vstack(
rx.image(src=f'/{img}', height = "200px"),
rx.text(img),
rx.hstack(rx.button("Usuń",
on_click=lambda img_name=img: State.delete_image(img_name), color="rgba(255, 75, 42,255)",
width = "125px"),
rx.button("Anonimizuj",
width = "125px"),
rx.button("Pobierz",
on_click=lambda img_name=img: State.download_image(img_name),
width = "125px"),
padding="1em"
),
),
),columns=[2],
spacing="5px",
#rx.foreach(
# State.img,
# lambda img: rx.vstack(
# rx.image(src=f'/{img}', max_width = "800px"),
# rx.hstack(rx.button("Usuń",
# on_click=lambda img_name=img: State.delete_image(img_name),
# width = "125px"),
# rx.button("Anonimizuj",
# width = "125px"),
# rx.button("Pobierz",
# on_click=lambda img_name=img: State.download_image(img_name),
# width = "125px"),
# padding="1em"
# ),
# padding="3em",
),)

View File

@ -4,7 +4,53 @@ import reflex as rx
from blurme import styles
import asyncio
class State(rx.State):
"""The app state."""
# The images to show.
img: list[str] = []
# Dark mode status
#dark_mode: bool = False
show: bool = False
def change(self):
self.show = not (self.show)
async def handle_upload(self, files: list[rx.UploadFile]):
"""Handle the upload of file(s).
Args:
files: The uploaded files.
"""
for file in files:
#if len(self.img) >= 5:
upload_data = await file.read()
outfile = rx.get_asset_path(file.filename)
# Save the file.
with open(outfile, "wb") as file_object:
file_object.write(upload_data)
# Update the img var.
self.img.append(file.filename)
self.img = self.img
def delete_image(self, img_name: str):
if img_name in self.img:
self.img.remove(img_name)
self.img=self.img
def download_image(self, img_name):
print(self.img)
return rx.download(url=f'/{img_name}', filename=img_name)
#async def toggle_dark_mode(self):
# self.dark_mode = not self.dark_mode
# print(f"Dark Mode State: {self.dark_mode}")
#class State(rx.State):
# def __init__(self):
# super().__init__()
@ -17,30 +63,4 @@ import asyncio
# styles.text_color = text_color
# print(f"Dark Mode State: {self.dark_mode_state}")
# print(f"Current Text Color: {text_color}")
# pass
class State(rx.State):
"""The app state."""
# The images to show.
img: list[str] = []
async def handle_upload(self, files: list[rx.UploadFile]):
"""Handle the upload of file(s).
Args:
files: The uploaded files.
"""
for file in files:
upload_data = await file.read()
outfile = rx.get_asset_path(file.filename)
# Save the file.
with open(outfile, "wb") as file_object:
file_object.write(upload_data)
# Update the img var.
self.img.append(file.filename)
self.img = self.img
print(f"Current Text Color: {self.img[0]}")
# pass

View File

@ -13,9 +13,6 @@ text_color_light = "black"
text_color_dark = "white"
accent_text_color = "black"
accent_color = "linear-gradient(linear-gradient(43deg, rgba(201,238,248,1) 18%, rgba(253,210,227,0.7792366946778712) 86%)"
#linear-gradient(120deg, #d299c2 0%, #fef9d7 100%);"
#linear-gradient(to top, #d9afd9 0%, #97d9e1 100%);"
hover_accent_color = {"_hover": {"color": accent_color}}
hover_accent_bg = {"_hover": {"bg": accent_color}}
content_width_vw = "90vw"
@ -43,16 +40,6 @@ overlapping_button_style = {
"border_radius": border_radius,
}
#base_style = {
# rx.MenuButton: {
# "width": "3em",
# "height": "3em",
# **overlapping_button_style,
# },
# rx.MenuItem: hover_accent_bg,
#}
markdown_style = {
"code": lambda text: rx.code(text, color="#1F1944", bg="#EAE4FD", margin="10px 0"),
"a": lambda text, **props: rx.link(

View File

@ -0,0 +1,48 @@
import os
from typing import List
from PIL import Image, ImageDraw, ImageFont, ImageFilter
from PIL.Image import composite
from BlurMe.ml.element_detection import BoundBox
DIR_PATH = os.path.dirname(os.path.realpath(__file__))
def show_image_with_boxes(
in_image_path: str, bounding_boxes: List[BoundBox], out_image_path: str = None
):
img = Image.open(in_image_path)
draw = ImageDraw.Draw(img)
font_path = DIR_PATH + "/assets/fonts/arial.ttf"
font = ImageFont.truetype(font_path, 25)
for i, box in enumerate(bounding_boxes):
draw.rectangle(box.get_params(), outline="red", width=2, fill=None)
draw.text((box.x1 + 5, box.y1 + 5), str(i + 1), fill="red", font=font)
if not out_image_path:
out_image_path = (
in_image_path.split(".")[0] + "_out." + in_image_path.split(".")[1]
)
img.save(out_image_path)
def blur_boxes_on_image(
in_image_path: str, bounding_boxes: List[BoundBox], out_image_path: str = None
):
img = Image.open(in_image_path)
blur_img = img.filter(ImageFilter.GaussianBlur(radius=7))
mask = Image.new("L", img.size, 255)
draw_mask = ImageDraw.Draw(mask)
for box in bounding_boxes:
if box.selected:
if box.object == "plate":
draw_mask.rectangle(box.get_params(), fill=0)
elif box.object == "face":
draw_mask.ellipse(box.get_params(), fill=0)
mask = mask.filter(ImageFilter.GaussianBlur(radius=3))
img = composite(img, blur_img, mask)
if not out_image_path:
out_image_path = (
in_image_path.split(".")[0] + "_blurred." + in_image_path.split(".")[1]
)
img.save(out_image_path)

View File

@ -2,7 +2,6 @@ import os
from typing import List, Tuple
import torch
from PIL import Image, ImageDraw, ImageFont
from ultralytics import YOLO
@ -16,9 +15,12 @@ IOU_THRESH = 0.5
class BoundBox:
def __init__(self, x1, y1, x2, y2):
def __init__(self, x1, y1, x2, y2, object=None):
self.x1, self.y1, self.x2, self.y2 = x1, y1, x2, y2
self.selected = True
if object not in ["face", "plate"]:
raise ValueError("object must be either 'face' or 'plate'")
self.object = object
def select(self):
self.selected = True
@ -41,29 +43,14 @@ def detect(image_path: str) -> List[BoundBox]:
)
plates = plates[0].cpu().numpy().boxes
bounding_boxes = []
for boxes in [faces, plates]:
for boxes, tag in zip([faces, plates], ["face", "plate"]):
for box in boxes:
xyxyn = box.xyxy[0]
x1 = int(xyxyn[0])
y1 = int(xyxyn[1])
x2 = int(xyxyn[2])
y2 = int(xyxyn[3])
bounding_boxes.append(BoundBox(x1, y1, x2, y2))
bounding_boxes.append(BoundBox(x1, y1, x2, y2, tag))
return bounding_boxes
def show_image_with_boxes(
in_image_path: str, bounding_boxes: List[BoundBox], out_image_path: str = None
):
img = Image.open(in_image_path)
draw = ImageDraw.Draw(img)
font_path = DIR_PATH + "/assets/fonts/arial.ttf"
font = ImageFont.truetype(font_path, 25)
for i, box in enumerate(bounding_boxes):
draw.rectangle(box.get_params(), outline="red", width=2, fill=None)
draw.text((box.x1 + 5, box.y1 + 5), str(i+1), fill="red", font=font)
if not out_image_path:
out_image_path = (
in_image_path.split(".")[0] + "_out." + in_image_path.split(".")[1]
)
img.save(out_image_path)

View File

@ -1,6 +1,8 @@
import unittest
from unittest.mock import Mock, patch
from element_detection import detect, show_image_with_boxes, BoundBox
from element_detection import detect, BoundBox
from BlurMe.graphics.image_modification import show_image_with_boxes
class TestYourModule(unittest.TestCase):