Galaxydude2 commited on
Commit
72ae5cb
·
verified ·
1 Parent(s): 1a21b55

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +56 -35
app.py CHANGED
@@ -4,12 +4,15 @@ from PIL import Image, ImageDraw, ImageFont
4
  import cv2
5
  from nudenet import NudeDetector
6
 
 
7
  DETECTION_MAX_DIM = 768
8
  PIXELS_PER_CM_ESTIMATE = 15
9
  MIN_CONFIDENCE = 0.45
10
 
 
11
  detector = NudeDetector(inference_resolution=640)
12
 
 
13
  def resize_for_detection(img_pil, max_dim):
14
  if max(img_pil.width, img_pil.height) <= max_dim:
15
  return img_pil, 1.0
@@ -21,35 +24,46 @@ def resize_for_detection(img_pil, max_dim):
21
 
22
  def describe_breast_precise(crop_pil):
23
  w,h = crop_pil.size
24
- if w*h==0: return "Fehler: leeres Crop"
 
25
  gray = cv2.cvtColor(np.array(crop_pil), cv2.COLOR_RGB2GRAY)
26
- _, thresh = cv2.threshold(gray,100,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
27
- contours,_ = cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
28
- nipple_detected = any(40<cv2.contourArea(c)<(w*h/4) and (p:=cv2.arcLength(c,True))>0 and (4*np.pi*cv2.contourArea(c)/(p*p))>0.55 for c in contours)
29
- ratio=w/h
30
- shape="Breit" if ratio>1.15 else "Hoch" if ratio<0.85 else "Rund"
31
- size="klein" if w*h<28000 else "mittel" if w*h<75000 else "groß" if w*h<140000 else "sehr groß"
32
- w_cm=round(w/PIXELS_PER_CM_ESTIMATE,1)
33
- h_cm=round(h/PIXELS_PER_CM_ESTIMATE,1)
 
 
 
 
34
  return f"Brust: {shape}, {size}, Nippel: {'Ja' if nipple_detected else 'Nein'}, {w_cm}x{h_cm}cm"
35
 
36
  def describe_vagina_precise(crop_pil):
37
- w,h=crop_pil.size
38
- if w*h==0: return "Fehler: leeres Crop"
39
- gray=cv2.cvtColor(np.array(crop_pil), cv2.COLOR_RGB2GRAY)
40
- hair_ratio=np.sum(np.inRange(gray,35,145)>0)/(w*h)
41
- shaved="rasiert" if hair_ratio<0.04 else "minimal" if hair_ratio<0.13 else "Brazilian" if hair_ratio<0.36 else "behaart"
42
- ratio=w/h
43
- area=w*h
44
- if area<18000: form_desc="Innie"
45
- elif area>65000 and ratio>1.45: form_desc="Outie (Puff)"
46
- elif ratio>1.45: form_desc="Outie"
47
- else: form_desc="Innie/Outie"
48
- size="winzig" if area<18000 else "klein" if area<38000 else "mittel" if area<65000 else "groß"
49
- w_cm=round(w/PIXELS_PER_CM_ESTIMATE,1)
50
- h_cm=round(h/PIXELS_PER_CM_ESTIMATE,1)
 
 
 
 
 
51
  return f"Vagina: {form_desc}, {size}, {shaved}, {w_cm}x{h_cm}cm"
52
 
 
53
  def process_image(image):
54
  try:
55
  original_pil = Image.fromarray(image).convert("RGB") if isinstance(image,np.ndarray) else image.convert("RGB")
@@ -57,31 +71,38 @@ def process_image(image):
57
  detections = detector.detect(np.array(detection_pil))
58
  draw = ImageDraw.Draw(original_pil)
59
  font = ImageFont.load_default()
60
- results_text=[]
 
61
  for det in detections:
62
- label=det["class"]
63
- score=det.get("score",0)
64
- if score<MIN_CONFIDENCE: continue
65
- if label not in ["FEMALE_BREAST_EXPOSED","FEMALE_GENITALIA_EXPOSED"]: continue
66
- x,y,w,h=[int(v*scale) for v in det["box"]]
67
- crop_pil=original_pil.crop((x,y,x+w,y+h))
 
 
68
  if label=="FEMALE_BREAST_EXPOSED":
69
- desc=describe_breast_precise(crop_pil)
70
- color=(255,46,130)
71
  else:
72
- desc=describe_vagina_precise(crop_pil)
73
- color=(138,43,226)
74
  draw.rectangle([x,y,x+w,y+h],outline=color,width=4)
75
- text_pos=(x,y-15 if y>15 else y+h)
76
  draw.text(text_pos,desc,fill=color,font=font)
77
  results_text.append(desc)
 
78
  if not results_text:
79
  draw.text((10,10),"Keine relevanten Bereiche erkannt.",fill=(255,0,0),font=font)
 
80
  return np.array(original_pil)
 
81
  except Exception as e:
82
  print(f"Fehler: {e}")
83
  return None
84
 
 
85
  css = """
86
  body { background: #0f0f1a; color: #e0e0ff; }
87
  .gradio-container { max-width: 900px !important; margin: auto; }
 
4
  import cv2
5
  from nudenet import NudeDetector
6
 
7
+ # --- Konstanten ---
8
  DETECTION_MAX_DIM = 768
9
  PIXELS_PER_CM_ESTIMATE = 15
10
  MIN_CONFIDENCE = 0.45
11
 
12
+ # --- NudeNet Detector ---
13
  detector = NudeDetector(inference_resolution=640)
14
 
15
+ # --- Hilfsfunktionen ---
16
  def resize_for_detection(img_pil, max_dim):
17
  if max(img_pil.width, img_pil.height) <= max_dim:
18
  return img_pil, 1.0
 
24
 
25
  def describe_breast_precise(crop_pil):
26
  w,h = crop_pil.size
27
+ if w*h == 0:
28
+ return "Fehler: leeres Crop"
29
  gray = cv2.cvtColor(np.array(crop_pil), cv2.COLOR_RGB2GRAY)
30
+ _, thresh = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
31
+ contours,_ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
32
+ nipple_detected = any(
33
+ 40 < cv2.contourArea(c) < (w*h/4) and (p:=cv2.arcLength(c,True))>0 and
34
+ (4*np.pi*cv2.contourArea(c)/(p*p))>0.55
35
+ for c in contours
36
+ )
37
+ ratio = w/h
38
+ shape = "Breit" if ratio>1.15 else "Hoch" if ratio<0.85 else "Rund"
39
+ size = "klein" if w*h<28000 else "mittel" if w*h<75000 else "groß" if w*h<140000 else "sehr groß"
40
+ w_cm = round(w/PIXELS_PER_CM_ESTIMATE,1)
41
+ h_cm = round(h/PIXELS_PER_CM_ESTIMATE,1)
42
  return f"Brust: {shape}, {size}, Nippel: {'Ja' if nipple_detected else 'Nein'}, {w_cm}x{h_cm}cm"
43
 
44
  def describe_vagina_precise(crop_pil):
45
+ w,h = crop_pil.size
46
+ if w*h == 0:
47
+ return "Fehler: leeres Crop"
48
+ gray = cv2.cvtColor(np.array(crop_pil), cv2.COLOR_RGB2GRAY)
49
+ hair_ratio = np.sum(cv2.inRange(gray, 35, 145) > 0) / (w*h) # <--- korrigiert
50
+ shaved = "rasiert" if hair_ratio < 0.04 else "minimal" if hair_ratio < 0.13 else "Brazilian" if hair_ratio < 0.36 else "behaart"
51
+ ratio = w/h
52
+ area = w*h
53
+ if area < 18000:
54
+ form_desc = "Innie"
55
+ elif area > 65000 and ratio > 1.45:
56
+ form_desc = "Outie (Puff)"
57
+ elif ratio > 1.45:
58
+ form_desc = "Outie"
59
+ else:
60
+ form_desc = "Innie/Outie"
61
+ size = "winzig" if area<18000 else "klein" if area<38000 else "mittel" if area<65000 else "groß"
62
+ w_cm = round(w/PIXELS_PER_CM_ESTIMATE,1)
63
+ h_cm = round(h/PIXELS_PER_CM_ESTIMATE,1)
64
  return f"Vagina: {form_desc}, {size}, {shaved}, {w_cm}x{h_cm}cm"
65
 
66
+ # --- Bildverarbeitung ---
67
  def process_image(image):
68
  try:
69
  original_pil = Image.fromarray(image).convert("RGB") if isinstance(image,np.ndarray) else image.convert("RGB")
 
71
  detections = detector.detect(np.array(detection_pil))
72
  draw = ImageDraw.Draw(original_pil)
73
  font = ImageFont.load_default()
74
+ results_text = []
75
+
76
  for det in detections:
77
+ label = det["class"]
78
+ score = det.get("score",0)
79
+ if score < MIN_CONFIDENCE:
80
+ continue
81
+ if label not in ["FEMALE_BREAST_EXPOSED","FEMALE_GENITALIA_EXPOSED"]:
82
+ continue
83
+ x,y,w,h = [int(v*scale) for v in det["box"]]
84
+ crop_pil = original_pil.crop((x,y,x+w,y+h))
85
  if label=="FEMALE_BREAST_EXPOSED":
86
+ desc = describe_breast_precise(crop_pil)
87
+ color = (255,46,130)
88
  else:
89
+ desc = describe_vagina_precise(crop_pil)
90
+ color = (138,43,226)
91
  draw.rectangle([x,y,x+w,y+h],outline=color,width=4)
92
+ text_pos = (x,y-15 if y>15 else y+h)
93
  draw.text(text_pos,desc,fill=color,font=font)
94
  results_text.append(desc)
95
+
96
  if not results_text:
97
  draw.text((10,10),"Keine relevanten Bereiche erkannt.",fill=(255,0,0),font=font)
98
+
99
  return np.array(original_pil)
100
+
101
  except Exception as e:
102
  print(f"Fehler: {e}")
103
  return None
104
 
105
+ # --- Gradio App ---
106
  css = """
107
  body { background: #0f0f1a; color: #e0e0ff; }
108
  .gradio-container { max-width: 900px !important; margin: auto; }