0

I am trying to save a picture to a folder in a directory. I have a button in tkinter that has a command that takes a picture of a camera output. I need to be able to save that picture in a specific file so that my facial recognition can train on them. I cant figure out how to have the image save to the folder. Any help is greatly appreciated.

CODE:

    from tkinter import *
from tkinter import filedialog
import cv2 as cv
import sys
from PIL import Image, ImageTk
import numpy as np
from PIL import Image, ImageTk
import os
import datetime
from socket import *

# stuff
root = Tk()
root.title('Real-Time Facial Detection/Recognition')
root.geometry('1400x700')
root.configure(bg='gray15')
root.resizable(0, 0)
global img
global test123

# button functions

def detect_on():
    global img
    global test123
    test123 = 2
    while test123 == 2:
        haar_cascade = cv.CascadeClassifier('haar_face.xml')
        img = cam.read()[1]
        faces_rect = haar_cascade.detectMultiScale(img, scaleFactor=1.1, minNeighbors=10)

        for (x,y,w,h) in faces_rect:
            img = cv.rectangle(img, (x,y), (x+w,y+h), (0,255,0), thickness=2)

        img = cv.cvtColor(img, cv.COLOR_BGR2RGB)
        img = ImageTk.PhotoImage(Image.fromarray(img))
        L1['image'] = img
        root.update()

def detect_off():
    global img
    global test123
    test123 = 1
    img = cam.read()[1]
    img = cv.cvtColor(img, cv.COLOR_BGR2RGB)
    img = ImageTk.PhotoImage(Image.fromarray(img))
    L1['image'] = img
    root.update()

def recog_on():
    global img
    global test123
    global name_gotten
    name_gotten = name_box.get()
    test123 = 3
    while test123 == 3:
        haar_cascade = cv.CascadeClassifier('haar_face.xml')

        people = ['Henry']

        face_recognizer = cv.face.LBPHFaceRecognizer_create()
        face_recognizer.read('face-trained2.yml')

        img = cam.read()[1]
        gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

        # detect the face
        if True:
            faces_rect = haar_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=10)

            for (x,y,w,h) in faces_rect:
                faces_roi = gray[y:y+h, x:x+w]

                label, confidence = face_recognizer.predict(faces_roi)
                print(f'Label = {people[label]} with a confidence of {confidence}')

                cv.putText(img, str(people[label]), (x+2,y+h-5), cv.FONT_HERSHEY_SIMPLEX, 0.8, (0,0,255), thickness=2)
                cv.rectangle(img, (x-5,y-5), (x+w,y+h),(0,255,0), thickness=2)

            img = cv.cvtColor(img, cv.COLOR_BGR2RGB)
            img = ImageTk.PhotoImage(Image.fromarray(img))
            L1['image'] = img
            root.update()

def recog_off():
    global img
    global test123
    test123 = 1
    img = cam.read()[1]
    img = cv.cvtColor(img, cv.COLOR_BGR2RGB)
    img = ImageTk.PhotoImage(Image.fromarray(img))
    L1['image'] = img
    root.update()

def take_picture():
    name_gotten = name_box.get()
    directory = f'{name_gotten}'
    parent_dir = 'C:/OCV/real-time-FR'
    path = os.path.join(parent_dir, directory)
    os.mkdir(path)




    image1 = Image.fromarray(img1)
    time = str(datetime.datetime.now().today())
    time2 = time.replace(':',' ') + '.jpg'
    image1.save(f'{path}', time2)

def name_get():
    global name_gotten
    name_gotten = name_box.get()
    print(name_gotten)
    print(type(name_gotten))

# buttons
Face_detect_on = Button(root, text='Start FD', padx=75, pady=25, bg='black', fg='white', font=('Calibri', 30, 'bold'), borderwidth=0, command=detect_on)
Face_detect_on.place(x=35, y=180)

Face_detect_off = Button(root, text='Stop FD', padx=75, pady=25, bg='black', fg='white', font=('Calibri', 30, 'bold'), borderwidth=0, command=detect_off)
Face_detect_off.place(x=35, y=380)

# FR buttons
Face_recog_on = Button(root, text='Start FR', padx=75, pady=25, bg='black', fg='white', font=('Calibri', 30, 'bold'), borderwidth=0, command=recog_on)
Face_recog_on.place(x=1060, y=180)

Face_recog_off = Button(root, text='Stop FR', padx=75, pady=25, bg='black', fg='white', font=('Calibri', 30, 'bold'), borderwidth=0, command=recog_off)
Face_recog_off.place(x=1060, y=380)

picture = Button(root, text='Picture', padx=50, pady=25, bg='black', fg='white', font=('Calibri', 15, 'bold'), borderwidth=0, command=take_picture)
picture.place(x=1060, y=430)

name_text = Label(root, text='Name:', bg='black', fg='white', font=('Calibri', 11, 'bold'))
name_text.place(x=1055, y=332)

name_enter = Button(root, text='Enter', bg='black', fg='white', font=('Calibri', 11, 'bold'), borderwidth=0, command=name_get)
name_enter.place(x=1276, y=330)

name_box = Entry(root, bg='black', width=17, fg='white', font=('Calibri', 15, 'bold'), borderwidth=0)
name_box.place(x=1103, y=331)

Label(root, text='Camera Output', font=('Calibri', 50, 'bold'), bg='gray15', fg='white').pack()
f1 = LabelFrame(root, bg='white')
f1.pack()
L1 = Label(f1, bg='white')
L1.pack()
test123 = 1
cam = cv.VideoCapture(0)

while test123 == 1:
    global img
    img = cam.read()[1]
    img1 = cv.cvtColor(img, cv.COLOR_BGR2RGB)
    img = ImageTk.PhotoImage(Image.fromarray(img1))
    L1['image'] = img
    root.update()

root.mainloop()

I am having with the last couple lines. Plz help ERROR:

    Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Python37\lib\tkinter\__init__.py", line 1884, in __call__
    return self.func(*args)
  File "C:\OCV\real-time FR\testforrealtimefd.py", line 108, in take_picture
    image1.save(time2, f'{path}')
  File "C:\Python37\lib\site-packages\PIL\Image.py", line 2153, in save
    save_handler = SAVE[format.upper()]
KeyError: 'C:/OCV/REAL-TIME FR\\TEST #1'
hlcodes01
  • 31
  • 6
  • Spaces are terrible for paths. Either get rid of the spaces in the names of folders and files, or you have to play around with how to include spaces in your path in Windows. – wxz May 06 '21 at 01:22
  • @wxz thanks for the suggestion. I changed every path to have no spaces and made new files with no spaces to put them in. Sadly I am still getting the same error. Any other ideas? – hlcodes01 May 06 '21 at 01:28
  • Can you update the post with the new code and new error message? – wxz May 06 '21 at 01:29
  • 3
    Also why does your code have this `image1.save(f'{path}', time)` but your error shows this `image1.save(time2, f'{path}')`? – wxz May 06 '21 at 01:34
  • @wxz ah shit i was seeing what would happen if i reversed them and forgot to put the other error message. my bad. the error is supposed to be '''image1.save(f'{path', time)''' ill edit the post now with new code – hlcodes01 May 06 '21 at 01:36
  • What does `print(path,time2)` give. AFAIK, `save(filepath,format)` accepts the file path and the format(not necessary) needed(in order). Are you doing it the same way? – Delrius Euphoria May 06 '21 at 01:37
  • You're also combining Linux paths with Windows paths. Shouldn't `C:/OCV/real-time-FR` be `C:\OCV\real-time-FR` in Windows? – wxz May 06 '21 at 01:38
  • @wxz Won't both paths be the same? – Delrius Euphoria May 06 '21 at 01:39
  • @CoolCloud as far as I know, Windows won't accept Linux paths with `/` and Linux won't accept windows paths with `\\` – wxz May 06 '21 at 01:40
  • @wxz Windows paths are not '\\', it is either '/' or '\', AFAIK. – Delrius Euphoria May 06 '21 at 01:41
  • @CoolCloud Hmm, I think this is a newer Windows feature, it never used to accept `/` in paths. – wxz May 06 '21 at 01:43
  • i tried to print path and time2 and it wouldnt let me cause of the error. ive always used / when using paths in windows and its worked. – hlcodes01 May 06 '21 at 01:44
  • 1
    About the history of Windows not accepting `/` for filepaths, but newer windows accepting it. https://stackoverflow.com/q/38428561/13020139 – wxz May 06 '21 at 01:47
  • If you are not able to `print()`, how will the code get executed? Place it somewhere the code has access to. At least what do you expect `path` and `rime2`to be? – Delrius Euphoria May 06 '21 at 01:47
  • i can i save the image to the directory that i am currently in by doing `image1.save(time)` but i cant get it to save in a different directory called `path` that is what im trying to explain – hlcodes01 May 06 '21 at 01:52
  • 1
    If you can save it without the path, then it's specifically a path issue. Take out everything that isn't essential and focus on figuring out what the path is that you're creating. I agree with @CoolCloud, you shouldn't have a path with `\\\` double backslashes. – wxz May 06 '21 at 01:55
  • 1
    @wxz LETS GOOOO I GOT IT. this is all i had to do. `def take_picture(): name_gotten = name_box.get() directory = f'{name_gotten}' parent_dir = 'C:/OCV/real-time-FR/' path = os.path.join(parent_dir, directory) os.mkdir(path) image1 = Image.fromarray(img1) time = str(datetime.datetime.now().today()).replace(':',' ') + '.jpg' print(time) print(path) test145 = os.path.join(path, time) print(test145) image1.save(test145)` – hlcodes01 May 06 '21 at 02:00
  • dam didnt mean to send it like that – hlcodes01 May 06 '21 at 02:00
  • i running on 2 hours of sleep so im kinda dumb. thank you so much for the help – hlcodes01 May 06 '21 at 02:01
  • Meaning the only change was adding `/` to the end of the parent_dir? – wxz May 06 '21 at 02:02
  • yes and adding some other things – hlcodes01 May 06 '21 at 02:03
  • 1
    Nice, congrats! – wxz May 06 '21 at 02:04

0 Answers0