[PYTHON] I made a Line bot that guesses the gender and age of a person from an image

Overview

From the image sent using line We have created a bot that performs gender, age prediction, and facial expression analysis.

Like this スクリーンショット 2020-01-23 22.38.40.png スクリーンショット 2020-01-23 22.40.02.png

When you send an image, the analysis result will be returned (up to 3 people can be seen at the same time)

The source code is here (I was satisfied when I tried to make it with almost solid writing for the time being I've lost the energy to refactor)

Language and technology used

Constitution

Composition like this コメント 2020-01-24 093650.jpg

Where I got caught

When I try to send an image using the signed url of s3, I can't send it

Since you need the url of the image when sending the image to the line bot, I got an error when I tried to reply the image with the following code

s3_url = generate_presigned_url(
             ClientMethod='get_object',
             Params={
                 'Bucket': BUCKET,
                 'Key': KEY
             },
             ExpiresIn=60,
             HttpMethod='GET'
         )
line_bot_api.reply_message(
    reply_token=event.reply_token,
    messages=ImageSendMessage(
        original_content_url=s3_url,
        preview_image_url=s3_url
    )
)
LineBotApiError: status_code=400, request_id=xxxxx-xxx-xxx-xxx-xxxxxxxxxx, error_response=
{
    "details": [
        {
            "message": "Length must be between 0 and 1000",
            "property": "messages[0].originalContentUrl"
        },
        {
            "message": "Length must be between 0 and 1000",
            "property": "messages[0].previewImageUrl"
        }
    ],
    "message": "The request body has 2 error(s)"
}

url was too long and got angry ...

Issuing a signed url for s3 is too long to send Create a new public s3 bucket and I decided to get the url by putting the image to send in s3 with read-only

#Give access and put
client.put_object(ACL='public-read', Bucket=bucketname, Body=image, Key=key)
#url is created by string concatenation
s3_pub_url = 'https://' + bucketname + '.s3-ap-northeast-1.amazonaws.com/' + key
line_bot_api.reply_message(
    reply_token=event.reply_token,
    messages=ImageSendMessage(
        original_content_url=s3_pub_url,
        preview_image_url=s3_pub_url
    )
)

I've never used s3 public access Let's look at the access authority, etc. It took a long time to play around with it.

PIL module cannot be read by lambda

To draw the BoundingBox on the image I got an error when trying to import a PIL module

Unable to import module 'lambda_function': cannot import name '_imaging'

It works locally, but if it is lambda, the PIL module cannot be imported and an error occurs When I asked Google teacher, it seems that Pillow's library has a part that depends on os. So, it seems that you need Pillow library installed in the environment where lambda runs (= Amazon Linux)

Reference site: https://michimani.net/post/aws-use-pillow-in-lambda/

In the above article, I created a library using docker, ~~ It seemed to be troublesome ~~, so I decided to create a library using cloud9

--Creating a cloud9 environment --Import lambda --Install Pillow library in the target folder python3 -m pip install Pillow -t ./ --Download the target folder, upload it to s3 and deploy it --Cloud9 environment deleted

I don't want to spend as much money as possible The cloud9 environment was used only to create the Pillow library

When downloaded from cloud9, it is compressed with zip, Since it is compressed for each folder, if you deploy lambda as it is, the function cannot be called and an error occurs (1 loss)

Current issues, what you want to do, etc.

--Refactoring --The code is almost solid.
I want to separate at least the process of accessing the DB

--Organization around AWS permissions ―― ~~ It's troublesome to think about various things ~~, lambda iam role has unnecessary privileges
I want to organize so that I do not have unnecessary privileges

--DynamoDB design ――Since I've only touched RDB until now, I don't know how to use it or its merits.
The usage has become RDB-like, so I would like to increase my knowledge and think about the design again.

Recommended Posts

I made a Line bot that guesses the gender and age of a person from an image
I made a LINE BOT that returns a terrorist image using the Flickr API
I made a slack bot that notifies me of the temperature
[Python] I made a LINE Bot that detects faces and performs mosaic processing.
In Python, I made a LINE Bot that sends pollen information from location information.
I made a LINE BOT with Python and Heroku
I made a LINE bot that tells me the type and strength of Pokemon in the Galar region with Heroku + Flask + PostgreSQL (Heroku Postgres)
I created a Slack bot that confirms and notifies AWS Lambda of the expiration date of an SSL certificate
I made a LINE BOT that returns parrots with Go
I made a dot picture of the image of Irasutoya. (part1)
I made a dot picture of the image of Irasutoya. (part2)
I want a Slack bot that calculates and tells me the salary of a part-time job from the schedule of Google Calendar!
[Python] I made a Line bot that randomly asks English words.
I made a twitter app that identifies and saves the image of a specific character on the twitter timeline by pytorch transfer learning
A formula that simply calculates the age from the date of birth
I made a calendar that automatically updates the distribution schedule of Vtuber
I made a simple timer that can be started from the terminal
[Python] I made a bot that tells me the current temperature when I enter a place name on LINE
I made a stamp substitute bot with line
I made a LINE Bot with Serverless Framework!
I made an AI that predicts from trivia and made me infer my trivia. Hee-AI
I made a Line Bot that uses Python to retrieve unread Gmail emails!
I made a LINE Bot that sends recommended images every day on time
I made a Docker image that can call FBX SDK Python from Node.js
I made an appdo command to execute a command in the context of the app
With LINEBot, I made an app that informs me of the "bus time"
I tried to extract a line art from an image with Deep Learning
[Discode Bot] I created a bot that tells me the race value of Pokemon
The story of making a Line Bot that tells us the schedule of competitive programming
I made a github action that notifies Slack of the visual regression test
It seems that the Messaging API has been newly released from LINE, so I made a BOT that just analyzes morphological elements as usual.
I made a twitter app that decodes the characters of Pricone with heroku (failure)
[AWS] I made a reminder BOT with LINE WORKS
I made a household account book bot with LINE Bot
Story that an inexperienced person made a masked solver
I made a Docker Image that reads RSS and automatically tweets regularly and released it.
Make a BOT that shortens the URL of Discord
I made a system with Raspberry Pi that regularly measures the discomfort index of the room and sends a LINE notification if it is a dangerous value
I compared the speed of the reference of the python in list and the reference of the dictionary comprehension made from the in list.
A memo that detects and returns an image acquired from a webcam with Django's OpenCV
LINE Bot that notifies you of the stocks of interest
A note that runs an external program in Python and parses the resulting line
[Python / C] I made a device that wirelessly scrolls the screen of a PC remotely.
I made a calendar that automatically updates the distribution schedule of Vtuber (Google Calendar edition)
I made a program in Python that changes the 1-minute data of FX to an arbitrary time frame (1 hour frame, etc.)
I converted the time to an integer, factored it into prime factors, and made a bot to tweet the result (xkcd material)
I want to cut out only the face from a person image with Python and save it ~ Face detection and trimming with face_recognition ~
I built an application with Lambda that notifies LINE of "likes" using the Qiita API
An example of a mechanism that returns a prediction by HTTP from the result of machine learning
When I created an ECR scan from a CDK, I could see the back side of the scan
I want to find the intersection of a Bezier curve and a straight line (Bezier Clipping method)
I made an API with Docker that returns the predicted value of the machine learning model
I made a function to crop the image of python openCV, so please use it.
I tried using PI Fu to generate a 3D model of a person from one image
How to make an interactive LINE BOT 004 (answer the closing date of a listed company)
Get an image from a web page and resize it
I scraped the Organization member team and made a ranking
I made a function to check the model of DCGAN
I want to send a message from Python to LINE Bot
I made a Chatbot using LINE Messaging API and Python
I wrote a script that splits the image in two