Jacob Logas commited on
Commit
9d68bbe
·
unverified ·
1 Parent(s): 8fd4e0e

Update space for app

Browse files
Files changed (6) hide show
  1. .pre-commit-config.yaml +16 -0
  2. Dockerfile +0 -24
  3. README.md +0 -12
  4. app.py +105 -99
  5. requirements-dev.txt +2 -0
  6. requirements.txt +4 -71
.pre-commit-config.yaml ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ repos:
2
+ - repo: https://github.com/pre-commit/pre-commit-hooks
3
+ rev: v2.3.0
4
+ hooks:
5
+ - id: check-yaml
6
+ - id: end-of-file-fixer
7
+ - id: trailing-whitespace
8
+ - repo: https://github.com/astral-sh/ruff-pre-commit
9
+ # Ruff version.
10
+ rev: v0.5.2
11
+ hooks:
12
+ # Run the linter.
13
+ - id: ruff
14
+ args: [ --fix ]
15
+ # Run the formatter.
16
+ - id: ruff-format
Dockerfile DELETED
@@ -1,24 +0,0 @@
1
- # Stage 1: Build Dependencies
2
- FROM python:slim as builder
3
-
4
- RUN apt update && \
5
- apt install --no-install-recommends -y build-essential gcc
6
-
7
- COPY requirements.txt /requirements.txt
8
-
9
- RUN pip install --upgrade pip && \
10
- pip install --quiet --no-cache-dir --no-warn-script-location --user -r requirements.txt
11
-
12
- # Stage 2: Runtime
13
- FROM python:slim
14
- ENV GRADIO_SERVER_NAME=0.0.0.0
15
-
16
- RUN rm -rf /var/lib/apt/lists/*
17
-
18
- COPY --from=builder /root/.local/lib/python3.11/site-packages /root/.local/lib/python3.11/site-packages
19
-
20
- COPY raccoon_emoji.png raccoon_emoji.png
21
- COPY app.py app.py
22
-
23
- CMD [ "python" , "-u", "app.py" ]
24
- EXPOSE 7860
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
README.md CHANGED
@@ -1,12 +0,0 @@
1
- ---
2
- title: Fawkes
3
- emoji: 🌖
4
- colorFrom: red
5
- colorTo: purple
6
- sdk: gradio
7
- sdk_version: 3.0.20
8
- app_file: app.py
9
- pinned: false
10
- license: gpl-3.0
11
- python_version: 3.8.13
12
- ---
 
 
 
 
 
 
 
 
 
 
 
 
 
app.py CHANGED
@@ -5,111 +5,117 @@ from mtcnn_cv2 import MTCNN
5
 
6
  detector = MTCNN()
7
 
 
8
  def predict(img, selection):
9
- faces = detector.detect_faces(img)
10
-
11
- privacy_fn = None
12
- if(selection == "Low"):
13
- opts = (anonymize_face_pixelate, 20)
14
- elif(selection == "Medium"):
15
- opts = (anonymize_face_pixelate, 10)
16
- elif(selection == "High"):
17
- opts = (anonymize_face_pixelate, 4)
18
- elif(selection == "Emoji"):
19
- opts = (anonymize_face_emoji, "smiley")
20
- else:
21
- raise Exception("I don't know how you did it but you chose something else.")
22
-
23
- if len(faces) > 0:
24
- for features in faces:
25
- img = opts[0](img, features, opts[1])
26
- else:
27
- raise Exception("No faces detected");
28
- return img
29
 
30
  def anonymize_face_pixelate(image, features, blocks=10):
31
- bb = features['box']
32
- face_crop = image[bb[1]:bb[1]+bb[3], bb[0]:bb[0]+bb[2]]
33
- # Divide the input image into NxN blocks
34
- (h,w) = face_crop.shape[:2]
35
- xSteps = np.linspace(0, w, blocks + 1, dtype="int")
36
- ySteps = np.linspace(0, h, blocks + 1, dtype="int")
37
-
38
- # loop over the blocks in both x and y direction
39
- for i in range(1, len(ySteps)):
40
- for j in range(1, len(xSteps)):
41
- # compute starting and ending (x, y)-coordinates
42
- # for current block
43
- startX = xSteps[j - 1]
44
- startY = ySteps[i - 1]
45
- endX = xSteps[j]
46
- endY = ySteps[i]
47
-
48
- # Extract the ROI using NumPy array slicing, compute the
49
- # mean of the ROI, and then draw a rectangle with the
50
- # mean RGB values over the ROI in teh original image
51
- roi = face_crop[startY:endY, startX:endX]
52
- (B, G, R) = [int(x) for x in cv2.mean(roi)[:3]]
53
- cv2.rectangle(face_crop, (startX, startY), (endX, endY),
54
- (B,G,R), -1)
55
-
56
- image[bb[1]:bb[1]+bb[3], bb[0]:bb[0]+bb[2]] = face_crop
57
- return image
58
 
59
  def anonymize_face_emoji(img, features, name="smiley"):
60
- bb = features['box']
61
- (y, x) = (bb[1] + int(bb[3]/2), bb[0] + int(bb[2]/2))
62
- (h,w) = (bb[3], bb[2])
63
- # Get emoji with transparency
64
- mask = cv2.imread('raccoon_emoji.png', -1)
65
 
66
- mshape = max(h,w)
67
- offset = int(mshape/2)
 
 
68
 
69
- return overlay_transparent(img, mask,
70
- x - offset,
71
- y - offset,
72
- (mshape, mshape))
73
 
74
  def overlay_transparent(background_img, img_to_overlay_t, x, y, overlay_size=None):
75
- """
76
- @brief Overlays a transparant PNG onto another image using CV2
77
-
78
- @param background_img The background image
79
- @param img_to_overlay_t The transparent image to overlay (has alpha channel)
80
- @param x x location to place the top-left corner of our overlay
81
- @param y y location to place the top-left corner of our overlay
82
- @param overlay_size The size to scale our overlay to (tuple), no scaling if None
83
-
84
- @return Background image with overlay on top
85
- """
86
-
87
- bg_img = background_img.copy()
88
-
89
- if overlay_size is not None:
90
- img_to_overlay_t = cv2.resize(img_to_overlay_t.copy(), overlay_size)
91
-
92
- # Extract the alpha mask of the RGBA image, convert to RGB
93
- b,g,r,a = cv2.split(img_to_overlay_t)
94
- overlay_color = cv2.merge((b,g,r))
95
-
96
- # Apply some simple filtering to remove edge noise
97
- mask = cv2.medianBlur(a,5)
98
-
99
- h, w, _ = overlay_color.shape
100
- roi = bg_img[y:y+h, x:x+w]
101
-
102
- # Black-out the area behind the logo in our original ROI
103
- img1_bg = cv2.bitwise_and(roi.copy(),roi.copy(),mask = cv2.bitwise_not(mask))
104
-
105
- # Mask out the logo from the logo image.
106
- img2_fg = cv2.bitwise_and(overlay_color,overlay_color,mask = mask)
107
-
108
- # Update the original image with our new ROI
109
- bg_img[y:y+h, x:x+w] = cv2.add(img1_bg, img2_fg)
110
-
111
- return bg_img
112
-
113
- gr.Interface(fn=predict,
114
- inputs=[gr.components.Image(type='numpy'), gr.components.Radio(["Low", "Medium", "High", "Emoji"], value="Medium")],
115
- outputs=gr.components.Image(type="pil"), allow_flagging="never").launch(show_error=True, quiet=False)
 
 
 
 
 
 
 
 
5
 
6
  detector = MTCNN()
7
 
8
+
9
  def predict(img, selection):
10
+ faces = detector.detect_faces(img)
11
+
12
+ if selection == "Low":
13
+ opts = (anonymize_face_pixelate, 20)
14
+ elif selection == "Medium":
15
+ opts = (anonymize_face_pixelate, 10)
16
+ elif selection == "High":
17
+ opts = (anonymize_face_pixelate, 4)
18
+ elif selection == "Emoji":
19
+ opts = (anonymize_face_emoji, "smiley")
20
+ else:
21
+ raise Exception("I don't know how you did it but you chose something else.")
22
+
23
+ if len(faces) > 0:
24
+ for features in faces:
25
+ img = opts[0](img, features, opts[1])
26
+ else:
27
+ raise Exception("No faces detected")
28
+ return img
29
+
30
 
31
  def anonymize_face_pixelate(image, features, blocks=10):
32
+ bb = features["box"]
33
+ face_crop = image[bb[1] : bb[1] + bb[3], bb[0] : bb[0] + bb[2]]
34
+ # Divide the input image into NxN blocks
35
+ (h, w) = face_crop.shape[:2]
36
+ xSteps = np.linspace(0, w, blocks + 1, dtype="int")
37
+ ySteps = np.linspace(0, h, blocks + 1, dtype="int")
38
+
39
+ # loop over the blocks in both x and y direction
40
+ for i in range(1, len(ySteps)):
41
+ for j in range(1, len(xSteps)):
42
+ # compute starting and ending (x, y)-coordinates
43
+ # for current block
44
+ startX = xSteps[j - 1]
45
+ startY = ySteps[i - 1]
46
+ endX = xSteps[j]
47
+ endY = ySteps[i]
48
+
49
+ # Extract the ROI using NumPy array slicing, compute the
50
+ # mean of the ROI, and then draw a rectangle with the
51
+ # mean RGB values over the ROI in teh original image
52
+ roi = face_crop[startY:endY, startX:endX]
53
+ (B, G, R) = [int(x) for x in cv2.mean(roi)[:3]]
54
+ cv2.rectangle(face_crop, (startX, startY), (endX, endY), (B, G, R), -1)
55
+
56
+ image[bb[1] : bb[1] + bb[3], bb[0] : bb[0] + bb[2]] = face_crop
57
+ return image
58
+
59
 
60
  def anonymize_face_emoji(img, features, name="smiley"):
61
+ bb = features["box"]
62
+ (y, x) = (bb[1] + int(bb[3] / 2), bb[0] + int(bb[2] / 2))
63
+ (h, w) = (bb[3], bb[2])
64
+ # Get emoji with transparency
65
+ mask = cv2.imread("raccoon_emoji.png", -1)
66
 
67
+ mshape = max(h, w)
68
+ offset = int(mshape / 2)
69
+
70
+ return overlay_transparent(img, mask, x - offset, y - offset, (mshape, mshape))
71
 
 
 
 
 
72
 
73
  def overlay_transparent(background_img, img_to_overlay_t, x, y, overlay_size=None):
74
+ """
75
+ @brief Overlays a transparant PNG onto another image using CV2
76
+
77
+ @param background_img The background image
78
+ @param img_to_overlay_t The transparent image to overlay (has alpha channel)
79
+ @param x x location to place the top-left corner of our overlay
80
+ @param y y location to place the top-left corner of our overlay
81
+ @param overlay_size The size to scale our overlay to (tuple), no scaling if None
82
+
83
+ @return Background image with overlay on top
84
+ """
85
+
86
+ bg_img = background_img.copy()
87
+
88
+ if overlay_size is not None:
89
+ img_to_overlay_t = cv2.resize(img_to_overlay_t.copy(), overlay_size)
90
+
91
+ # Extract the alpha mask of the RGBA image, convert to RGB
92
+ b, g, r, a = cv2.split(img_to_overlay_t)
93
+ overlay_color = cv2.merge((b, g, r))
94
+
95
+ # Apply some simple filtering to remove edge noise
96
+ mask = cv2.medianBlur(a, 5)
97
+
98
+ h, w, _ = overlay_color.shape
99
+ roi = bg_img[y : y + h, x : x + w]
100
+
101
+ # Black-out the area behind the logo in our original ROI
102
+ img1_bg = cv2.bitwise_and(roi.copy(), roi.copy(), mask=cv2.bitwise_not(mask))
103
+
104
+ # Mask out the logo from the logo image.
105
+ img2_fg = cv2.bitwise_and(overlay_color, overlay_color, mask=mask)
106
+
107
+ # Update the original image with our new ROI
108
+ bg_img[y : y + h, x : x + w] = cv2.add(img1_bg, img2_fg)
109
+
110
+ return bg_img
111
+
112
+
113
+ gr.Interface(
114
+ fn=predict,
115
+ inputs=[
116
+ gr.components.Image(type="numpy"),
117
+ gr.components.Radio(["Low", "Medium", "High", "Emoji"], value="Medium"),
118
+ ],
119
+ outputs=gr.components.Image(type="pil"),
120
+ allow_flagging="never",
121
+ ).launch(show_error=True, quiet=False)
requirements-dev.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ ruff
2
+ pre-commit
requirements.txt CHANGED
@@ -1,71 +1,4 @@
1
- aiofiles==23.1.0
2
- aiohttp==3.8.3
3
- aiosignal==1.3.1
4
- altair==4.2.2
5
- anyio==3.6.2
6
- async-timeout==4.0.2
7
- attrs==22.1.0
8
- bcrypt==4.0.1
9
- certifi==2022.12.7
10
- cffi==1.15.1
11
- charset-normalizer==2.1.1
12
- click==8.1.3
13
- contourpy==1.0.6
14
- cryptography==39.0.2
15
- cycler==0.11.0
16
- emoji==2.2.0
17
- entrypoints==0.4
18
- fastapi==0.86.0
19
- ffmpy==0.3.0
20
- filelock==3.9.1
21
- fonttools==4.38.0
22
- frozenlist==1.3.3
23
- fsspec==2022.10.0
24
- gradio==3.21.0
25
- h11==0.12.0
26
- httpcore==0.15.0
27
- httpx==0.23.0
28
- huggingface-hub==0.13.2
29
- idna==3.4
30
- Jinja2==3.1.2
31
- jsonschema==4.17.3
32
- kiwisolver==1.4.4
33
- linkify-it-py==1.0.3
34
- markdown-it-py==2.2.0
35
- MarkupSafe==2.1.1
36
- matplotlib==3.6.2
37
- mdit-py-plugins==0.3.1
38
- mdurl==0.1.2
39
- mtcnn-opencv==1.0.2
40
- multidict==6.0.2
41
- numpy==1.23.4
42
- opencv-contrib-python-headless==4.6.0.66
43
- orjson==3.8.1
44
- packaging==21.3
45
- pandas==1.5.1
46
- paramiko==2.12.0
47
- Pillow==9.3.0
48
- pycparser==2.21
49
- pycryptodome==3.15.0
50
- pydantic==1.10.2
51
- pydub==0.25.1
52
- PyNaCl==1.5.0
53
- pyparsing==3.0.9
54
- pyrsistent==0.19.3
55
- python-dateutil==2.8.2
56
- python-multipart==0.0.5
57
- pytz==2022.6
58
- PyYAML==6.0
59
- requests==2.28.1
60
- rfc3986==1.5.0
61
- six==1.16.0
62
- sniffio==1.3.0
63
- starlette==0.20.4
64
- toolz==0.12.0
65
- tqdm==4.65.0
66
- typing_extensions==4.4.0
67
- uc-micro-py==1.0.1
68
- urllib3==1.26.12
69
- uvicorn==0.19.0
70
- websockets==10.4
71
- yarl==1.8.1
 
1
+ gradio>=4.38.1
2
+ numpy>=2.0.0
3
+ mtcnn-opencv>=1.0.2
4
+ opencv-python>=4.10.0.84