Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: mastnacek 21. 02. 2023, 22:12:50
-
Hraju si s openCV a pythonem nad rodinnou sbirkou fotek. Momentalne resim, jak rychle a elegantne presunout opravdu hodne rozmazane fotky mimo.
V tehle oblasti jsem uplny zelenac, takze jsem si pomohl pokecal s ChatGPT a dali jsem dokupy tohle. Je to sice napsace s cestama pro windows, ale davali jsem to dokupy pro linux, meni se pouze cesty.
Prohledat to INPUT_DIR rekurzivne s omezenim na obrazove soubory. Detekuje to tvare a hodnota return fm < 40 urcuje prah rozmazani, kdy je fotka uz "spatna" a bude presunuta, nebo je v poradku. Jsem na zacatku. Mate nekdo s openCV zkusenosti?
import os
import cv2
INPUT_DIR = 'C:\\aaa\\aaa\\aaa'
OUTPUT_DIR_OK = 'E:\\aaa\\aaa\\bb'
OUTPUT_DIR_ROZMAZANE = 'E:\\aaa\\aaa\\cc'
face_cascade = cv2.CascadeClassifier('C:\\python\\Lib\\site-packages\\cv2\\data\\haarcascade_frontalface_default.xml')
def is_blurry(img):
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
fm = cv2.Laplacian(gray, cv2.CV_64F).var()
return fm < 40
def detect_faces(img):
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
return len(faces) > 0
def process_file(file_path):
img = cv2.imread(file_path)
if is_blurry(img) or not detect_faces(img):
output_path = os.path.join(OUTPUT_DIR_ROZMAZANE, os.path.basename(file_path))
os.replace(file_path, output_path)
else:
output_path = os.path.join(OUTPUT_DIR_OK, os.path.basename(file_path))
os.replace(file_path, output_path)
def process_dir(input_dir):
for root, dirs, files in os.walk(input_dir):
for file in files:
if file.lower().endswith(('.jpg', '.png', '.bmp')):
file_path = os.path.join(root, file)
process_file(file_path)
if __name__ == "__main__":
if not os.path.exists(OUTPUT_DIR_OK):
os.makedirs(OUTPUT_DIR_OK)
if not os.path.exists(OUTPUT_DIR_ROZMAZANE):
os.makedirs(OUTPUT_DIR_ROZMAZANE)
process_dir(INPUT_DIR)
print("Done.")
-
Optimalizace
import cv2
import os
# vstupni a vystupni slozky
INPUT_DIR = 'E:\\aaa\\aaa\\aaa'
OUTPUT_DIR_OK = 'E:\\aaa\\aaa\\bb'
OUTPUT_DIR_ROZMAZANE = 'E:\\aaa\\aaa\\cc'
# inicializace kaskad pro detekci obliceju a tel
face_cascade = cv2.CascadeClassifier('C:\\python\\Lib\\site-packages\\cv2\\data\\haarcascade_frontalface_default.xml')
body_cascade = cv2.CascadeClassifier('C:\\python\\Lib\\site-packages\\cv2\\data\\haarcascade_fullbody.xml')
# funkce pro detekci rozmazani obrazku
def is_blurry(img):
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
laplacian_var = cv2.Laplacian(gray, cv2.CV_64F).var()
canny_var = cv2.Canny(gray, 100, 200).var()
contrast = cv2.meanStdDev(gray)[1][0][0]
return laplacian_var < 40 or canny_var < 20 or contrast < 25
# funkce pro detekci obliceju a tel v obrazku
def detect_faces(img):
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
bodies = body_cascade.detectMultiScale(gray, 1.3, 5)
return (len(faces) > 0) or (len(bodies) > 0)
# funkce pro zpracovani jednoho souboru
def process_file(file_path):
img = cv2.imread(file_path)
if is_blurry(img) or not detect_faces(img):
output_path = os.path.join(OUTPUT_DIR_ROZMAZANE, os.path.basename(file_path))
os.replace(file_path, output_path)
print(f"Soubor {file_path} byl presunut do adresare {OUTPUT_DIR_ROZMAZANE} kvuli rozmazanym oblicejum nebo telum.")
else:
output_path = os.path.join(OUTPUT_DIR_OK, os.path.basename(file_path))
os.replace(file_path, output_path)
print(f"Soubor {file_path} byl presunut do adresare {OUTPUT_DIR_OK}.")
# funkce pro zpracovani celeho adresare
def process_dir(input_dir):
for root, dirs, files in os.walk(input_dir):
for file in files:
if file.lower().endswith(('.jpg', '.png', '.bmp')):
file_path = os.path.join(root, file)
process_file(file_path)
# zpracovani vstupniho adresare
if __name__ == "__main__":
if not os.path.exists(OUTPUT_DIR_OK):
os.makedirs(OUTPUT_DIR_OK)
if not os.path.exists(OUTPUT_DIR_ROZMAZANE):
os.makedirs(OUTPUT_DIR_ROZMAZANE)
process_dir(INPUT_DIR)
print
-
ty parametry pro test zda je obrazek rozmazany jsou vec heuristiky, kazdy to muze videt jinak.
musite si sam nastavit ty hodnoty podle sebe.
-
taky by chtelo zkusit zda opravdu testovat nad sedym obrazkem, zda spise netestovat kazdou slozku rgb, pripadne hsv.
-
Urcite je to individualni jak to kdo potrebuje. Me treba ted staci zbavit se totalne rozmazanych fotech.
Prevod do sedi je tam kvuli tomu laplacian vypoctu. Pridali jsme tam s chatbotem detekci ostrosti hran.
import cv2
import os
# vstupni a vystupni slozky
INPUT_DIR = 'E:\\FOTKY\\BABICKY_FOTAK\\FOTKY'
OUTPUT_DIR_OK = 'E:\\FOTKY\\BABICKY_FOTAK\\ok'
OUTPUT_DIR_ROZMAZANE = 'E:\\FOTKY\\BABICKY_FOTAK\\rozmazane'
# funkce pro detekci rozmazani obrazku
def is_blurry(img):
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
laplacian_var = cv2.Laplacian(gray, cv2.CV_64F).var()
canny_var = cv2.Canny(gray, 100, 200).var()
contrast = cv2.meanStdDev(gray)[1][0][0]
return laplacian_var < 40 or (canny_var < 20 or contrast < 25)
# funkce pro zpracovani jednoho souboru
def process_file(file_path):
img = cv2.imread(file_path)
if is_blurry(img):
output_path = os.path.join(OUTPUT_DIR_ROZMAZANE, os.path.basename(file_path))
os.replace(file_path, output_path)
print(f"Soubor {file_path} byl presunut do adresare {OUTPUT_DIR_ROZMAZANE} kvuli rozmazani.")
else:
output_path = os.path.join(OUTPUT_DIR_OK, os.path.basename(file_path))
os.replace(file_path, output_path)
print(f"Soubor {file_path} byl presunut do adresare {OUTPUT_DIR_OK}.")
# funkce pro zpracovani celeho adresare
def process_dir(input_dir):
for root, dirs, files in os.walk(input_dir):
for file in files:
if file.lower().endswith(('.jpg', '.png', '.bmp')):
file_path = os.path.join(root, file)
process_file(file_path)
# zpracovani vstupniho adresare
if __name__ == "__main__":
if not os.path.exists(OUTPUT_DIR_OK):
os.makedirs(OUTPUT_DIR_OK)
if not os.path.exists(OUTPUT_DIR_ROZMAZANE):
os.makedirs(OUTPUT_DIR_ROZMAZANE)
process_dir(INPUT_DIR)
print("Hotovo.")
-
zopakuji to, proc zustavate jen u prevodu do sedi?
detekci ostrosti/rozmazanosti hran laplacianem lze delat nejen nad vysedenym obrazkem, ale i nad jednotlivymi slozkami r, g, b nebo prevest na h, s, v a pouzit tohle.
https://en.m.wikipedia.org/wiki/HSL_and_HSV
-
A k tomuto tvojmu super kodu a unesenia s AI ty poviem tajomstvo. Chces? Prave si sa krasne okradol :D To s coho si uneseny a paf su uplne zakladne veci ktore najdes za par minut v stovkach prikladov. Takto si dostal nieco co sice cosi spravi ale netusis ako a preco. Nevies ze mas x dalsich moznosti a dalsim krokom pre teba bude spytat sa AI a dufat ze posklada novy kod ktory to bude splnat a nevymaze nezmeni ziadnu funkcnost. Schvalne chod dalej a povedz ze chces detekciu rozmazanosti, automaticke zosvetlenie atd a zadas.
alex6bbc : Lebo AI mu tak povedala a vlastne ani netusi co robi. Mozno ani nevie ze to dokaze. :D
-
A k tomuto tvojmu super kodu a unesenia s AI ty poviem tajomstvo. Chces? Prave si sa krasne okradol :D To s coho si uneseny a paf su uplne zakladne veci ktore najdes za par minut v stovkach prikladov. Takto si dostal nieco co sice cosi spravi ale netusis ako a preco. Nevies ze mas x dalsich moznosti a dalsim krokom pre teba bude spytat sa AI a dufat ze posklada novy kod ktory to bude splnat a nevymaze nezmeni ziadnu funkcnost. Schvalne chod dalej a povedz ze chces detekciu rozmazanosti, automaticke zosvetlenie atd a zadas.
alex6bbc : Lebo AI mu tak povedala a vlastne ani netusi co robi. Mozno ani nevie ze to dokaze. :D
snazim se ho popostrcit, bud mu to otevre obzory a zacne se zajimat co a jak, nebo zustane nepoliben znalostmi a bude uz jen zavisly na ai. pak muze jit lidstvo do zadele.
-
alex6bbc: nemusi. Prave naopak. Ostanu len "dobry". Ak nema v sebe potrebu vediet a chapat preco je to tak, staci mu ze mu nekto da riesenie tak AI je idealna. Ak chce vediet co a ako ,tak sa bude zaujimat a ucit a posunie sa. AI je zabijak pre ludi ako Jezko ktory generuju tony clankov o pochybnej kvalite, kde prezentuju svoj nazor ako fakt. Jeho AI nahradi ako oci. A co dalej s nim? Bude fotit na film? S coho bude zit? Vlastne nic nevie okrem toho fotenia a pisania clankov. A to su ludia ktory sa boja AI, presne ich AI zomelie. S pohladu mna programatora je to skvele pokial si necham poradit/doporucit nieco, ale nepozeram sa na to ako na nieco co spravi moju pracu, pozeram sa na to ako na sikovneho kolegu ktoreho sa vies spytat nieco co nie je jasne a vie to ozrejmit (Kombinacia chatGPT a Copilot)
-
alex6bbc: diky za popostrkavani a kritiku ai, samozrejme jsem hledal i jine zdroje ( ze kterych ai vychazi ) a nikde jsem nevidel laplacian jinak nez v sedi. Zkusim to. Vy mate konkretni zkusenosti jak si vede grey a barvy?
A k te kritice ai, mam to presne jako Wangarad ( kdyz pominu, ze jsem to objevil pred par dny ). Vidim to jako druhe oci a zjednoduseni v setreni casu s procitanim dokumentaci. Muj zivot je moc kratkej na to, abych do vseho pronikal do hloubky. To si muze dovolit nekdo kdo nema rodinu a nebo uz deticky vyletely z hnizda. Kdyz se clovek sikovne pta, tak gpt dava velice dobry vysledky. Co se me velice libi, tak jako ( i kdyz ne moc sikovnymu ) programatorovi to setri cas napr s komentovanim kodu.
-
a nikde jsem nevidel laplacian jinak nez v sedi. Zkusim to. Vy mate konkretni zkusenosti jak si vede grey a barvy?
prevod RGB do GREY bere nejvice ze zelene slozky a nejmene modre: grayscale = 0.3 * R + 0.59 * G + 0.11 * B
prevod do HSV, HSL ma jine prevodni matice, bez vyzkouseni nerikam, ze je to lepsi nez GREY, ale je to dobre vyzkouset.
a existuje hodne jinych metod na detekci hran nez jen Laplacian.
https://en.wikipedia.org/wiki/Edge_detection
-
Diky za nakopnuti, vcera jsem si ( nebudu rikat diky komu :) ) zkousel prave i dalsi moznosti v kombinaci s detekci osob a obliceju. Ale je dobre mozne, ze se po case zase vratim k digikamu a pohraju si s nastavenim detekce v nem. Myslim ze pouziva take tyhle zpusoby. V pythonu jsem si chtel napsat par scriptu pro jakous takous automatizaci pro cleny rodiny. Dnes ma kazdy tuny fotek a jen se to hromadi i s balastem a v tom lepsim pripade si to zalohuji alespon na google fotky. Potom jsou ty rozmazane a malo kvalitni fotky problem ( objem dat ).
-
OT: Daju sa tie AI pouzivat aj bez toho aby som si tam musel vytvarat konto s mojim telefonnym cislom? Pride mi to trochu scestne aby som do chatu registroval svoje realne udaje.
-
Zdravím super vlákno,
moc se v tom neorientuji, ale zeptám se na performance, když budu mít 5000 fotek, jak dlouho to zpracovaní bude trvat?
Mám Nas server, synology, lze udělat web aplikaci, která mi projede všechny adresáře kde mám fotky a udělá mi analýzu ? A nebude potřebovat žádné natáhnuté knihovny online z Internetu?
Mám dost fotek všude možně a tohle by mohlo pomoci setřídit nebo smazat nepotřebné fotky.
Nebo i identifikovat fotky kde mám manželku a je třeba někdo jiný.
-
Mam v planu to pak nasadit na Synology nasku, hodne veci se da vyresit dockerem. Identifikace obliceju, obektu, zvirat, to vsecko lze, ale nez to dam dokupy :) Aplikace by na to potreba ani nebyla, pokud by to melo bezet v cronu, probihalo by vse automaticky. Jsou i takove moznosti, ze se pomoci python zapise informace do metatagu fotek.
-
Mam v planu to pak nasadit na Synology nasku, hodne veci se da vyresit dockerem. Identifikace obliceju, obektu, zvirat, to vsecko lze, ale nez to dam dokupy :) Aplikace by na to potreba ani nebyla, pokud by to melo bezet v cronu, probihalo by vse automaticky. Jsou i takove moznosti, ze se pomoci python zapise informace do metatagu fotek.
dobře, ale ty k tomu aplikace rozpoznala nebo identifikovala známé obličeje musím mít nějakou databází fotek na kterých určíš sám, že tohle je tvoje manželka a tohle jsou třeba tvé děti. Databáze bude na Synology. Pak potřebuješ knihovny, které dělají analýzu fotek na disku, také na Synology.
Jde mi o to, že pro analýzu fotek mohu mít vše potřebné na Synology a vůbec nemusím být připojený na internetu. Nechci na analýzu posílat někam do cloudu své privátní fotky.
Chápu to tak dobře ?
-
To vsechno jde udelat, vytvori se trenovaci soubory. Jsem teprve na zacatku. treba pomoci openCV se projedou fotky, detekuji se obliceje, vyrobi se vyrezy jen s nimi... dal jsem jeste nedosel, napriklad jak urcim, ke kteremu jemu je priradit.
-
Zkousim k zjisteni rozmazani imagemagick, je to o hodne pomalejsi, ale vysledky vypadaji lepe
import os
import subprocess
# Cesta k složce se vstupními obrázky
input_folder = '/home/uziv/TESTY/IN'
# Cesta k výstupní složce
output_folder = '/home/uziv/TESTY/OUT'
# Nastavení prahové hodnoty pro detekci rozmazání
THRESHOLD_BLUR = 0.1
# Krok 1: Načtení obrázků a detekce rozmazání
for file_name in os.listdir(input_folder):
# Zkontrolujeme, zda se jedná o soubor s obrázkem
if file_name.lower().endswith(('.jpg', '.jpeg', '.png', '.bmp')):
input_path = os.path.join(input_folder, file_name)
output_path = os.path.join(output_folder, file_name)
# Spuštění příkazu Identify pro zjištění velikosti obrázku
identify_output = subprocess.check_output(['identify', '-format', '%w,%h', input_path])
width, height = identify_output.decode().split(',')
# Spuštění příkazu Convolve pro získání konvoluce obrázku s Gaussovým jádrem
convolve_output = subprocess.check_output(['convert', input_path, '-colorspace', 'gray', '-define', 'convolve:scale=1.5', '-morphology', 'Convolve', 'Gaussian:0x3', '-format', '%[fx:maxima.mean]', 'info:'])
maxima_mean = float(convolve_output.decode())
# Vypočítání průměru a směrodatné odchylky z gradientů vodorovného a svislého směru
sobel_output = subprocess.check_output(['convert', input_path, '-colorspace', 'gray', '-define', 'convolve:scale=1.5', '-define', 'convolve:normalize=false', '-morphology', 'Convolve', 'Sobel:0x1', '-format', '%[fx:mean],%[fx:standard_deviation]', 'info:'])
sobel_mean, sobel_std = map(float, sobel_output.decode().split(','))
# Pokud je hodnota maximálního průměru gradientů menší než prahová hodnota,
# obrázek se považuje za rozmazaný a přesune se do složky
if maxima_mean < THRESHOLD_BLUR:
output_subfolder = os.path.join(output_folder, 'rozmazane')
else:
output_subfolder = os.path.join(output_folder, 'ostre')
if not os.path.exists(output_subfolder):
os.makedirs(output_subfolder)
# Uložíme výsledný obrázek do příslušné složky
output_path = os.path.join(output_subfolder, file_name)
os.replace(input_path, output_path)
print(f"Obrázek {file_name} byl přesunut do složky {output_subfolder}.")
else:
print(f"Soubor {file_name} není obrázek, přeskočen.")
-
Pokud jde o jpeg soubory, tak bych rozmazani detekoval treba velikosti AC komponent (at uz absoutni hodnotu, nebo zkompresenou velikost).
V zjednousene podobe to znamena seradit soubory dle velikosti a ty mensi budou mit holt mensi entropii a vice rozmazanych mist.
Pokud neudelas relativni klasifikaci v nejake mrizce, tak tento zpusob bude mit stejne neduhy jako naivni mira bluru - tj. prijdes o vsechny fotky ktere maji treba v sobe oblohu.
-
Diky za pripominku. Je to komplexni. Jeste jsem nezkousel takove ty fotky, kde je pozadi zamerne rozostrene.