2017-05-10 82 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