2017-05-10 4 views
1

나는 snapchat에 대한 필터링 시스템을 모방하려는 프로젝트를 가지고 있습니다. 윈도우의 측면에있는 필터 버튼을 클릭하면 필터가 무엇이든간에 웹캠에 표시됩니다. 그러나 창문이 얼어 붙어 버립니다. 필터를 개별적으로 구현하려고하면 실제로 작동합니다. 하지만 여기에 구현하려고하면 창이 멈 춥니 다. 여기 pyc 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

관련 문제