I made a Smart RGB Light Bulb using Raspberry Pi Pico W and NeoPixel RGB Ring. by help of Deepface library and opencv we can detect emotions of persons in video. color of the lamp changes based on the emotions of person in video.
first of all I Wrote a python script using opencv python and deepface library(developed by Meta) that detects emotions.
install these libraries using pip command.
pip install opencv-python
pip install deepface
emotion detection script:
import cv2
from deepface import DeepFace
from time import sleep
cap = cv2.VideoCapture("faces8s.avi")
def showResults(feed):
output = feed[0]
outputList = list(output.items())
#print(type(outputList))
#print(outputList[1])
dominantEmotion, detectedEmotion = outputList[1]
#print(detectedEmotion)
#sleep(2)
return detectedEmotion
while True:
ret , vid = cap.read()
results = DeepFace.analyze(vid,actions=("emotion"),enforce_detection=False)
emotion = showResults(results)
#print(emotion)
cv2.putText(vid,emotion, (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (80, 70, 255), 2, cv2.LINE_4)
cv2.imshow("video",vid)
k = cv2.waitKey(1) & 0xFF
if k == 27:
break
cv2.destroyAllWindows()
run this script and see what happens.
In the second step, we write a script that, in addition to detecting emotions, sends commands to the raspberry pi pico microcontroller using socket programming.
import socket
import cv2
from deepface import DeepFace
from time import sleep
cap = cv2.VideoCapture("faces8s.avi")
def showResults(feed):
output = feed[0]
outputList = list(output.items())
#print(type(outputList))
#print(outputList[1])
dominantEmotion, detectedEmotion = outputList[1]
#print(detectedEmotion)
#sleep(2)
return detectedEmotion
# Create a TCP socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Specify the IP address and port number of your Raspberry Pi Pico W
# You can use the ipconfig or ifconfig command to find out the IP address of your device
ip = '192.168.0.103' # Change this to your Raspberry Pi Pico W IP address
port = 80 # Change this to your Raspberry Pi Pico W port number
# Connect to the server socket
s.connect((ip, port))
# Start a while loop
while True:
ret , vid = cap.read()
results = DeepFace.analyze(vid,actions=("emotion"),enforce_detection=False)
emotion = showResults(results)
#print(emotion)
cv2.putText(vid,emotion, (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (80, 70, 255), 2, cv2.LINE_4)
cv2.imshow("video",vid)
k = cv2.waitKey(1) & 0xFF
data = emotion
# Encode the data as bytes
data = data.encode()
# Send the data to the server
s.send(data)
# Receive a response from the server
response = s.recv(1024)
print(response)
# Check if the user wants to stop the loop
if k == 27:
break
# Close the socket
s.close()
cv2.destroyAllWindows()
in final step wee need to receive commands on raspberry pi pico side. On the microcontroller side, we also need socket programming to receive commands over the network. According to each command we receive, the color of the lamp changes. By reading the following script, you will get a detailed understanding of the functionality of the lamp hardware.
import socket
import network
from time import sleep
import machine
from machine import Pin
import neopixel
ssid = 'mrsh77'
password = '1m77n2299215r77#'
def connect():
#Connect to WLAN
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)
while wlan.isconnected() == False:
print('Waiting for connection...')
sleep(1)
ip = wlan.ifconfig()[0]
print(f'Connected on {ip}')
return ip
def open_socket(ip):
address = (ip,80)
connection = socket.socket()
connection.bind(address)
connection.listen(1)
#print(connection)
return connection
neopixel_pin = Pin(0)
led_num = 8
brightness = 0.2 # Adjust the brightness (0.0 - 1.0)
rgb_ring = neopixel.NeoPixel(neopixel_pin, led_num)
def brightnessfcn(color):
r, g, b= color
r = int(r * brightness)
g = int(g * brightness)
b = int(b * brightness)
return (r,g,b)
try:
ip = connect()
connection = open_socket(ip)
while True:
# Accept a connection from a client
client, addr = connection.accept()
print(f'Connected to {addr}')
while True:
# Receive data from the client
data = client.recv(1024)
if data:
# Print the data to the console
print(data)
if data == b'sad':
lamp_color = (255,255,255)
final_color = brightnessfcn(lamp_color)
rgb_ring.fill(final_color)
rgb_ring.write()
elif data == b'fear':
lamp_color = (128,0,128)
final_color = brightnessfcn(lamp_color)
rgb_ring.fill(final_color)
rgb_ring.write()
elif data == b'angry':
lamp_color = (0,0,255)
final_color = brightnessfcn(lamp_color)
rgb_ring.fill(final_color)
rgb_ring.write()
elif data == b'happy':
lamp_color = (255,165,0)
final_color = brightnessfcn(lamp_color)
rgb_ring.fill(final_color)
rgb_ring.write()
elif data == b'neutral':
lamp_color = (255,255,255)
final_color = brightnessfcn(lamp_color)
rgb_ring.fill(final_color)
rgb_ring.write()
# Send a response back to the client
client.send(b'OK')
else:
# Break the loop if no data is received
break
# Close the client socket
client.close()
except KeyboardInterrupt:
# Close the server socket
connection.close()
machine.reset()
also you can see full video tutorial on my youtube channel in below.
I hope you enjoy this project.
Comments