This commit is contained in:
Rémi BUSSIERE 2023-11-22 17:31:12 +01:00
parent c3d23ae2e1
commit c79adab0ec
9 changed files with 162 additions and 57 deletions

View File

@ -21,13 +21,13 @@ def roi(frame):
color = (255, 255, 255) # Color in BGR format (white)
# thickness = 2
mask = np.zeros((height, width), dtype=np.uint8)
cv2.ellipse(mask, center_ellipse, axes, angle, 0, 360, 255, -1) # 255 for a white oval
cv2.ellipse(mask, center_ellipse, axes, angle, 0, 360, 0, -1) # 255 for a white oval
# Apply the inverted mask to the face
result = cv2.bitwise_and(frame, frame, mask=mask)
#black_mask = (result[:, :, 0] == 0) & (result[:, :, 1] == 0) & (result[:, :, 2] == 0)
black_mask = (result[:, :, 3] == 0)# & (result[:, :, 1] == 0) & (result[:, :, 2] == 0)
#print(result[c_x2, c_y2,1])
# Replace black pixels with white pixels
#result[black_mask] = [result[10, 10, 0], result[10, 10, 1], result[10, 10, 2]]
result[black_mask] = [result[0, 0, 0], result[0, 0, 1], result[0, 0, 2]]
return result
return frame

67
coordinates_change.py Normal file
View File

@ -0,0 +1,67 @@
import numpy as np
def coord(contours, x_offset, y_offset, x_scale, y_scale):
new_contours = []
for i in range(len(contours)):
for j in range(len(contours[i])):
x = contours[i][j][0][0]*x_scale + x_offset
y = contours[i][j][0][1]*y_scale + y_offset
new_contours.append([x, y])
return new_contours
def scale_calculator(contours, size):
x_max = contours[0][0][0][0]
x_min = contours[0][0][0][0]
y_max = contours[0][0][0][1]
y_min = contours[0][0][0][1]
for i in range(len(contours)):
for j in range(len(contours[i])):
x = contours[i][j][0][0]
y = contours[i][j][0][1]
if x_min > x:
x_min = x
if x > x_max:
x_max = x
if y_min > y:
y_min = y
if y > y_max:
y_max = y
# print([[x_min, x_max], [y_min, y_max]]) #display max and min in x and y
x_scale = 1.0
y_scale = 1.0
if size[0] != 0:
x_scale = size[0]/(x_max - x_min)
if size[1] != 0:
y_scale = size[1]/(y_max - y_min)
if size[0] == 0:
x_scale = y_scale
if size[1] == 0:
y_scale = x_scale
x_min = x_min*x_scale
y_min = y_min*y_scale
return [x_min, y_min, x_scale, y_scale]
def get_size(coords):
x_max = coords[0][0]
x_min = coords[0][0]
y_max = coords[0][1]
y_min = coords[0][1]
for i in range(len(coords)):
x = coords[i][0]
y = coords[i][1]
if x_min > x:
x_min = x
if x > x_max:
x_max = x
if y_min > y:
y_min = y
if y > y_max:
y_max = y
return [[x_min, x_max], [y_min, y_max]] #display max and min in x and y

View File

@ -1,37 +1,39 @@
import cv2
import time
cap = cv2.VideoCapture(0)
def get_image():
# Set the window name
cap = cv2.VideoCapture(0)
window_name = 'Camera Capture'
countdown_duration = 60
# Get the default frames per second (fps) of the camera
fps = int(cap.get(cv2.CAP_PROP_FPS))
# Check if the camera is opened successfully
if not cap.isOpened():
print("Error: Could not open the camera.")
return None
# Set the countdown duration in seconds
countdown_duration = 10
# Start the countdown
for countdown in range(countdown_duration, 10, -1):
ret, frame = cap.read()
# Display the camera feed
cv2.imshow(window_name, frame)
# Display the countdown on the image
# Check if the frame is read successfully
if not ret:
print("Error: Could not read frame.")
return None
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(frame, str(countdown)[0], (10, 30), font, 1, (0, 255, 0), 2, cv2.LINE_AA)
cv2.imshow(window_name, frame)
cv2.waitKey(100)
# Wait for 1 second and check for key press
if cv2.waitKey(100) & 0xFF == 27: # 27 is the ASCII code for the 'ESC' key
break
output_path = 'image.png'
cv2.imwrite(output_path, frame)
# Take a picture at the end of the countdown
ret, frame = cap.read()
#cv2.imwrite("image.png", frame)
# Release the camera and close the OpenCV window
# Release the camera capture object
cap.release()
cv2
return frame
# Destroy all OpenCV windows
cv2.destroyAllWindows()
print(f"Image saved successfully at '{output_path}'.")
return output_path

BIN
goutput.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

BIN
image.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 295 KiB

After

Width:  |  Height:  |  Size: 283 KiB

41
main.py
View File

@ -1,17 +1,42 @@
import cv2
import show_img_conditions
import ROI_face
import remove_bg
import get_head
import coordinates_change
import numpy as np
#show_img_conditions.show()
gray = get_head.get_image()
cv2.imshow('Grey Image', gray)
face = ROI_face.roi(gray)
cv2.imshow('Face', face)
edges = cv2.Canny(face, 10, 100)
cv2.imshow('Image avec Contours de Visage', edges)
image_path = get_head.get_image()
image = cv2.imread(image_path)
#cv2.imshow('Image', image)
image_path = 'image.png'
background_path = remove_bg.rmbg(image_path)
background = cv2.imread(background_path)
#cv2.imshow('Image without background', background)
gray_image = cv2.cvtColor(background, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray_image, 20, 80)
cv2.imshow("contours", edges)
cv2.waitKey(0)
cv2.destroyAllWindows()
contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
x_offset = 0 # offset in the x_axis
y_offset = 0 # offset in the y_axis
new_size = [150, 0] # new size of the picture in mm, write 0 if you want to be proportional
[x_min, y_min, x_scale, y_scale] = coordinates_change.scale_calculator(contours, new_size)
x_offset = x_offset - x_min
y_offset = y_offset - y_min
new_coords = coordinates_change.coord(contours, x_offset, y_offset, x_scale, y_scale)
size = coordinates_change.get_size(new_coords)
print("x offset : ", int(x_offset+x_min), "mm")
print("y offset : ", int(y_offset+y_min), "mm")
print("size : ", int(size[0][1] - size[0][0]), "x", int(size[1][1] - size[1][0]), "mm")

BIN
output.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

11
remove_bg.py Normal file
View File

@ -0,0 +1,11 @@
from rembg import remove
from PIL import Image
output_path = 'output.png'
def rmbg(input_path):
input = Image.open(input_path)
output = remove(input)
output.save(output_path)
return output_path

View File

@ -1,35 +1,35 @@
import cv2
import numpy as np
# Load an image
image = cv2.imread('image.jpg')
# Open a connection to the webcam (default camera index is 0)
cap = cv2.VideoCapture(0)
# Convert the image to grayscale
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Check if the camera is opened successfully
if not cap.isOpened():
print("Error: Could not open the camera.")
exit()
# Apply thresholding to create a binary image
_, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
# Create a window to display the webcam feed
window_name = 'Webcam Feed'
cv2.namedWindow(window_name, cv2.WINDOW_NORMAL)
# Find contours in the binary image
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
while True:
# Read a frame from the webcam
ret, frame = cap.read()
# Choose the contour you want to remove (in this example, the first contour is removed)
contour_to_remove = contours[0]
# Check if the frame is read successfully
if not ret:
print("Error: Could not read frame.")
break
# Create a mask with the same shape as the image
mask = np.zeros_like(image)
# Display the frame in the window
cv2.imshow(window_name, frame)
# Fill the contour with a background color (white in this case)
cv2.fillPoly(mask, [contour_to_remove], (255, 255, 255))
# Break the loop if 'q' key is pressed
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# Invert the mask to keep the rest of the image
mask_inv = cv2.bitwise_not(mask)
# Release the camera capture object
cap.release()
# Bitwise AND the original image with the inverted mask
result = cv2.bitwise_and(image, mask_inv)
# Display the original and processed images
cv2.imshow('Original Image', image)
cv2.imshow('Result', result)
cv2.waitKey(0)
# Destroy the OpenCV window
cv2.destroyAllWindows()