dhawalbanker commited on
Commit
56391c7
·
1 Parent(s): 30012f3

app restoration

Browse files
Files changed (2) hide show
  1. app.py +151 -224
  2. requirements.txt +1 -2
app.py CHANGED
@@ -1,227 +1,154 @@
 
 
 
 
 
 
 
 
1
  import cv2
2
- import mediapipe as mp
3
- import random
4
- import time
5
- import datetime # Import datetime for timestamping video files
6
-
7
- # Initialize Mediapipe Pose
8
- mp_pose = mp.solutions.pose
9
- pose = mp_pose.Pose()
10
- mp_drawing = mp.solutions.drawing_utils
11
-
12
- # Initialize the video capture
13
- cap = cv2.VideoCapture(0) # Use 0 for the default camera or provide a video file path
14
-
15
- # Set the resolution to 720p
16
- cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280) # Width for 720p
17
- cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 960) # Height for a resolution higher than 720p
18
-
19
- # Define actions and their corresponding scores
20
- actions = ['Raise Right Hand', 'Raise Left Hand', 'Wave Right Hand', 'Wave Left Hand', 'Clap', 'Touch shoulder Right', 'Touch shoulder Left', 'Tilt Head Right', 'Tilt Head Left', 'Spread Hands', 'Spin'] # Updated action names
21
- # actions = ['Spin']#, 'Jump'] # Updated action names
22
- current_action = random.choice(actions)
23
- score = 0
24
- last_action_time = time.time()
25
- action_duration = 10 # seconds
26
- pause_duration = .5 # Define the pause duration
27
-
28
- # Add a boolean variable to check if pose estimation is enabled
29
- pose_estimation_enabled = True # Set to True to enable pose estimation
30
- pose_estimation_paused_time = None # Variable to track when pose estimation was paused
31
-
32
- # Initialize video writer
33
- video_writer = None # Variable to hold the video writer
34
- is_recording = False # Variable to track recording state
35
-
36
- # Add a variable to control pose drawing
37
- pose_drawing_enabled = False # Add a variable to control pose drawing
38
-
39
-
40
- def ChangeAction():
41
- global current_action, last_action_time, score, pose_estimation_enabled, pose_estimation_paused_time # Declare global variables
42
- new_action = random.choice(actions) # Select a new action
43
- # while new_action == current_action: # Ensure the new action is different from the current one
44
- # new_action = random.choice(actions)
45
- current_action = new_action # Update current action
46
- print(f"New action: {current_action}") # Update text for new pose
47
- last_action_time = time.time()
48
- pose.reset() # Reset pose values (assuming a reset method exists)
49
-
50
- pose_estimation_enabled = False # Disable pose estimation
51
- pose_estimation_paused_time = time.time() # Update the pause time
52
- while True:
53
- ret, frame = cap.read()
54
- if not ret:
55
- break
56
-
57
- # Check if pose estimation was paused for more than pause_duration
58
- if pose_estimation_paused_time and time.time() - pose_estimation_paused_time > pause_duration:
59
- pose_estimation_enabled = True # Re-enable pose estimation
60
- pose_estimation_paused_time = None # Reset the pause time
61
-
62
- action_detected = False # Replace with actual detection logic
63
- # Process the frame with Mediapipe Pose only if enabled
64
- if pose_estimation_enabled:
65
- frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
66
- results = pose.process(frame_rgb)
67
-
68
- # Draw pose landmarks if enabled
69
- if pose_drawing_enabled and results.pose_landmarks: # Check if drawing is enabled
70
- mp_drawing.draw_landmarks(frame, results.pose_landmarks, mp_pose.POSE_CONNECTIONS)
71
-
72
- if results.pose_landmarks: # Check if pose landmarks are detected
73
- # Get the coordinates of the landmarks
74
- landmarks = results.pose_landmarks.landmark
75
-
76
- # Define required variables for actions
77
- right_shoulder = landmarks[mp_pose.PoseLandmark.RIGHT_SHOULDER.value]
78
- right_wrist = landmarks[mp_pose.PoseLandmark.RIGHT_WRIST.value]
79
- left_shoulder = landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value]
80
- left_wrist = landmarks[mp_pose.PoseLandmark.LEFT_WRIST.value]
81
- right_hip = landmarks[mp_pose.PoseLandmark.RIGHT_HIP.value]
82
- left_hip = landmarks[mp_pose.PoseLandmark.LEFT_HIP.value]
83
- right_pinky = landmarks[mp_pose.PoseLandmark.RIGHT_PINKY.value]
84
- right_index = landmarks[mp_pose.PoseLandmark.RIGHT_INDEX.value]
85
- right_thumb = landmarks[mp_pose.PoseLandmark.RIGHT_THUMB.value]
86
- left_pinky = landmarks[mp_pose.PoseLandmark.LEFT_PINKY.value]
87
- left_index = landmarks[mp_pose.PoseLandmark.LEFT_INDEX.value]
88
- left_thumb = landmarks[mp_pose.PoseLandmark.LEFT_THUMB.value]
89
- nose = landmarks[mp_pose.PoseLandmark.NOSE.value]
90
- near_shoulder_distance = 0.1 # Define the near shoulder distance
91
-
92
- # Check for each action
93
- if current_action == 'Raise Right Hand' and right_wrist.y < nose.y: # Condition for raising right hand
94
- action_detected = True
95
- print("Raise Right Hand")
96
- elif current_action == 'Raise Left Hand' and left_wrist.y < nose.y: # Condition for raising left hand
97
- action_detected = True
98
- print("Raise Left Hand")
99
- elif current_action == 'Wave Right Hand' and (right_wrist.x > right_shoulder.x and right_wrist.y < nose.y): # Condition for waving, adjusted to be further from shoulder
100
- action_detected = True
101
- print("Wave Right Hand")
102
- elif current_action == 'Wave Left Hand' and (left_wrist.x < left_shoulder.x and left_wrist.y < nose.y): # Condition for waving, adjusted to be further from shoulder
103
- action_detected = True
104
- print("Wave Left Hand")
105
- elif current_action == 'Clap' and (abs(right_wrist.x - left_wrist.x) < 0.1 and right_wrist.y < left_wrist.y and left_wrist.y < right_shoulder.y): # Condition for clapping based on proximity
106
- action_detected = True
107
- print("Clap")
108
- elif current_action == 'Touch shoulder Right' and (
109
- (((right_pinky.x - right_shoulder.x) ** 2 + (right_pinky.y - right_shoulder.y) ** 2) ** 0.5 < near_shoulder_distance) or
110
- (((right_index.x - right_shoulder.x) ** 2 + (right_index.y - right_shoulder.y) ** 2) ** 0.5 < near_shoulder_distance) or
111
- (((right_thumb.x - right_shoulder.x) ** 2 + (right_thumb.y - right_shoulder.y) ** 2) ** 0.5 < near_shoulder_distance)): # Condition for touching shoulder
112
- action_detected = True
113
- print("Touch shoulder Right")
114
- elif current_action == 'Touch shoulder Left' and (
115
- (((left_pinky.x - left_shoulder.x) ** 2 + (left_pinky.y - left_shoulder.y) ** 2) ** 0.5 < near_shoulder_distance) or
116
- (((left_index.x - left_shoulder.x) ** 2 + (left_index.y - left_shoulder.y) ** 2) ** 0.5 < near_shoulder_distance) or
117
- (((left_thumb.x - left_shoulder.x) ** 2 + (left_thumb.y - left_shoulder.y) ** 2) ** 0.5 < near_shoulder_distance)): # Condition for touching shoulder
118
- action_detected = True
119
- print("Touch shoulder Left")
120
- elif current_action == 'Tilt Head Right':
121
- is_nose_near_right_shoulder = (abs(nose.x - right_shoulder.x) < near_shoulder_distance) and (abs(nose.y - right_shoulder.y) < near_shoulder_distance)
122
- is_nose_below_left_shoulder = nose.y > left_shoulder.y
123
-
124
- if is_nose_near_right_shoulder or is_nose_below_left_shoulder:
125
- action_detected = True
126
- print("Tilt Head Right")
127
-
128
- elif current_action == 'Tilt Head Left':
129
- is_nose_near_left_shoulder = (abs(nose.x - left_shoulder.x) < near_shoulder_distance) and (abs(nose.y - left_shoulder.y) < near_shoulder_distance)
130
- is_nose_above_right_shoulder = nose.y > right_shoulder.y
131
-
132
- if is_nose_near_left_shoulder or is_nose_above_right_shoulder:
133
- action_detected = True
134
- print("Tilt Head Left")
135
- elif current_action == 'Spread Hands':
136
- is_right_hand_spread = right_wrist.x < right_shoulder.x and abs(right_wrist.y - right_shoulder.y) < near_shoulder_distance
137
- is_left_hand_spread = left_wrist.x > left_shoulder.x and abs(left_wrist.y - left_shoulder.y) < near_shoulder_distance
138
-
139
- if is_right_hand_spread and is_left_hand_spread:
140
- action_detected = True
141
- print("Spread Hands")
142
- elif current_action == 'Spin' and right_shoulder.x > left_shoulder.x: # Condition for spinning
143
- action_detected = True
144
- print("Spin")
145
- elif current_action == 'Jump' and (right_hip.y < left_hip.y): # Condition for jumping
146
- action_detected = True
147
- print("Jump")
148
-
149
- # Update action based on detection
150
- if action_detected:
151
- score += 1
152
- text_to_display = f'{current_action} success!'
153
- ChangeAction() # Call the new function
154
  else:
155
- remaining_time = action_duration - (time.time() - last_action_time)
156
- if remaining_time <= 0:
157
- text_to_display = f'{current_action} missed!'
158
- ChangeAction() # Call the new function
159
- else:
160
- text_to_display = f'Time left to {current_action}: {int(remaining_time)}'
161
-
162
- # # Get the size of the text to display the action result
163
- # text_size = cv2.getTextSize(text_to_display, cv2.FONT_HERSHEY_SIMPLEX, 1, 2)[0]
164
- # # Calculate the x position to center the text horizontally
165
- # text_x = (frame.shape[1] - text_size[0]) // 2
166
- # Put the text on the frame at the bottom center
167
- # cv2.putText(frame, text_to_display,
168
- # (text_x, frame.shape[0] - 30), # Centered at the bottom based on text width
169
- # cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2, cv2.LINE_AA) # White color for visibility
170
-
171
- # Get the size of the text for the current action to display
172
- text_size = cv2.getTextSize(f'{current_action}', cv2.FONT_HERSHEY_SIMPLEX, 3, 5)[0]
173
- # Calculate the x position to center the current action text horizontally
174
- text_x = (frame.shape[1] - text_size[0]) // 2
175
- # Put the current action text on the frame at the top center, adjusting the y position to avoid going off-screen
176
- cv2.putText(frame, f'{current_action}',
177
- (text_x, text_size[1] + 10), # Adjusted y position to ensure text is visible
178
- cv2.FONT_HERSHEY_SIMPLEX, 3, (0, 0, 255), 5, cv2.LINE_AA) # Large font size and blue color for visibility
179
-
180
- # Create a banner for the score background
181
- banner_height = 50
182
- overlay = frame.copy() # Create a copy of the frame for the overlay
183
- cv2.rectangle(overlay, (0, frame.shape[0] - banner_height), (frame.shape[1], frame.shape[0]), (0, 0, 0), cv2.FILLED) # Black banner at the bottom
184
- alpha = 0.5 # Set transparency level
185
- cv2.addWeighted(overlay, alpha, frame, 1 - alpha, 0, frame) # Blend the overlay with the original frame
186
-
187
- # Display the score at the bottom center of the frame
188
- text_size = cv2.getTextSize(f'Score: {score}', cv2.FONT_HERSHEY_SIMPLEX, 1, 2)[0] # Get the size of the text
189
- text_x = (frame.shape[1] - text_size[0]) // 2 # Calculate the x position to center the text horizontally
190
- cv2.putText(frame, f'Score: {score}',
191
- (text_x, frame.shape[0] - 20), # Move text to the bottom center of the image
192
- cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2, cv2.LINE_AA) # White text for visibility
193
-
194
- # Show the frame
195
- cv2.imshow('Body Tracking', frame)
196
-
197
- key = cv2.waitKey(1) & 0xFF
198
- # Check for quitting the application
199
- if key == ord('q'): # Press 'q' to quit
200
- break
201
- elif key == ord('r'): # Press 'r' to reset score
202
- score = 0
203
- elif key == ord('v'): # Press 'v' to toggle recording
204
- if not is_recording:
205
- user_input_name = input("Enter the name for the recording: ") # Prompt user for input name
206
- timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") # Get current timestamp
207
- video_writer = cv2.VideoWriter(f'recording/{user_input_name}_{timestamp}.mp4', cv2.VideoWriter_fourcc(*'H264'), 20.0, (1280, 720)) # Initialize video writer in MP4 format with H.264 codec
208
- is_recording = True
209
- print("Recording started.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
210
  else:
211
- is_recording = False
212
- video_writer.release() # Release the video writer
213
- video_writer = None
214
- print("Recording stopped.")
215
- elif key == ord('d'): # Press 'd' to toggle drawing of pose
216
- pose_drawing_enabled = not pose_drawing_enabled # Toggle the drawing state
217
- print(f"Pose drawing {'enabled' if pose_drawing_enabled else 'disabled'}.") # Print the current state
218
-
219
- # Write the frame to the video file if recording
220
- if is_recording and video_writer is not None:
221
- video_writer.write(frame)
222
-
223
- pose.close()
224
- cap.release()
225
- if video_writer is not None:
226
- video_writer.release() # Ensure the video writer is released if still open
227
- cv2.destroyAllWindows()
 
1
+ """Application to demo inpainting, Median and Bilateral Blur using streamlit.
2
+
3
+ Run using: streamlit run 10_04_image_restoration_app.py
4
+ """
5
+
6
+ import streamlit as st
7
+ import pathlib
8
+ from streamlit_drawable_canvas import st_canvas
9
  import cv2
10
+ import numpy as np
11
+ import io
12
+ import base64
13
+ from PIL import Image
14
+
15
+
16
+ # Function to create a download link for output image
17
+ def get_image_download_link(img, filename, text):
18
+ """Generates a link to download a particular image file."""
19
+ buffered = io.BytesIO()
20
+ img.save(buffered, format='JPEG')
21
+ img_str = base64.b64encode(buffered.getvalue()).decode()
22
+ href = f'<a href="data:file/txt;base64,{img_str}" download="{filename}">{text}</a>'
23
+ return href
24
+
25
+
26
+ # Set title.
27
+ st.sidebar.title('Image Restoration')
28
+
29
+
30
+ # Specify canvas parameters in application
31
+ uploaded_file = st.sidebar.file_uploader("Upload Image to restore OK:", type=["png", "jpg"])
32
+ image = None
33
+ res = None
34
+
35
+ if uploaded_file is not None:
36
+ # Debug: Print uploaded file information
37
+ # st.write("Uploaded file:", uploaded_file.name)
38
+
39
+ # Convert the file to an opencv image.
40
+ file_bytes = np.asarray(bytearray(uploaded_file.read()), dtype=np.uint8)
41
+ image = cv2.imdecode(file_bytes, 1)
42
+ # Debug: Print image shape
43
+ # st.write("Image shape:", image.shape)
44
+
45
+ # Display the uploaded image immediately
46
+ # st.image(image[:,:,::-1], caption='Uploaded Image')
47
+ # Display a selection box for choosing the filter to apply.
48
+ option = st.sidebar.selectbox('Median or Bilateral Blur or Inpaint?', ('None', 'Median Blur', 'Bilateral Blur', 'Image Inpaint'))
49
+
50
+ if option == 'Median Blur':
51
+ ksize = st.sidebar.slider("ksize: ", 3, 15, 5, 2)
52
+ image = cv2.medianBlur(image, ksize)
53
+ res=image[:,:,::-1]
54
+ st.image(res)
55
+ elif option == 'Bilateral Blur':
56
+ dia = st.sidebar.slider("diameter: ", 1, 50, 20)
57
+ sigmaColor = st.sidebar.slider("sigmaColor: ", 0, 250, 200, 10)
58
+ sigmaSpace = st.sidebar.slider("sigmaSpace: ", 0, 250, 100, 10)
59
+ image = cv2.bilateralFilter(image, dia, sigmaColor, sigmaSpace)
60
+ res=image[:,:,::-1]
61
+ st.image(res)
62
+
63
+ elif option == 'Image Inpaint':
64
+ # Debug: Print selected option
65
+ # st.write("Selected option for inpainting:", option)
66
+
67
+ stroke_width = st.sidebar.slider("Stroke width: ", 1, 25, 5)
68
+ # st.write("Stroke width:", stroke_width) # Debug: Print stroke width
69
+
70
+ h, w = image.shape[:2]
71
+ # st.write("Original image dimensions (h, w):", h, w) # Debug: Print dimensions
72
+ if w > 800:
73
+ h_, w_ = int(h * 800 / w), 800
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  else:
75
+ h_, w_ = h, w
76
+ # st.write("Updated image dimensions (h_, w_):", h_, w_) # Debug: Print dimensions
77
+
78
+ # Create a canvas component.
79
+ canvas_result = st_canvas(
80
+ fill_color='white',
81
+ stroke_width=stroke_width,
82
+ stroke_color='black',
83
+ background_image=Image.open(uploaded_file).resize((h_, w_)),
84
+ update_streamlit=True,
85
+ height=h_,
86
+ width=w_,
87
+ drawing_mode='freedraw',
88
+ key="canvas",
89
+ )
90
+
91
+ # Debug: Print canvas result
92
+ # st.write("Canvas result:", canvas_result)
93
+
94
+ stroke = canvas_result.image_data
95
+ if stroke is not None:
96
+ # Debug: Print stroke data
97
+ # st.write("Stroke data shape:", stroke.shape)
98
+
99
+ if st.sidebar.checkbox('show mask'):
100
+ st.image(stroke)
101
+
102
+ mask = cv2.split(stroke)[3]
103
+ mask = np.uint8(mask)
104
+ mask = cv2.resize(mask, (w, h))
105
+ # Debug: Print mask shape
106
+ # st.write("Mask shape:", mask.shape)
107
+
108
+ st.sidebar.caption('Happy with the selection?')
109
+ option = st.sidebar.selectbox('Mode', ['None', 'Telea', 'NS', 'Compare both'])
110
+
111
+ if option == 'Telea':
112
+ st.subheader('Result of Telea')
113
+ res = cv2.inpaint(src=image, inpaintMask=mask, inpaintRadius=3, flags=cv2.INPAINT_TELEA)[:,:,::-1]
114
+ st.image(res)
115
+ # Debug: Print result shape
116
+ # st.write("Telea result shape:", res.shape)
117
+ elif option == 'Compare both':
118
+ col1, col2 = st.columns(2)
119
+ res1 = cv2.inpaint(src=image, inpaintMask=mask, inpaintRadius=3, flags=cv2.INPAINT_TELEA)[:,:,::-1]
120
+ res2 = cv2.inpaint(src=image, inpaintMask=mask, inpaintRadius=3, flags=cv2.INPAINT_NS)[:,:,::-1]
121
+ with col1:
122
+ st.subheader('Result of Telea')
123
+ st.image(res1)
124
+ with col2:
125
+ st.subheader('Result of NS')
126
+ st.image(res2)
127
+ if res1 is not None:
128
+ # Display link.
129
+ result1 = Image.fromarray(res1)
130
+ st.sidebar.markdown(
131
+ get_image_download_link(result1, 'telea.png', 'Download Output of Telea'),
132
+ unsafe_allow_html=True)
133
+ if res2 is not None:
134
+ # Display link.
135
+ result2 = Image.fromarray(res2)
136
+ st.sidebar.markdown(
137
+ get_image_download_link(result2, 'ns.png', 'Download Output of NS'),
138
+ unsafe_allow_html=True)
139
+
140
+ elif option == 'NS':
141
+ st.subheader('Result of NS')
142
+ res = cv2.inpaint(src=image, inpaintMask=mask, inpaintRadius=3, flags=cv2.INPAINT_NS)[:,:,::-1]
143
+ st.image(res)
144
  else:
145
+ pass
146
+
147
+ if res is not None:
148
+ # Debug: Print final result shape
149
+ # st.write("Final result shape:", res.shape)
150
+ # Display link.
151
+ result = Image.fromarray(res)
152
+ st.sidebar.markdown(
153
+ get_image_download_link(result, 'output.png', 'Download Output'),
154
+ unsafe_allow_html=True)
 
 
 
 
 
 
 
requirements.txt CHANGED
@@ -1,6 +1,5 @@
1
- # opencv-python
2
  numpy
3
  streamlit
4
  opencv-python-headless
5
  pillow
6
- mediapipe==0.10.14
 
 
1
  numpy
2
  streamlit
3
  opencv-python-headless
4
  pillow
5
+ streamlit_drawable_canvas