shukdevdatta123 commited on
Commit
1445dfa
·
verified ·
1 Parent(s): a4dea84

Upload 3 files

Browse files
app.py ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## original color nose thicken
2
+ import cv2
3
+ import numpy as np
4
+ import streamlit as st
5
+ from PIL import Image
6
+ import os
7
+ import zipfile
8
+
9
+ def detect_nose_and_realistically_thicken(image):
10
+ # Load pre-trained classifiers for face and nose detection
11
+ face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
12
+ nose_cascade = cv2.CascadeClassifier('haarcascade_mcs_nose.xml')
13
+
14
+ # Convert the image to grayscale for better detection
15
+ gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
16
+
17
+ # Detect faces in the image
18
+ faces = face_cascade.detectMultiScale(gray, 1.3, 5)
19
+
20
+ for (x, y, w, h) in faces:
21
+ # For each face, detect the nose
22
+ face_region = gray[y:y+h, x:x+w]
23
+ noses = nose_cascade.detectMultiScale(face_region, 1.3, 5)
24
+
25
+ for (nx, ny, nw, nh) in noses:
26
+ # Get the nose region from the original image
27
+ nose_region = image[y+ny:y+ny+nh, x+nx:x+nx+nw]
28
+
29
+ # Thicken the nose by increasing its width symmetrically
30
+ thicken_factor = 1.5 # Adjust this value to control thickness
31
+ new_width = int(nw * thicken_factor)
32
+
33
+ # Create a thickened nose by resizing
34
+ thickened_nose = cv2.resize(nose_region, (new_width, nh), interpolation=cv2.INTER_LINEAR)
35
+
36
+ # Feather the edges of the thickened nose to blend with the face
37
+ mask = np.zeros_like(thickened_nose, dtype=np.float32)
38
+ center_x = new_width // 2
39
+ cv2.circle(mask, (center_x, nh // 2), int(min(new_width, nh) * 0.6), (1, 1, 1), -1, cv2.LINE_AA)
40
+ mask = cv2.GaussianBlur(mask, (21, 21), 10) # Feathering
41
+
42
+ # Calculate the offsets to center the thickened nose
43
+ left_offset = (new_width - nw) // 2
44
+
45
+ # Ensure not to go out of bounds
46
+ start_x = max(x + nx - left_offset, 0)
47
+ end_x = min(start_x + new_width, image.shape[1])
48
+ start_y = y + ny
49
+ end_y = start_y + nh
50
+
51
+ # Blend the thickened nose smoothly into the face
52
+ alpha = 0.7 # Controls transparency of thickened nose
53
+
54
+ # Blending with the feathered mask to smooth edges
55
+ image[start_y:end_y, start_x:end_x] = (
56
+ image[start_y:end_y, start_x:end_x].astype(np.float32) * (1 - mask) +
57
+ thickened_nose[:, :end_x - start_x].astype(np.float32) * mask
58
+ ).astype(np.uint8)
59
+
60
+ return image
61
+
62
+ def main():
63
+ st.title("Nose Thickening App")
64
+
65
+ # Modal Popup for Instructions
66
+ with st.expander("Application of OpenCV for Nose thickening", expanded=False):
67
+ st.write(
68
+ "The application of OpenCV for nose thickening showcases the power of computer vision in image processing. By leveraging pre-trained classifiers like Haar cascades, the program effectively detects facial features, particularly the nose, within images. The algorithm then applies a thicken effect by resizing the detected nose region, ensuring a realistic blend with the surrounding facial features. This involves techniques such as Gaussian blurring to feather the edges of the modified area, resulting in a seamless transition. The integration with Streamlit allows users to easily upload images, apply the effect, and download the modified results, making sophisticated image manipulation accessible to a broader audience without requiring extensive programming knowledge. This demonstrates OpenCV's versatility in creative applications, from enhancing personal photos to providing entertainment or social media enhancements."
69
+ )
70
+
71
+ # Instructions sidebar
72
+ with st.sidebar:
73
+ st.header("Instructions")
74
+ st.write(
75
+ "1) If you choose only one image to upload, the results will be shown on display, and you can click the 'Download Processed Images' button to download the processed images in zip format.\n"
76
+ "2) If you choose more than one image, it will not display any image as results; instead, it will directly show you the 'Download Processed Images' button, and you can click on it to download the processed images in zip format."
77
+ )
78
+
79
+ uploaded_files = st.file_uploader("Upload Images", type=["jpg", "jpeg", "png"], accept_multiple_files=True)
80
+
81
+ if st.button("Thicken Nose"):
82
+ if len(uploaded_files) == 1:
83
+ image = Image.open(uploaded_files[0]).convert("RGB")
84
+ image_np = np.array(image)
85
+
86
+ # Apply the nose detection and thickening effect
87
+ output_image = detect_nose_and_realistically_thicken(image_np)
88
+
89
+ # Display the output image
90
+ st.image(output_image, caption="Output Image", use_column_width=True)
91
+
92
+ # Convert the output image to RGB for saving
93
+ output_image_rgb = cv2.cvtColor(output_image, cv2.COLOR_BGR2RGB)
94
+
95
+ # Save the output image in the correct color format
96
+ output_path = 'output_image.jpg'
97
+ cv2.imwrite(output_path, output_image_rgb) # Save as RGB
98
+
99
+ st.success("Nose thickening applied! You can download the image below.")
100
+ st.download_button("Download Image", data=open(output_path, "rb").read(), file_name='output_image.jpg', mime='image/jpeg')
101
+
102
+ elif len(uploaded_files) > 1:
103
+ st.warning("Multiple images uploaded. No output will be displayed. Please download the images directly.")
104
+
105
+ # Save all images in the output directory
106
+ output_dir = 'output_images'
107
+ os.makedirs(output_dir, exist_ok=True)
108
+
109
+ for i, uploaded_file in enumerate(uploaded_files):
110
+ image = Image.open(uploaded_file).convert("RGB")
111
+ image_np = np.array(image)
112
+ output_image = detect_nose_and_realistically_thicken(image_np)
113
+
114
+ # Convert the output image to RGB for saving
115
+ output_image_rgb = cv2.cvtColor(output_image, cv2.COLOR_BGR2RGB)
116
+
117
+ output_path = os.path.join(output_dir, f'output_image_{i + 1}.jpg')
118
+ cv2.imwrite(output_path, output_image_rgb) # Save as RGB
119
+
120
+ st.success("Nose thickening applied to all images! You can download them below.")
121
+
122
+ # Zip the images for download
123
+ zip_file_path = 'output_images.zip'
124
+ with zipfile.ZipFile(zip_file_path, 'w') as zipf:
125
+ for i in range(len(uploaded_files)):
126
+ zipf.write(os.path.join(output_dir, f'output_image_{i + 1}.jpg'), arcname=f'output_image_{i + 1}.jpg')
127
+
128
+ st.download_button("Download Images", data=open(zip_file_path, "rb").read(), file_name='output_images.zip', mime='application/zip')
129
+
130
+ if __name__ == "__main__":
131
+ main()
haarcascade_frontalface_default.xml ADDED
The diff for this file is too large to render. See raw diff
 
haarcascade_mcs_nose.xml ADDED
The diff for this file is too large to render. See raw diff