Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Face Detection using Web(Html css) and Python

I am pretty new to web technologies. I am making a chatbot with face detection integrated although I know how to work with python and its libs with other works, i am facing issue while loading the pages

Requirement: Face detection on web, for now, we can refer to it as localhost. So for this, I have OpenCV Harcascade file ready and the detection part is also happening. sample below image and code for web and pyton.

Error: By clicking on Weblink python flask navigation are going to a pending state.

enter image description here

As you can see here Face detection is working but when i am clicking on Collect my Image link its loading forever. Please help on this.

Html Code:

<!DOCTYPE html>
<html>
<head>
    <title>Video Stream</title>
    <!-- <link rel="stylesheet" href="templates/css/main.css"> -->
</head>
<body>

<h2>ChatBot</h2>
<p >{{ alert }}</p>

<div class="container">
  <img class="bottomright" class="center" style="width: 500px;height: 300px;"src="{{ url_for('video_feed') }}">
  <div class="col-md-6 col-sm-6 col-xs-6"> <a href="/exec2" class="btn btn-sm animated-button victoria-one">Collect My Images</a> </div>
</div>  
</body>
</html>

Python Main.py class:-

from flask import Flask, render_template, Response
from camera import VideoCamera
# import create_data

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

def gen(camera):
    while True:
        frame = camera.get_frame()
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')

@app.route('/video_feed')
def video_feed():
    return Response(gen(VideoCamera()),
                    mimetype='multipart/x-mixed-replace; boundary=frame')

@app.route('/exec2')
def parse1():
#     response_data_collection = 
    print("Here")
    VideoCamera().save_to_dataset()
#     if response_data_collection != None:
#         print("Done with Collecting Data")
#     else:    
#         response_data_collection = "Couldn't able to create data files"
#     return render_template('index.html', alert='Done with Collecting Data')

@app.route('/training')
def training():
    return render_template('training.html', alert='Not Yet Trained')

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)

Need help correcting parse1() class.

VideoCamera.py:- (Where all face detection related py code lies)

import cv2
import os
import time
face_cascade=cv2.CascadeClassifier("haarcascade_frontalface_alt2.xml")
ds_factor=0.6
datasets = 'datasets'

class VideoCamera(object):
    def __init__(self):
        self.video = cv2.VideoCapture(0)

    def __del__(self):
        self.video.release()

    def get_frame(self):
        success, image = self.video.read()
        image=cv2.resize(image,None,fx=ds_factor,fy=ds_factor,interpolation=cv2.INTER_AREA)
        gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
        face_rects=face_cascade.detectMultiScale(gray,1.3,5)
        for (x,y,w,h) in face_rects:
            cv2.rectangle(image,(x,y),(x+w,y+h),(0,255,0),2)
            break
        ret, jpeg = cv2.imencode('.jpg', image)
        return jpeg.tobytes()

    def save_to_dataset(self):
        return_data = ''
        sub_data = 'Tapan_1'
        (width, height) = (130, 100) 


        count = 1
        path = os.path.join(datasets, sub_data)
        if not os.path.isdir(path):
            os.mkdir(path)
            while count < 20: 
                success, image = self.video.read()
                image=cv2.resize(image,None,fx=ds_factor,fy=ds_factor,interpolation=cv2.INTER_AREA)
                gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
                face_rects=face_cascade.detectMultiScale(gray,1.3,5)
                for (x,y,w,h) in face_rects:
                    cv2.rectangle(image,(x,y),(x+w,y+h),(0,255,0),2)
                    face = gray[y:y + h, x:x + w]
                    face_resize = cv2.resize(face, (width, height))
                    cv2.imwrite('%s/%s.png' % (path,count), face_resize)
                count += 1

                if count == 20:
                    return_data = '20 image captured.'
                    # cv2.waitKey(1)
                    # self.video.release()
                    # cv2.destroyAllWindow()
                    # time.sleep(1)

                    break
        else:
            return_data = "Data already Thr"

        return return_data

So when I am clicking on Collect my Images the network going to a pending state.

here are some screenshots.

enter image description here

enter image description here

Here you can see the Here message is printing but not navigating to exec2 page, hence this is unable to take pictures. if you are thinking might be some issue with capturing images I can surely tell there is no issue with that. I have tested with one direct link where pictures are taking so there is no problem in Videocamera python code. Something going wrong with python calling the functions.

If you can help me with the same code or if you have any reference code from your understanding which might work in this scenario please let me know Thanks.

like image 842
Tapan Kumar Patro Avatar asked Jun 08 '20 06:06

Tapan Kumar Patro


People also ask

Can Python be used for facial recognition?

OpenCV. OpenCV is the most popular library for computer vision. Originally written in C/C++, it now provides bindings for Python. OpenCV uses machine learning algorithms to search for faces within a picture.

How Numpy is used in face recognition?

NumPy is the fundamental package for scientific computing in Python which provides a multidimensional array object other mathematical operations can be performed using this but simply speaking we just need it to convert our images into some form of an array so that we can store the model that has been trained.


2 Answers

There should be exception somewhere in save_to_dataset. More debugging is needed to find the source of the exception. Since there isn't much error checking in the function, one way you could start debugging is by with putting the call in a try except block, something like:

def parse1():
#     response_data_collection = 
    #print("Here")
    try:
        VideoCamera().save_to_dataset()
    except Exception as e:
        exc = 'Exc Type: {}'.format(type(e))
        exc += 'Exc Args: {}'.format(e.args)
        print(exc)
        raise # Raise the original exception

If there is an exception, this will print the exception type and message of the exception in the logs that you are referring (instead of "Here").

Note that this is intended only for debugging. Ideally, in this scenario, you should be adding more error checking in save_to_dataset function.

like image 133
singhatulks Avatar answered Oct 25 '22 15:10

singhatulks


tl;dr: The problems: Your self.video = cv2.VideoCapture(0) run twice.

If you don't want to use the global variable, you can fix the instance.

class VideoCamera:
    def __new__(cls, *args, **kwargs):
        if getattr(cls, '_instance', False):
            return cls._instance

        cls._instance = super().__new__(cls, *args, **kwargs)
        return cls._instance

    def __init__(self):
        if not hasattr(self, 'video'):
            self.video = cv2.VideoCapture(0)

Full code

And I do some modifications to let the code is more clear? The full code sees the following:

# camera.py
import cv2
import os
import time
from flask import Response
from pathlib import Path
import uuid
from contextlib import contextmanager
from typing import Callable

# https://github.com/opencv/opencv/blob/master/data/haarcascades/haarcascade_frontalface_alt2.xml
face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_alt2.xml")
ds_factor = 0.6
datasets = 'datasets'


class VideoCamera:
    def __new__(cls, *args, **kwargs):
        if getattr(cls, '_instance', False):
            return cls._instance

        cls._instance = super().__new__(cls, *args, **kwargs)
        return cls._instance

    def __init__(self):
        if not hasattr(self, 'video'):
            self.video = cv2.VideoCapture(0)
            # self.video.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
            # self.video.set(cv2.CAP_PROP_FRAME_HEIGHT, 360)

    def get_frame(self) -> bytes:
        success, image = self.video.read()

        if not success:
            return b''

        image = cv2.resize(image, None, fx=ds_factor, fy=ds_factor, interpolation=cv2.INTER_AREA)
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        face_rects = face_cascade.detectMultiScale(gray, 1.3, 5)
        for (x, y, w, h) in face_rects:
            cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
            break
        ret, jpeg = cv2.imencode('.jpg', image)
        return jpeg.tobytes()

    def save_to_dataset(self) -> str:
        data_set_size: int = 20
        sub_folder = 'Tapan_1'
        (width, height) = (130, 100)

        dst_dir = Path(__file__).parent / Path(f'{datasets}/{sub_folder}')
        dst_dir.mkdir(parents=True, exist_ok=True)
        num_of_files = len([_ for _ in dst_dir.glob('*.*')])

        if num_of_files >= data_set_size:
            return ""

        for _ in range(data_set_size - num_of_files):
            success, image = self.video.read()
            image = cv2.resize(image, None, fx=ds_factor, fy=ds_factor, interpolation=cv2.INTER_AREA)
            gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
            face_rects = face_cascade.detectMultiScale(gray, 1.3, 5)
            for (x, y, w, h) in face_rects:
                cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
                face = gray[y:y + h, x:x + w]
                face_resize = cv2.resize(face, (width, height))
                cv2.imwrite(f'{dst_dir/Path(str(uuid.uuid4()))}.png', face_resize)
        return f'{data_set_size} image captured.'

from flask import Flask, render_template, Response
from camera import VideoCamera


app = Flask(__name__)


@app.route('/')
def index():
    return render_template('index.html')


def gen(camera):
    while True:
        frame: bytes = camera.get_frame()
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')


@app.route('/video_feed')
def video_feed():
    return Response(gen(VideoCamera()),
                    mimetype='multipart/x-mixed-replace; boundary=frame')


@app.route('/exec2')
def parse1():
    response_data_collection = VideoCamera().save_to_dataset()
    response_data_collection = "Done with Collecting Data" if response_data_collection else "Do nothing"
    return render_template('index.html', alert=response_data_collection)


@app.route('/training')
def training():
    return render_template('training.html', alert='Not Yet Trained')


if __name__ == '__main__':
    app.run(debug=True)

like image 36
Carson Avatar answered Oct 25 '22 17:10

Carson