# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# + slideshow={"slide_type": "subslide"}
class Recognizer:
    
    def __init__(self,socket):
        self.socket = socket;
        self.stop = False;
    
    def disconnect(self):
        self.socket.disconnect()
   


# + slideshow={"slide_type": "subslide"}
     
    def train(self):
            # BASE_DIR = os.path.dirname(os.path.abspath(__file__))
        image_dir = os.path.join("./", "images")

        # face_cascade = cv2.CascadeClassifier('cascades/data/haarcascade_profileface.xml')

        face_cascade = cv2.CascadeClassifier('cascades/data/haarcascade_frontalface_alt.xml')

        recognizer = cv2.face.LBPHFaceRecognizer_create()
        
        current_id = 0
        label_ids = {}
        y_labels = []
        x_train = []
        x = True;
        for root, dirs, files in os.walk(image_dir):
        # Walking through the dir images recursively 
            print("root:",root,end='\n')
            print("DIR:",len(dirs),end='\n')
            print("Files:",len(files))
        #   For every file in the current walking dir we check if it is png,  jpg 
        #   and start adding to the lable_id map
        #   sample {'chakri': 0, 'puneeth': 1} 
            print("files length",len(files))
            t_detected_faces = 0
            count  = 0
            
            for file in files:
                if file.endswith("png") or file.endswith("jpg") or file.endswith("JPG"):
                    #print("file name ",file)
                    path = os.path.join(root, file)
                    label = os.path.basename(root).replace(" ", "-").lower()

                    if not label in label_ids:
                        label_ids[label] = current_id
                        current_id = current_id+1
                    # take the current id of the person
                    
                    #print("current_id",current_id,"label_ids",label_ids)
                    id_ = label_ids[label]
                    print(id_,end="_*_")
                    # Convert the image into graysacle and resize to 500x500 
                    pil_image = Image.open(path).convert("L") # grayscale
                    size = (300,300)
                    final_image = pil_image.resize(size, Image.ANTIALIAS)
                    
        # the final image is converted into graysacle and resized to 500x500 
        # now converted into nummpy array for detecting faces in that image
                    image_array = np.array(final_image, "uint8")

        # after converting the image into nummpy array for analytics we take that array and 
        # dectect all the faces in the image using Haar Cascade 
                   
                    faces = face_cascade.detectMultiScale(image_array, minNeighbors=3)
        # after detection of the faces 
                    t_detected_faces+= len(faces)
                    count+=1
                    
                    for (x,y,w,h) in faces:
                        roi = image_array[y:y+h, x:x+w]
                        x_train.append(roi)
                        y_labels.append(id_)
                        
            print("detected faces are ",t_detected_faces)
            t_detected_faces=0
            
        
        with open("pickles/face-labels.pickle", 'wb') as f:
            pickle.dump(label_ids, f)
        
        recognizer.train(x_train, np.array(y_labels))
        recognizer.save("recognizers/face-trainner.yml")

        print("COMPLETED TRAINING saved to recognizers/face-trainner.yml")
        
      

# + slideshow={"slide_type": "subslide"}
  
    def recognize(self):
        print("recognize")
        face_cascade = cv2.CascadeClassifier('cascades/data/haarcascade_frontalface_alt.xml')

        recognizer = cv2.face.LBPHFaceRecognizer_create()
        recognizer.read("./recognizers/face-trainner.yml")

        labels = {"person_name": 1}
        with open("pickles/face-labels.pickle", 'rb') as f:
            og_labels = pickle.load(f)
            labels = {v:k for k,v in og_labels.items()}

        cap = cv2.VideoCapture(0)

#         cap1 = cv2.VideoCapture(1)

#         cap = cv2.VideoCapture("rtsp://192.168.0.5:8080/h264_pcm.sdp")

        while(True):
            if self.stop:
                self.socket.disconnect()
                break
            # Capture frame-by-frame
            ret, frame = cap.read()
#             faces = face_cascade.detectMultiScale(gray, scaleFactor=1.5, minNeighbors=5)
            
            gray  = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
            faces = face_cascade.detectMultiScale(gray, scaleFactor=1.5, minNeighbors=3)
            
            for (x, y, w, h) in faces:
                roi_gray = gray[y:y+h, x:x+w] #(ycord_start, ycord_end)
                roi_color = frame[y:y+h, x:x+w]

                # recognize? we are using har-calsifiers, But using deep learned model 
                # predict keras tensorflow pytorch scikit learn can be used in future work of this system...
                
                id_, conf = recognizer.predict(roi_gray)
                                 
                # with a confidence level between 65% to 100% our system starts pushes the recognized faces to
                # Web Application using websockets
                if conf>=65 and conf <= 100:
                    sio.emit('push_faces', {'location': random.choice(locations),'name':labels[id_]}, namespace='/facemap')                    

                    font = cv2.FONT_HERSHEY_SIMPLEX
                    name = labels[id_]
                    color = (255, 255, 255)
                    stroke = 2
                    cv2.putText(frame, name, (x,y), font, 1, color, stroke, cv2.LINE_AA)

                img_item = "7.png"
#                 cv2.imwrite(img_item, roi_color)

                color = (0, 255, 0) #BGR 0-255 
                stroke = 2
                end_cord_x = x + w
                end_cord_y = y + h
                cv2.rectangle(frame, (x, y), (end_cord_x, end_cord_y), color, stroke)
                
            # Display the resulting frame
            frame = cv2.resize(frame, (640, 480), interpolation = cv2.INTER_LINEAR)
            cv2.imshow('frame',frame)
            if cv2.waitKey(20) & 0xFF == ord('q'):
#                 self.socket.disconnect()
                break

        # When everything done, release resources and capture.

        cap.release()
        cv2.destroyAllWindows()
    
        

StarcoderdataJupyterScriptsDedupFiltered