PC-2017.3.2 <Dell@XPS_13_9343 Merge branch 'master'
This commit is contained in:
commit
0bab6a7dd6
BIN
assets/background.png
Normal file
BIN
assets/background.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 38 KiB |
BIN
assets/flower.png
Normal file
BIN
assets/flower.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
@ -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")
|
||||
|
@ -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"}),)
|
||||
|
@ -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",
|
||||
|
||||
),)
|
||||
|
@ -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
|
@ -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(
|
||||
|
48
graphics/image_modification.py
Normal file
48
graphics/image_modification.py
Normal 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)
|
@ -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)
|
||||
|
@ -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):
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user