Browse Source

Finished and tested pyhtk, include sample conf file, added non working facedetect

master
Sam Black 11 years ago
parent
commit
a87db64932
3 changed files with 345 additions and 118 deletions
  1. +172
    -0
      ee4h/facedetect.py
  2. +22
    -0
      ee4p/python/ee4h.conf
  3. +151
    -118
      ee4p/python/pyhtk.py

+ 172
- 0
ee4h/facedetect.py View File

@@ -0,0 +1,172 @@
#!/usr/bin/python
"""
This program is demonstration for face and object detection using haar-like features.
The program finds faces in a camera image or video stream and displays a red box around them.

Original C implementation by: ?
Python implementation by: Roman Stanchak
"""
import sys
import os
from opencv.cv import *
from opencv.highgui import *
from PIL import Image

# Global Variables
cascade = None
storage = cvCreateMemStorage(0)
cascade_name = "/usr/share/opencv/haarcascades/haarcascade_frontalface_alt.xml"
input_name = "../c/lena.jpg"

# Parameters for haar detection
# From the API:
# The default parameters (scale_factor=1.1, min_neighbors=3, flags=0) are tuned
# for accurate yet slow object detection. For a faster operation on real video
# images the settings are:
# scale_factor=1.2, min_neighbors=2, flags=CV_HAAR_DO_CANNY_PRUNING,
# min_size=<minimum possible face size
min_size = cvSize(20,20)
image_scale = 1.2
haar_scale = 1.2
min_neighbors = 2
haar_flags = CV_HAAR_DO_CANNY_PRUNING


def crop_count():

#load image
im = Image.open("face.jpg")
#get image dimensions
images = im.size
iheight = images[0] / 2
iwidth = images [1]
#set cropping area
box = (0,iheight,iwidth,iwidth)
#crop image in half
im = im.crop(box)
#get cropped image dimensions
crops = im.size
cheight = crops[0] / 4
cwidth = crops[1]
#set new crop area
box2 = (60,cheight, iwidth - 60, cwidth)
#crop mouth
im2 = im.crop(box2)
#save picture
im2.save("current.jpg")
os.remove("face.jpg")
source = cvLoadImage ("current.jpg")
grey = cvCreateImage (cvSize (source.width, source.height), 8, 1)
output = cvCreateImage (cvSize (source.width, source.height), 8, 1)

# Convert to greyscale
cvCvtColor (source, grey, CV_BGR2GRAY)

# Convert to black and white based on threshold of 50
cvThreshold(grey, output, 50, 255, CV_THRESH_BINARY)

count = 0

# Count number of dark pixels
for i in output:
for j in i:
if j == 255:
count += 1

print "Number of dark pixels: " + str(count)

def detect_and_draw( img ):
# allocate temporary images
gray = cvCreateImage( cvSize(img.width,img.height), 8, 1 )
small_img = cvCreateImage( cvSize( cvRound (img.width/image_scale),
cvRound (img.height/image_scale)), 8, 1 )

# convert color input image to grayscale
cvCvtColor( img, gray, CV_BGR2GRAY )

# scale input image for faster processing
cvResize( gray, small_img, CV_INTER_LINEAR )

cvEqualizeHist( small_img, small_img )

cvClearMemStorage( storage )

if( cascade ):
t = cvGetTickCount()
faces = cvHaarDetectObjects( small_img, cascade, storage,
haar_scale, min_neighbors, haar_flags, min_size )
t = cvGetTickCount() - t
print "detection time = %gms" % (t/(cvGetTickFrequency()*1000.))
if faces:
for face_rect in faces:
x = int(face_rect.x*image_scale)
y = int(face_rect.y*image_scale)
h = int(face_rect.height*image_scale)
w = int(face_rect.width*image_scale)
face = cvRect(x,y,w,h)
crop = cvGetSubRect(img,face)
cvSaveImage("face.jpg", crop)

if __name__ == '__main__':

if len(sys.argv) > 1:

if sys.argv[1].startswith("--cascade="):
cascade_name = sys.argv[1][ len("--cascade="): ]
if len(sys.argv) > 2:
input_name = sys.argv[2]

elif sys.argv[1] == "--help" or sys.argv[1] == "-h":
print "Usage: facedetect --cascade=\"<cascade_path>\" [filename|camera_index]\n"
sys.exit(-1)

else:
input_name = sys.argv[1]

# the OpenCV API says this function is obsolete, but we can't
# cast the output of cvLoad to a HaarClassifierCascade, so use this anyways
# the size parameter is ignored
cascade = cvLoadHaarClassifierCascade( cascade_name, cvSize(1,1) )

if not cascade:
print "ERROR: Could not load classifier cascade"
sys.exit(-1)


if input_name.isdigit():
capture = cvCreateCameraCapture( int(input_name) )
print "Capturing from camera"
else:
capture = cvCreateFileCapture( input_name )
print "Capturing from file"

if( capture ):
frame_copy = None
i = 0
while True:
frame = cvQueryFrame( capture )
print i
if( not frame ):
break
if( not frame_copy ):
frame_copy = cvCreateImage( cvSize(frame.width,frame.height), IPL_DEPTH_8U, frame.nChannels )
if( frame.origin == IPL_ORIGIN_TL ):
cvCopy( frame, frame_copy )
else:
cvFlip( frame, frame_copy, 0 )
detect_and_draw( frame_copy )
print "detecting and drawing!"
crop_count()
i = i+1
if( cvWaitKey( 10 ) >= 0 ):
break

else:
image = cvLoadImage( input_name, 1 )

if( image ):

detect_and_draw( image )
cvWaitKey(0)

cvDestroyWindow("result")

+ 22
- 0
ee4p/python/ee4h.conf View File

@@ -0,0 +1,22 @@
listTest list/listTestFulPath_Hcopy.scp
resultdir results/
binpath /home/sam/apps/htk/bin/
listTestHCopy list/listTestFulPath_Hcopy.scp
worddict lib/wordDict
wordLabelSP label/label_EE4H_withSP.mlf
wordnet lib/wordNetwork
wordLabel label/label_EE4H_noSP.mlf
proto lib/proto_s1d39_st8m1_EE4H
hmmdir hmmsTrained/
listTrain list/listTrainFulPath.scp
hedsilsp lib/tieSILandSP_EE4H.hed
configTrain config/config_train_mfcc
configTest config/config_test_mfcc
space_step 8
wordListSP lib/wordList_withSP
wordList lib/wordList_noSP
listTrainHCopy list/listTrainFulPath_Hcopy.scp
confpath /home/sam/htk/
project ee4h
flags
configHCopy config/config_HCopy

+ 151
- 118
ee4p/python/pyhtk.py View File

@@ -28,6 +28,7 @@ class HtkConfig:

def __init__(self, binpath="/usr/bin/", configpath="./", projname="testHTK", list=False):
self.configfile = open(configpath + projname + ".conf", 'r')
self.no_conf = ["binpath", "project", "confpath", "flags", "space_step"]
self.configs = {
"binpath" : binpath,
"project" : projname,
@@ -48,22 +49,26 @@ class HtkConfig:
"worddict" : configpath + "lib/worddict_" + projname,
"hedsilsp" : configpath + "lib/hedsilsp_" + projname + ".hed",
"proto" : configpath + "lib/proto_" + projname,
"results" : configpath + "results/results_" + projname,
"flags" : "",
"resultdir" : configpath + "results/",
"space_step" : 8
}

if not list:
for line in self.configfile:
if line.split()[0] in self.configs:
self.configs[line.split()[0]] = line.split()[1]
if len(line.split()) > 1:
if line.split()[0] in self.configs:
if line.split()[0] in self.no_conf:
self.configs[line.split()[0]] = line.split()[1]
else:
self.configs[line.split()[0]] = configpath + line.split()[1]

for part in self.configs:
if not self.configs[part].isdigit():
if not os.path.exists(self.configs[part]):
if not os.path.exists(self.configs[part]) and not part in self.no_conf:
print part
print "%s does not exist, dieing" % self.configs[part]
sys.exit(1)
else:
elif not part in self.no_conf:
if self.configs[part].endswith("/"):
if not os.path.isdir(self.configs[part]):
print "%s is not a directory and it is configured as such, dieing" % self.configs[part]
@@ -80,8 +85,9 @@ class HtkConfig:
return False

def listSettings(self):
print "Default settings:"
for item in self.configs:
print item
print item + " %s" % self.configs[item]

class Htk:
def __init__(self, binpath, confpath, projname):
@@ -132,15 +138,17 @@ class Htk:
def training(self):
# Run HCopy to create initial HMMs
try:
ret1 = subprocess.check_call("-C %s -S %s" %
(self.config.getSetting("configHCopy"),
self.config.getSetting("listTrainHCopy")),
executable=self.config.getSetting("binpath") + "HCopy"
)
ret2 = subprocess.check_call("-C %s -S %s" % (self.config.getSetting("configHCopy"),
self.config.getSetting("listTestHCopy")),
executable=self.config.getSetting("binpath") + "HCopy"
)
hcopy1 = [self.config.getSetting("binpath") + "HCopy",
'-C', self.config.getSetting("configHCopy"),
'-S', self.config.getSetting("listTrainHCopy")
]
ret1 = subprocess.check_call(hcopy1)

hcopy2 = [self.config.getSetting("binpath") + "HCopy",
'-C', self.config.getSetting("configHCopy"),
'-S', self.config.getSetting("listTestHCopy")
]
ret2 = subprocess.check_call(hcopy2)
if ret1 != 0 or ret2 != 0:
print "Error, return codes wrong"
sys.exit(1)
@@ -149,18 +157,29 @@ class Htk:
sys.exit(1)
# Now training
print "Training"
for direc in range(0, self.config.getSetting("space_step")+1):
if os.path.isdir(self.config.getSetting("hmmdir")):
for root, dirs, files in os.walk(self.config.getSetting("hmmdir"), topdown=False):
for name in files:
os.remove(os.path.join(root, name))
for name in dirs:
os.rmdir(os.path.join(root, name))
if not os.path.isdir(self.config.getSetting("hmmdir")):
os.mkdir(self.config.getSetting("hmmdir"))
for direc in range(0, int(self.config.getSetting("space_step"))+1):
if not os.path.isdir(self.config.getSetting("hmmdir") + "hmm%d" % direc):
os.mkdir(self.config.getSetting("hmmdir") + "hmm%d" % direc)

try:
ret = subprocess.check_call("-C %s -o hmmdef -f 0.01 -m -S %s -M %shmm0 %s" %
(self.config.getSetting("configTrain"),
self.config.getSetting("listTrain"),
self.config.getSetting("hmmdir"),
self.config.getSetting("proto")),
executable=self.config.getSetting("binpath") + "HCompV"
)
hcompv = [self.config.getSetting("binpath") + "HCompV",
'-C', self.config.getSetting("configTrain"),
'-o', 'hmmdef',
'-f', '0.01',
'-m',
'-S', self.config.getSetting("listTrain"),
'-M', self.config.getSetting("hmmdir") + "hmm0",
self.config.getSetting("proto")
]
ret = subprocess.check_call(hcompv)
if ret != 0:
print "Error, return codes wrong"
sys.exit(1)
@@ -175,9 +194,9 @@ class Htk:
record = False
tmpdata = []
for line in hmmdef:
if line.contains("BEGINHMM"):
if line.find("BEGINHMM") >= 0:
record = True
elif line.contains("ENDHMM"):
elif line.find("ENDHMM") >= 0:
record = False
tmpdata.append(line)
if record:
@@ -186,52 +205,53 @@ class Htk:
model0 = open(self.config.getSetting("hmmdir") + "hmm0/models", 'a')
wordlist = open(self.config.getSetting("worddict"), 'r')
for line in wordlist:
if not line.contains("sp"):
model0.append('~h "%s"' % line.split()[0])
if not line.find("sp") >= 0:
model0.write('~h "%s"\n' % line.split()[0])
for part in tmpdata:
model0.append(part)
model0.write(part)
model0.close()
wordlist.close()
hmmdef.close()

vfloor = open(self.config.getSetting("hmmdir") + "hmm0/vFloors", 'r')
hmmdef = open(self.config.getSetting("hmmdir") + "hmm0/hmmdef", 'r')
macros = open(self.config.getSetting("hmmdir") + "hmm0/macros", 'a')
tmpmacro = []
macroterms = ["~o", "STREAMINFO", "DIAGC"]
for line in hmmdef:
if not line.contains("~h"):
tmpmacro.append(line)
for items in macroterms:
if items in line:
tmpmacro.append(line.strip('\n'))
tmpline = tmpmacro.pop().split("<")
for item in tmpline:
if item.find("DIAGC") == -1 and len(item) > 0:
tmpmacro.append("<" + item)
for line in tmpmacro:
if line.contains("DIAGC"):
tmpline = line.split("<")
tmpmacro.remove(line)
for item in tmpline:
if not item.contains("DIAGC"):
tmpmacro.append("<" + item)
for line in tmpmacro:
macros.append(line)
macros.write(line + "\n")
for line in vfloor:
macros.append(line)
macros.write(line)
print "Finished HMM word models"
vfloor.close()
macros.close()
hmmdef.close()
del tmpmacro

for iteration in range(1, 3):
for iteration in range(1,4):
print "Iteration %d" % iteration

try:
ret = subprocess.check_call("-D -C %s -I %s -t 250.0 150.0 1000.0 -S %s -H %shmm%d/macros -H %shmm%d/models -M %shmm%d %s" %
(self.config.getSetting("configTrain"),
self.config.getSetting("wordLabel"),
self.config.getSetting("listTrain"),
self.config.getSetting("hmmdir"),
iteration - 1,
self.config.getSetting("hmmdir"),
iteration - 1,
self.config.getSetting("hmmdir"),
iteration,
self.config.getSetting("wordList")),
executable=self.config.getSetting("binpath") + "HERest"
)
herest = [self.config.getSetting("binpath") + "HERest",
'-D',
'-C', self.config.getSetting("configTrain"),
'-I', self.config.getSetting("wordLabel"),
'-t', str(250.0), str(150.0), str(1000.0),
'-S', self.config.getSetting("listTrain"),
'-H', "%shmm%d/macros" % (self.config.getSetting("hmmdir"), iteration - 1),
'-H', "%shmm%d/models" % (self.config.getSetting("hmmdir"), iteration - 1),
'-M', "%shmm%d" % (self.config.getSetting("hmmdir"), iteration),
self.config.getSetting("wordList")
]
ret = subprocess.check_call(herest)
if ret != 0:
print "Error, return codes wrong"
sys.exit(1)
@@ -240,47 +260,53 @@ class Htk:
sys.exit(1)

print "Copying for 4th iteration"
shutil.copytree(self.config.getSetting("hmmdir") + "hmm3", self.config.getSetting("hmmdir") + "hmm4")
for root, dirs, files in os.walk(self.config.getSetting("hmmdir") + "hmm3", topdown=False):
for name in files:
shutil.copy(self.config.getSetting("hmmdir") + "hmm3/" + name, self.config.getSetting("hmmdir") + "hmm4")
print "Copied 4th iteration"

# create silence model
print "Correcting silence model"
macro3 = open(self.config.getSetting("hmmdir") + "hmm3/macros", 'r')
macro4 = open(self.config.getSetting("hmmdir") + "hmm4/macros", 'a')
tmpmacro = []
model3 = open(self.config.getSetting("hmmdir") + "hmm3/models", 'r')
model4 = open(self.config.getSetting("hmmdir") + "hmm4/models", 'a')
tmpmodel = []
record = False
for line in macro3:
if line.contains("sil"):
for line in model3:
if line.find("sil") >= 0:
record = True
if record and line.contains("ENDHMM"):
if record and line.find("ENDHMM") >= 0:
record = False
if record:
tmpmacro.append(line)
tmpmodel.append(line)
states = []
for line in tmpmacro:
if line.contains("STATE"):
states.append([tmpmacro[tmpmacro.index(line):tmpmacro.index(line) + 6]])
midstate = states[int(len(states)/2)]
macro4.append('~h "sp"\n<BEGINHMM>\n<NUMSTATES> 3\n<STATE> 2\n')
midstate = []
for line in tmpmodel:
if line.find("STATE") >= 0:
states.append([tmpmodel[tmpmodel.index(line):tmpmodel.index(line) + 6]])
for stat in states[int(len(states)/2)][0]:
midstate.append(stat)
model4.write('~h "sp"\n<BEGINHMM>\n<NUMSTATES> 3\n<STATE> 2\n')
for line in midstate:
macro4.append(line)
macro4.append("<TRANSP> 3")
for i in range(1,3):
macro4.append("0.000000e+00 0.000000e+00 0.000000e+00")
macro4.append("<ENDHMM>")
if line.find("STATE") == -1:
model4.write(line)
model4.write("<TRANSP> 3\n")
for i in range(0,3):
model4.write("0.000000e+00 1.000000e+00 0.000000e+00\n")
model4.write("<ENDHMM>\n")

macro3.close()
macro4.close()
model3.close()
model4.close()

try:
ret = subprocess.check_call("-T 2 -H %shmm4/macros -H %shmm4/models -M %shmm5 $ED_CMDFILE1 $WORD_LISTSP" %
(self.config.getSetting("hmmdir"),
self.config.getSetting("hmmdir"),
self.config.getSetting("hmmdir"),
hhed = [self.config.getSetting("binpath") + "HHEd",
'-T', "2",
'-H', self.config.getSetting("hmmdir") + "hmm4/macros",
'-H', self.config.getSetting("hmmdir") + "hmm4/models",
'-M', self.config.getSetting("hmmdir") + "hmm5",
self.config.getSetting("hedsilsp"),
self.config.getSetting("wordList")),
executable=self.config.getSetting("binpath") + "HHEd"
)
self.config.getSetting("wordList")
]
ret = subprocess.check_call(hhed)
if ret != 0:
print "Error, return codes wrong"
sys.exit(1)
@@ -289,23 +315,21 @@ class Htk:
sys.exit(1)
print "Corrected silence model"

for iteration in range(6, 8):
for iteration in range(5, 9):
print "Iteration %d" % iteration

try:
subprocess.check_call("-D -C %s -I %s -S %s -H %shmm%d/macros -H %shmm%d/models -M %shmm%d %s" %
(self.config.getSetting("configTrain"),
self.config.getSetting("wordLabelSP"),
self.config.getSetting("listTrain"),
self.config.getSetting("hmmdir"),
iteration - 1,
self.config.getSetting("hmmdir"),
iteration - 1,
self.config.getSetting("hmmdir"),
iteration,
self.config.getSetting("wordListSP")),
executable=self.config.getSetting("binpath") + "HERest"
)
herest = [self.config.getSetting("binpath") + "HERest",
'-D',
'-C', self.config.getSetting("configTrain"),
'-I', self.config.getSetting("wordLabelSP"),
'-S', self.config.getSetting("listTrain"),
'-H', "%shmm%d/macros" % (self.config.getSetting("hmmdir"), iteration - 1),
'-H', "%shmm%d/models" % (self.config.getSetting("hmmdir"), iteration - 1),
'-M', "%shmm%d" % (self.config.getSetting("hmmdir"), iteration),
self.config.getSetting("wordListSP")
]
subprocess.check_call(herest)
if ret != 0:
print "Error, return codes wrong"
sys.exit(1)
@@ -319,44 +343,53 @@ class Htk:
def testing(self):
print "Testing"

if os.path.isfile(self.config.getSetting("resultdir") + self.config.getSetting("project") + ".mlf"):
os.remove(self.config.getSetting("resultdir") + self.config.getSetting("project") + ".mlf")
if os.path.isfile(self.config.getSetting("resultdir") + self.config.getSetting("project") + ".res"):
os.remove(self.config.getSetting("resultdir") + self.config.getSetting("project") + ".res")

try:
ret = subprocess.check_call(
"-H %s -H %s -S %s -C %s -w %s -i %s.mlf %s %s %s" %
("%shmm%d/macros" % (self.config.getSetting("hmmdir"), self.config.getSetting("space_step")),
"%shmm%d/models" % (self.config.getSetting("hmmdir"), self.config.getSetting("space_step")),
self.config.getSetting("listTest"),
self.config.getSetting("configTest"),
self.config.getSetting("wordnet"),
self.config.getSetting("results"),
self.config.getSetting("flags"),
hvite = [self.config.getSetting("binpath") + "HVite",
'-H', "%shmm%d/macros" % (self.config.getSetting("hmmdir"), int(self.config.getSetting("space_step"))),
'-H', "%shmm%d/models" % (self.config.getSetting("hmmdir"), int(self.config.getSetting("space_step"))),
'-S', self.config.getSetting("listTest"),
'-C', self.config.getSetting("configTest"),
'-w', self.config.getSetting("wordnet"),
'-i', self.config.getSetting("resultdir") + self.config.getSetting("project") + ".mlf",
'-p', '10',
'-s', '0.0',
self.config.getSetting("worddict"),
self.config.getSetting("wordListSP")),
executable=self.config.getSetting("binpath") + "HVite"
)
self.config.getSetting("wordListSP")
]
ret = subprocess.check_call(hvite)
if ret != 0:
print "Error, return codes wrong"
sys.exit(1)
print "Error, return codes wrong"
sys.exit(1)
except CalledProcessError, e:
print e
sys.exit(1)

try:
subprocess.check_call(
'-e "???" sil -e "???" sp -I %s %s %s.mlf >> %s' %
(self.config.getSetting("wordLabelSP"),
hresult = [self.config.getSetting("binpath") + "HResults",
'-e', '\"???\"', 'sil',
'-e', '\"???\"', 'sp',
'-I', self.config.getSetting("wordLabelSP"),
self.config.getSetting("wordListSP"),
self.config.getSetting("results"),
self.config.getSetting("results")),
executable=self.config.getSetting("binpath") + "HResults"
)
self.config.getSetting("resultdir") + self.config.getSetting("project") + ".mlf"
]
result = open(self.config.getSetting("resultdir") + self.config.getSetting("project") + ".res", 'w')
ret = subprocess.check_call(hresult, stdout=result)
if ret != 0:
print "Error, return codes wrong"
sys.exit(1)
print "Error, return codes wrong"
sys.exit(1)
else:
result.close()
except CalledProcessError, e:
print e
sys.exit(1)

print "Testing finished"
print "Results can be found at %s" % self.config.getSetting("resultdir") + self.config.getSetting("project") + ".res"

def recognition(self):
pass


Loading…
Cancel
Save