2017-05-10 100 views
1

我有一个项目,我试图模仿为snapchat的过滤系统。据推测,在点击窗口侧面的过滤器按钮之后,网络摄像头将显示过滤器是什么。然而,窗户刚结束冻结。如果我尝试单独实施过滤器,他们确实工作。但是当我尝试在这里实现它时,窗口会冻结。使用python在摄像头上切换图像过滤器opencv

下面的代码:(功能检测(),get_cam_frame(),show_frame()和phone_filter()是不是我的我只是取回他们从互联网上。)

# Import Libraries 
import numpy as np 
import Tkinter as tk 
import tkMessageBox 
import cv2 
import sys 
from PIL import Image, ImageTk 
from video import create_capture 


# Initialize Window 

root = tk.Tk() 
root.wm_title("Filter App") 
root.config(background="#000000") 
canvas = tk.Canvas(root, width=600, height=700) 
canvas.pack() 
canvas.grid(row=0, column=0, padx=5, pady=20) 

lmain = tk.Label(canvas) 
lmain.grid(row=0, column=0, padx=85, pady=119) 
cap = cv2.VideoCapture(0) 

def detect(img, cascade): 
    rects = cascade.detectMultiScale(img, scaleFactor=1.3, minNeighbors=4, minSize=(30, 30), flags=cv2.CASCADE_SCALE_IMAGE) 
    if len(rects) == 0: 
     return [] 
    rects[:, 2:] += rects[:, :2] 
    return rects 

def get_cam_frame(cam): 
    ret, img = cam.read() 
    # smaller frame size - things run a lot smoother than a full screen img 
    img = cv2.resize(img, (800, 470)) 
    return img 



def show_frame(): 
    _, frame = cap.read() 
    frame = cv2.flip(frame, 1) 
    cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA) 
    img = Image.fromarray(cv2image) 
    imgtk = ImageTk.PhotoImage(image=img) 
    lmain.imgtk = imgtk 
    lmain.configure(image=imgtk) 
    lmain.after(10, show_frame) 

sliderFrame = tk.Frame(root, width=500, height=50) 
sliderFrame.grid(row = 500, column=0, padx=10, pady=2) 
show_frame() 

def phone_filter(img): 
    show_frame() 
    print img 
    if img == "dog": 
     filter_img = cv2.imread("img/face/dogfilter.png", cv2.IMREAD_COLOR) 
    elif img == "dalmatian": 
     filter_img = cv2.imread("img/face/dalmatianfilter.png", cv2.IMREAD_COLOR) 
    elif img == "anime": 
     filter_img = cv2.imread("img/face/animefilter.png", cv2.IMREAD_COLOR) 
    elif img == "catears": 
     filter_img = cv2.imread("img/face/catearsfilter.png", cv2.IMREAD_COLOR) 
    elif img == "mustache": 
     filter_img = cv2.imread("img/face/mustachefilter.png", cv2.IMREAD_COLOR) 
    elif img == "pig": 
     filter_img = cv2.imread("img/face/pigfilter.png", cv2.IMREAD_COLOR) 
    elif img == "shaider": 
     filter_img = cv2.imread("img/face/shaiderfilter.png", cv2.IMREAD_COLOR) 
    elif img == "none": 
     filter_img = cv2.imread("img/Empty.png", cv2.IMREAD_COLOR) 
    else: 
     filter_img = cv2.imread("img/Empty.png", cv2.IMREAD_COLOR) 
    haar_classifier = "data/haarcascade_frontalface_default.xml" 
    # use the haar classifier for now, it seems to work a little bit better 
    cascade = cv2.CascadeClassifier(haar_classifier) 
    print cascade 
    while True: 
     print "." 
     cam = cv2.VideoCapture(0) 
     print cam 
     bw = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 
     bw = cv2.equalizeHist(bw) 
     rects = detect(bw, cascade) 
     final = img.copy() 
     # for x1, y1, x2, y2 in rects: 
     #  cv2.rectangle(img, (x1, y1), (x2, y2), (0,255,0), 2) 
     if len(rects) >= 1: 
      allFaces = rects 
      #rect = (ax1, ay1, ax2, ay2) 
      for index, (ax1, ay1, ax2, ay2) in enumerate(allFaces): 
       deltaY = abs(ay2) - abs(ay1) 
       stretchFactor = 0.2 
       stretchAmount = int(stretchFactor * deltaY) 
       ay2 = ay2 + stretchAmount 
       ay1 = ay1 - stretchAmount 
       height, width, _ = img.shape 
       if ax1 > stretchAmount and ax2 < width - stretchAmount and ay1 > stretchAmount and ay2 < height - stretchAmount: 
        face = img[ay1:ay2, ax1:ax2] 
        filter_scale = [] 
        if index % 2 == 0: 
         #dog_scale = cv2.resize(dog_img, (ax2 - ax1, ay2 - ay1)) 
         filter_scale = cv2.resize(filter_img, (ax2 - ax1, ay2 - ay1)) 
        else: 
         filter_scale = cv2.resize(filter_img, (ax2 - ax1, ay2 - ay1)) 
        # my_scaled = np.where(dog_scale == 0, face, dog_scale) 
        my_scaled = np.where(filter_scale == 0, face, filter_scale) 
        # faceB = cv2.resize(
        # img[by1:by2, bx1:bx2].copy(), (ax2 - ax1, ay2 - ay1)) 
        final[ay1:ay2, ax1:ax2] = my_scaled 
        #final[by1:by2, bx1:bx2] = faceA 
     cv2.imshow(final) 

def dogOp(): 
    phone_filter("dog") 
    # tkMessageBox.showinfo("Face Filter", "Dog Filter") 

def dalmatianOp(): 
    phone_filter("dalmatian") 
    # tkMessageBox.showinfo("Face Filter", "Dalmatian Filter") 

def animeOp(): 
    phone_filter("anime") 
    # tkMessageBox.showinfo("Face Filter", "Anime Filter") 

def catearsOp(): 
    phone_filter("catears") 
    # tkMessageBox.showinfo("Face Filter", "Cat Ears Filter") 

def mustacheOp(): 
    phone_filter("mustache") 
    # tkMessageBox.showinfo("Face Filter", "Mustache Filter") 

def pigOp(): 
    phone_filter("pig") 
    # tkMessageBox.showinfo("Face Filter", "Pig Filter") 

def shaiderOp(): 
    phone_filter("shaider") 
    # tkMessageBox.showinfo("Face Filter", "Shaider Pulis Pangkalawakan") 

initializing background 

image = Image.open('img/phone_bg.png') 
image = image.resize((820, 700), Image.ANTIALIAS) 
tk_img = ImageTk.PhotoImage(image) 
canvas.create_image(400, 360, image=tk_img) 

initializing face filters 

dogfilter = Image.open("img/face/dogfilter.png") 
dogfilter = dogfilter.resize((50, 50), Image.ANTIALIAS) 
dog = ImageTk.PhotoImage(dogfilter) 

dalmatianfilter = Image.open("img/face/dalmatianfilter.png") 
dalmatianfilter = dalmatianfilter.resize((50, 50), Image.ANTIALIAS) 
dalmatian = ImageTk.PhotoImage(dalmatianfilter) 

animefilter = Image.open("img/face/animefilter.png") 
animefilter = animefilter.resize((50, 50), Image.ANTIALIAS) 
anime = ImageTk.PhotoImage(animefilter) 

catearsfilter = Image.open("img/face/catearsfilter.png") 
catearsfilter = catearsfilter.resize((50, 50), Image.ANTIALIAS) 
catears = ImageTk.PhotoImage(catearsfilter) 

mustachefilter = Image.open("img/face/mustachefilter.png") 
mustachefilter = mustachefilter.resize((50, 50), Image.ANTIALIAS) 
mustache = ImageTk.PhotoImage(mustachefilter) 

pigfilter = Image.open("img/face/pigfilter.png") 
pigfilter = pigfilter.resize((50, 50), Image.ANTIALIAS) 
pig = ImageTk.PhotoImage(pigfilter) 

shaiderfilter = Image.open("img/face/shaiderfilter.png") 
shaiderfilter = shaiderfilter.resize((50, 50), Image.ANTIALIAS) 
shaider = ImageTk.PhotoImage(shaiderfilter) 


face filter buttons 

dogbtn = tk.Button(root, width=30, height=30, image = dog, command=dogOp) 
dogbtn_window = canvas.create_window(100,150, anchor='nw', window=dogbtn) 

dalmatianbtn = tk.Button(root, width=30, height=30, image = dalmatian, command=dalmatianOp) 
dalmatianbtn_window = canvas.create_window(100,190, anchor='nw', window=dalmatianbtn) 

animebtn = tk.Button(root, width=30, height=30, image = anime, command=animeOp) 
animebtn_window = canvas.create_window(100,230, anchor='nw', window=animebtn) 

catearsbtn = tk.Button(root, width=30, height=30, image = catears, command=catearsOp) 
catearsbtn_window = canvas.create_window(100,270, anchor='nw', window=catearsbtn) 

mustachebtn = tk.Button(root, width=30, height=30, image = mustache, command=mustacheOp) 
mustachebtn_window = canvas.create_window(100,310, anchor='nw', window=mustachebtn) 

pigbtn = tk.Button(root, width=30, height=30, image = pig, command=pigOp) 
pigbtn_window = canvas.create_window(100,350, anchor='nw', window=pigbtn) 

shaiderbtn = tk.Button(root, width=30, height=30, image = shaider, command=shaiderOp) 
shaiderbtn_window = canvas.create_window(100,390, anchor='nw', window=shaiderbtn) 

quit_button = tk.Button(root, text = "X", command = root.quit, anchor = 'w', 
        width = 2, bg="red") 
quit_button_window = canvas.create_window(680,120, anchor='nw', window=quit_button) 


root.mainloop() 

回答

1

camerafeed冻结时您按下按钮是因为您的phone_filter()功能永不结束。事实上,它包含一个while True循环。

此外,在此功能中,您尝试重新打开VideoCapture(0),因为您已在初始化步骤(cap = cv2.VideoCapture(0))中打开它,所以错误是错误的。改为使用cap变量。

两行波纹管,与bw = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY),你尝试转换img这是你的输入字符串


无论如何,我不认为你的代码结构是正确的,根据你想要实现的。你应该做一下这种味道:

里面一个while True循环:

  • 检索相机的框架。
  • 然后,在该帧上调用脸部识别函数,该函数将返回检测到的脸部的位置。
  • 绘制将选定的过滤器放在检测到的面部上。
  • 最后,显示得到的图像。

绑定到按钮的功能应该只能改变一个变量(你可以调用selected_filter)。然后,在while True循环中,您将读取此变量以绘制正确的过滤器。

+0

啊,我想我明白了。谢谢! – xjm