Python / OpenCV从网络摄像头捕获图像不起作用

时间:2014-03-09 04:09:14

标签: python opencv python-imaging-library webcam

我创建了原始的python脚本来处理已保存的图像。我现在想要它捕获图像并裁剪它。我有一个工作的网络摄像头部分和工作作物部分,但我无法将它们组合起来并制作它们。我已经包含了组合代码。目前,它仍将裁剪已保存的图像,网络摄像头的GUI会显示一秒钟但不显示任何内容(灰色屏幕)。任何人都可以帮助我吗?

import cv
import cv2
import numpy
import Image
import glob
import os

# Static
faceCascade = cv.Load('haarcascade_frontalface_alt.xml')
padding = -1


inputimg = raw_input('Please enter the entire path to the image folder:')
outputimg = raw_input('Please enter the entire path to the output folder:')
if not os.path.exists(outputimg):
    os.makedirs(outputimg)

while (padding < 0):
    padding = int(raw_input('Enter crop padding:'))

capture = cv2.VideoCapture(0)
cv2.namedWindow("Face Crop")
if capture.isOpened():
    frame = capture.read()

def DetectFace(image, faceCascade, returnImage=False):

    #variables    
    min_size = (50,50)
    haar_scale = 1.1
    min_neighbors = 3
    haar_flags = 0
    DOWNSCALE = 4

    # Equalize the histogram
    cv.EqualizeHist(image, image)

    # Detect the faces
    faces = cv.HaarDetectObjects(image, faceCascade, cv.CreateMemStorage(0),haar_scale, min_neighbors, haar_flags, min_size)

    # If faces are found
    if faces and returnImage:
        for ((x, y, w, h), n) in faces:
            # Convert bounding box to two CvPoints
            pt1 = (int(x), int(y))
            pt2 = (int(x + w), int(y + h))
            cv.Rectangle(image, pt1, pt2, cv.RGB(255, 0, 0), 5, 8, 0)

                        # Start video frame
            minisize = (frame.shape[1]/DOWNSCALE,frame.shape[0]/DOWNSCALE)
            miniframe = cv2.resize(frame, minisize)
            faceCam = classifier.detectMultiScale(miniframe)
            for f in faceCam:
                x, y, w, h = [ v*DOWNSCALE for v in f ]
                cv2.rectangle(frame, (x,y), (x+w,y+h), (0,0,255))

            cv2.putText(frame, "Press ESC to close.", (5, 25),
            cv2.FONT_HERSHEY_SIMPLEX, 1.0, (255,255,255))
            cv2.imshow("preview", frame)

            # get next frame
            frame = capture.read()         
            raw_input('Pause for testing')
            key = cv2.waitKey(20)
            if key in [27, ord('Q'), ord('q')]: # exit on ESC
                break

    if returnImage:
        return image
    else:
        return faces

def pil2cvGrey(pil_im):
    pil_im = pil_im.convert('L')
    cv_im = cv.CreateImageHeader(pil_im.size, cv.IPL_DEPTH_8U, 1)
    cv.SetData(cv_im, pil_im.tostring(), pil_im.size[0]  )
    return cv_im

def imgCrop(image, cropBox, boxScale=1):
    # Crop a PIL image with the provided box [x(left), y(upper), w(width), h(height)]

    # Calculate scale factors
    xPadding=max(cropBox[2]*(boxScale-1),int(padding))
    yPadding=max(cropBox[3]*(boxScale-1),int(padding))

    # Convert cv box to PIL box [left, upper, right, lower]
    PIL_box=[cropBox[0]-xPadding, cropBox[1]-yPadding, cropBox[0]+cropBox[2]+xPadding, cropBox[1]+cropBox[3]+yPadding]

    return image.crop(PIL_box)

def Crop(imagePattern,boxScale=1):
    imgList=glob.glob(imagePattern)
    if len(imgList)<=0:
        return
    else:
            for img in imgList:
                    pil_im=Image.open(img)
                    cv_im=pil2cvGrey(pil_im)
                    faces=DetectFace(cv_im,faceCascade)
                    if faces:
                            n=1
                            for face in faces:
                                    croppedImage=imgCrop(pil_im, face[0],boxScale=boxScale)
                                    fname,ext=os.path.splitext(img)
                                    fname = os.path.basename(fname)
                                    croppedImage.save(outputimg + '\\' + fname + ' -c' + ext)
                                    n+=1
                            print 'Cropping:', fname
                    else:
                            print 'No faces found:', img

# Crop all images in a folder
Crop(inputimg + '\*.png', boxScale=1)
Crop(inputimg + '\*.jpg', boxScale=1)

此外,如果有人有任何代码改进,请告诉我,因为我不熟悉Python。

1 个答案:

答案 0 :(得分:0)

我能够通过重新编写逻辑和代码流来解决这个问题。更新了以下代码和github,https://github.com/aDroidman/EyeonYou

import cv
import cv2
import numpy
import Image
import glob
import os

# Static
faceCascade = cv.Load('haarcascade_frontalface_alt.xml')
padding = -1
boxScale = 1
# Needed for webcam CV2 section
HaarXML = "haarcascade_frontalface_alt.xml"
classifier = cv2.CascadeClassifier(HaarXML)
downScale = 4
webcam = cv2.VideoCapture(0)

def DetectFace(image, faceCascade, returnImage=False):

    #variables    
    min_size = (50,50)
    haar_scale = 1.1
    min_neighbors = 3
    haar_flags = 0
    DOWNSCALE = 4

    # Equalize the histogram
    cv.EqualizeHist(image, image)

    # Detect the faces
    faces = cv.HaarDetectObjects(image, faceCascade, cv.CreateMemStorage(0),haar_scale, min_neighbors, haar_flags, min_size)

    # If faces are found
    if faces and returnImage:
        for ((x, y, w, h), n) in faces:
            # Convert bounding box to two CvPoints
            pt1 = (int(x), int(y))
            pt2 = (int(x + w), int(y + h))
            cv.Rectangle(image, pt1, pt2, cv.RGB(255, 0, 0), 5, 8, 0)

    if returnImage:
        return image
    else:
        return faces

def pil2cvGrey(pil_im):
    pil_im = pil_im.convert('L')
    cv_im = cv.CreateImageHeader(pil_im.size, cv.IPL_DEPTH_8U, 1)
    cv.SetData(cv_im, pil_im.tostring(), pil_im.size[0]  )
    return cv_im

def imgCrop(image, cropBox, boxScale=1):
    # Crop a PIL image with the provided box [x(left), y(upper), w(width), h(height)]

    # Calculate scale factors
    xPadding=max(cropBox[2]*(boxScale-1),int(padding))
    yPadding=max(cropBox[3]*(boxScale-1),int(padding))

    # Convert cv box to PIL box [left, upper, right, lower]
    PIL_box=[cropBox[0]-xPadding, cropBox[1]-yPadding, cropBox[0]+cropBox[2]+xPadding, cropBox[1]+cropBox[3]+yPadding]

    return image.crop(PIL_box)

def Crop(imagePattern,boxScale,outputimg):
    imgList=glob.glob(imagePattern)
    if len(imgList)<=0:
        return
    else:
        for img in imgList:
            pil_im=Image.open(img)
            cv_im=pil2cvGrey(pil_im)
            faces=DetectFace(cv_im,faceCascade)
            if faces:
                n=1
                for face in faces:
                    croppedImage=imgCrop(pil_im, face[0],boxScale=boxScale)
                    fname,ext=os.path.splitext(img)
                    fname = os.path.basename(fname)
                    croppedImage.save(outputimg + '\\' + fname + ' -c' + ext)
                    n+=1
        print 'Cropping:', fname
        else:
                print 'No faces found:', img

def CropSetup(padding, boxScale):
        inputimg = raw_input('Please enter the entire path to the image folder:')
        outputimg = raw_input('Please enter the entire path to the output folder:')

        # Create output folder if missing
        if not os.path.exists(outputimg):
                os.makedirs(outputimg)

        # Get padding for crop
        while (padding < 0):
                padding = int(raw_input('Enter crop padding:'))

        # Crop images
        Crop(inputimg + '\*.png', boxScale, outputimg)
        Crop(inputimg + '\*.jpg', boxScale, outputimg)

print 'Option 1: Detect image from Webcam'
print 'Option 2: Crop saved images'
option = int(raw_input('Please enter 1 or 2: '))

def Webcam(webcam, classifier, downScale):

        if webcam.isOpened():
                rval, frame = webcam.read()
        else:
                rval = False

        while rval:
                # detect faces and draw bounding boxes
                minisize = (frame.shape[1]/downScale,frame.shape[0]/downScale)
                miniframe = cv2.resize(frame, minisize)
                faces = classifier.detectMultiScale(miniframe)
                for f in faces:
                        x, y, w, h = [ v*downScale for v in f ]
                        cv2.rectangle(frame, (x,y), (x+w,y+h), (0,0,255))

                cv2.putText(frame, "Press ESC to close.", (5, 25),
                                        cv2.FONT_HERSHEY_SIMPLEX, 1.0, (255,255,255))
                cv2.imshow("Face Crop", frame)

                # get next frame
                rval, frame = webcam.read()

                key = cv2.waitKey(10)
                if key in [27, ord('Q'), ord('q')]: # exit on ESC
                        break   





if option == 1:
        Webcam(webcam, classifier, downScale)
elif option == 2:
        CropSetup(padding, boxScale)
else:
        print 'Not a valid input'