ageitgey / ageitgey/face_recognition

Detecting face from Uploaded files in aiohttp. RuntimeError: Expected writable numpy.ndarray with shape set.

Open
#879 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
56.8k
Forks
13.7k
PR merge metrics
No merged PRs in 30d

Description

  • face_recognition version: 1.2.3
  • Python version: 3.7.3
  • Operating System: Mac 10.14.4
Description

I wrote a small microservice in which I was getting images in HTTP POST requests and I was trying to recognize them and save their encodings into the database so that no existing face comes again.

It was working fine in my local Mac book environment with the versions written above. The code snippet is given below.

response = {
    "status": "fail",
    "message": "Invalid request"
}


try:
    reader = await request.multipart()
    field = await reader.next()
    filename = field.filename
    data = await field.read(decode=True)
    image_data = Image.open(io.BytesIO(data))
    image  = np.asarray(image_data)
    my_face_encoding = face_recognition.face_encodings(image)[0] #error on this line
    folder = 'Deliveryman/Self'
    key = '{}/{}'.format(folder, filename)
    session = aiobotocore.get_session(loop=loop)
    async with session.create_client('s3', region_name='us-west-2',
                                     aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
                                     aws_access_key_id=AWS_ACCESS_KEY_ID) as client:
        paginator = client.get_paginator('list_objects')
        async for result in paginator.paginate(Bucket=bucket, Prefix=folder):
            for c in result.get('Contents', []):
                _key = c['Key']
                file = await client.get_object(Bucket=bucket, Key=_key)
                async with file['Body']as stream:
                    file_data = await stream.read()
                    old_image = np.asarray(Image.open(io.BytesIO(file_data)))
                    unkown_face_encoding = face_recognition.face_encodings(old_image)[0]
                    results = face_recognition.compare_faces([my_face_encoding], unkown_face_encoding)
                    if results[0]:
                        response["message"] = "Face id already exists"
                        return web.json_response(response , status=400)
        resp = await client.put_object(Bucket=bucket, Key=key,  Body=data)

        if resp['ResponseMetadata']['HTTPStatusCode'] == 200:
            response["message"] = "Successfully uploaded and saved face id"
            response["key"] = key
            response["status"] = "success"
except:
    response["message"] = "An error occurred during uploading"
    return web.json_response(response, status=505)

But when I dockerize it and use it in docker, first of all, docker took about 20 mins to build on a server with bandwidth speed of 100MB/s, it starts breaking at line

    my_face_encoding = face_recognition.face_encodings(image)[0] #error on this line

and started giving me errors
RuntimeError: Expected writable numpy.ndarray with shape set.

Docker file


FROM python:3.6-slim-stretch

RUN apt-get -y update
RUN apt-get install -y --fix-missing \
    build-essential \
    cmake \
    gfortran \
    git \
    wget \
    curl \
    graphicsmagick \
    libgraphicsmagick1-dev \
    libatlas-dev \
    libavcodec-dev \
    libavformat-dev \
    libgtk2.0-dev \
    libjpeg-dev \
    liblapack-dev \
    libswscale-dev \
    pkg-config \
    python3-dev \
    python3-numpy \
    software-properties-common \
    zip \
    && apt-get clean && rm -rf /tmp/* /var/tmp/*

RUN cd ~ && \
    mkdir -p dlib && \
    git clone -b 'v19.9' --single-branch https://github.com/davisking/dlib.git dlib/ && \
    cd  dlib/ && \
    python3 setup.py install --yes USE_AVX_INSTRUCTIONS




WORKDIR /usr/src/app



COPY ./requirements.txt /usr/src/app/requirements.txt
RUN pip install -r requirements.txt


COPY ./entrypoint.sh /usr/src/app/entrypoint.sh

RUN chmod 777 /usr/src/app/entrypoint.sh


COPY . /usr/src/app



CMD ["/usr/src/app/entrypoint.sh"]


My questions are

  1. First of all why did it give me that error, when it was running perfectly on local system

  2. When I changed it a little bit, it fixed in docker too. I need to know what was the main issue behind this.

What I Did

First of all, I tried setting flag (write=true) in numpy array but it didn't work.

I saw the issue #174, he said he needed to load the file first, I then loaded files and it started working. below is my changed code.


response = {
        "status": "fail",
        "message": "Invalid request"
    }


    try:
        reader = await request.multipart()
        field = await reader.next()
        filename = field.filename
        data = await field.read(decode=True)



        # image_data = Image.open(io.BytesIO(data))
        # image  = np.asarray(image_data)

        image = face_recognition.load_image_file(io.BytesIO(data))

        my_face_encoding = face_recognition.face_encodings(image)[0]
        folder = 'Taximan/Self'
        key = '{}/{}'.format(folder, filename)
        session = aiobotocore.get_session(loop=loop)
        async with session.create_client('s3', region_name='us-west-2',
                                         aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
                                         aws_access_key_id=AWS_ACCESS_KEY_ID) as client:
            paginator = client.get_paginator('list_objects')
            async for result in paginator.paginate(Bucket=bucket, Prefix=folder):
                for c in result.get('Contents', []):
                    _key = c['Key']
                    file = await client.get_object(Bucket=bucket, Key=_key)
                    async with file['Body']as stream:
                        file_data = await stream.read()
                        old_image = face_recognition.load_image_file(io.BytesIO(file_data))

                        # old_image = np.asarray(Image.open(io.BytesIO(file_data)))
                        unkown_face_encoding = face_recognition.face_encodings(old_image)[0]
                        results = face_recognition.compare_faces([my_face_encoding], unkown_face_encoding)
                        if results[0]:
                            response["message"] = "Face id already exists"
                            return web.json_response(response , status=400)
            resp = await client.put_object(Bucket=bucket, Key=key,  Body=data)

            if resp['ResponseMetadata']['HTTPStatusCode'] == 200:
                response["message"] = "Successfully uploaded and saved face id"
                response["key"] = key
                response["status"] = "success"
    except Exception as ex:
        ex.with_traceback()
        response["message"] = "An error occurred during uploading " + str(ex)
        return web.json_response(response, status=505)

Please tell me, as the issue is fixed but what was the issue here. If file loading is really required then how is it working in my local environment.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the face_recognition.face_encodings and face_recognition.load_image_file entry points, then compare them with the PIL and np.asarray path shown in the report. Check the project documentation or tests for accepted image-array requirements; done would be an explanation of the differing behavior or a documented, reproducible fix.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, numpy, python
Domain
computer-vision, machine-learning
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.