Reputation: 161
This script is analysing face reactions with Face.com API. for some reason pygame can't find my camera (I think that's the problem). is there anything wrong with my code?
I have pygame installed and appears to work perfectly. but the code below gives me error.
####################################################
# IMPORTS
####################################################
# imports for capturing a frame from the webcam
import pygame
import pygame.camera
import pygame.image
# import for detecting faces in the photo
import face_client
# import for storing data
from pysqlite2 import dbapi2 as sqlite
# miscellaneous imports
from time import strftime, localtime, sleep
import os
import sys
####################################################
# CONSTANTS
####################################################
DB_FILE_PATH="log.db"
FACE_COM_APIKEY="API CODE"
FACE_COM_APISECRET="API SECRET"
DALELANE_FACETAG="[email protected]"
POLL_FREQUENCY_SECONDS=3
class AudienceMonitor():
#
# prepare the database where we store the results
#
def initialiseDB(self):
self.connection = sqlite.connect(DB_FILE_PATH, detect_types=sqlite.PARSE_DECLTYPES|sqlite.PARSE_COLNAMES)
cursor = self.connection.cursor()
cursor.execute('SELECT name FROM sqlite_master WHERE type="table" AND NAME="facelog" ORDER BY name')
if not cursor.fetchone():
cursor.execute('CREATE TABLE facelog(ts timestamp unique default current_timestamp, isSmiling boolean, smilingConfidence int, mood text, moodConfidence int)')
cursor.execute('SELECT name FROM sqlite_master WHERE type="table" AND NAME="guestlog" ORDER BY name')
if not cursor.fetchone():
cursor.execute('CREATE TABLE guestlog(ts timestamp unique default current_timestamp, isSmiling boolean, smilingConfidence int, mood text, moodConfidence int, agemin int, ageminConfidence int, agemax int, agemaxConfidence int, ageest int, ageestConfidence int, gender text, genderConfidence int)')
self.connection.commit()
#
# initialise the camera
#
def prepareCamera(self):
# prepare the webcam
pygame.camera.init()
self.camera = pygame.camera.Camera(pygame.camera.list_cameras()[0], (900, 675))
self.camera.start()
#
# take a single frame and store in the path provided
#
def captureFrame(self, filepath):
# save the picture
image = self.camera.get_image()
pygame.image.save(image, filepath)
#
# gets a string representing the current time to the nearest second
#
def getTimestampString(self):
return strftime("%Y%m%d%H%M%S", localtime())
#
# get attribute from face detection response
#
def getFaceDetectionAttributeValue(self, face, attribute):
value = None
if attribute in face['attributes']:
value = face['attributes'][attribute]['value']
return value
#
# get confidence from face detection response
#
def getFaceDetectionAttributeConfidence(self, face, attribute):
confidence = None
if attribute in face['attributes']:
confidence = face['attributes'][attribute]['confidence']
return confidence
#
# detects faces in the photo at the specified path, and returns info
#
def faceDetection(self, photopath):
client = face_client.FaceClient(FACE_COM_APIKEY, FACE_COM_APISECRET)
response = client.faces_recognize(DALELANE_FACETAG, file_name=photopath)
faces = response['photos'][0]['tags']
for face in faces:
userid = ""
faceuseridinfo = face['uids']
if len(faceuseridinfo) > 0:
userid = faceuseridinfo[0]['uid']
if userid == DALELANE_FACETAG:
smiling = self.getFaceDetectionAttributeValue(face, "smiling")
smilingConfidence = self.getFaceDetectionAttributeConfidence(face, "smiling")
mood = self.getFaceDetectionAttributeValue(face, "mood")
moodConfidence = self.getFaceDetectionAttributeConfidence(face, "mood")
self.storeResults(smiling, smilingConfidence, mood, moodConfidence)
else:
smiling = self.getFaceDetectionAttributeValue(face, "smiling")
smilingConfidence = self.getFaceDetectionAttributeConfidence(face, "smiling")
mood = self.getFaceDetectionAttributeValue(face, "mood")
moodConfidence = self.getFaceDetectionAttributeConfidence(face, "mood")
agemin = self.getFaceDetectionAttributeValue(face, "age_min")
ageminConfidence = self.getFaceDetectionAttributeConfidence(face, "age_min")
agemax = self.getFaceDetectionAttributeValue(face, "age_max")
agemaxConfidence = self.getFaceDetectionAttributeConfidence(face, "age_max")
ageest = self.getFaceDetectionAttributeValue(face, "age_est")
ageestConfidence = self.getFaceDetectionAttributeConfidence(face, "age_est")
gender = self.getFaceDetectionAttributeValue(face, "gender")
genderConfidence = self.getFaceDetectionAttributeConfidence(face, "gender")
# if the face wasnt recognisable, it might've been me after all, so ignore
if "tid" in face and face['recognizable'] == True:
self.storeGuestResults(smiling, smilingConfidence, mood, moodConfidence, agemin, ageminConfidence, agemax, agemaxConfidence, ageest, ageestConfidence, gender, genderConfidence)
print face['tid']
#
# stores face results in the DB
#
def storeGuestResults(self, smiling, smilingConfidence, mood, moodConfidence, agemin, ageminConfidence, agemax, agemaxConfidence, ageest, ageestConfidence, gender, genderConfidence):
cursor = self.connection.cursor()
cursor.execute('INSERT INTO guestlog(isSmiling, smilingConfidence, mood, moodConfidence, agemin, ageminConfidence, agemax, agemaxConfidence, ageest, ageestConfidence, gender, genderConfidence) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
(smiling, smilingConfidence, mood, moodConfidence, agemin, ageminConfidence, agemax, agemaxConfidence, ageest, ageestConfidence, gender, genderConfidence))
self.connection.commit()
#
# stores face results in the DB
#
def storeResults(self, smiling, smilingConfidence, mood, moodConfidence):
cursor = self.connection.cursor()
cursor.execute('INSERT INTO facelog(isSmiling, smilingConfidence, mood, moodConfidence) values(?, ?, ?, ?)',
(smiling, smilingConfidence, mood, moodConfidence))
self.connection.commit()
monitor = AudienceMonitor()
monitor.initialiseDB()
monitor.prepareCamera()
while True:
photopath = "data/photo" + monitor.getTimestampString() + ".bmp"
monitor.captureFrame(photopath)
try:
faceresults = monitor.faceDetection(photopath)
except:
print "Unexpected error:", sys.exc_info()[0]
os.remove(photopath)
sleep(POLL_FREQUENCY_SECONDS)
error I get is
Traceback (most recent call last):
File "gamemood.py", line 147, in <module>
monitor.prepareCamera()
File "gamemood.py", line 56, in prepareCamera
self.camera = pygame.camera.Camera(pygame.camera.list_cameras()[0], (900, 675))
TypeError: 'NoneType' object is not subscriptable
I don't understand this error! what's wrong? Pygame can't find my camera?
Upvotes: 2
Views: 2542
Reputation: 5161
list_cameras
is returning None
instead of a list, and the error you're seeing is what happens when you try to retrieve None[0]
.
Based on the source, it looks like much of the functionality in the camera
module is quietly disabled when Pygame is compiled on a non-Linux platform. Even if these functions should work on Mac OS, there are preprocessor directives that directly exclude it.
From Pygame 1.9.1:
/* list_cameras() - lists cameras available on the computer */
PyObject* list_cameras (PyObject* self, PyObject* arg)
{
#if defined(__unix__)
PyObject* ret_list;
PyObject* string;
char** devices;
int num_devices, i;
num_devices = 0;
ret_list = NULL;
ret_list = PyList_New (0);
if (!ret_list)
return NULL;
devices = v4l2_list_cameras(&num_devices);
for(i = 0; i < num_devices; i++) {
string = PyString_FromString(devices[i]);
PyList_Append(ret_list, string);
Py_DECREF(string);
free(devices[i]);
}
free(devices);
return ret_list;
#else
Py_RETURN_NONE;
#endif
}
I think that's the most likely explanation for what's happening. Your code may be fine, but the function you're calling can only return None
. I don't know enough about Mac OS or the camera
module to tell you what would or wouldn't work if you changed all of those statements to #if defined(__unix__) || defined(__APPLE__)
and compiled it yourself.
Upvotes: 1