|
from fastapi import FastAPI, File, UploadFile,HTTPException, Form |
|
from pydantic import BaseModel |
|
from deepface import DeepFace |
|
from transformers import pipeline |
|
import io |
|
import base64 |
|
import pandas as pd |
|
import numpy as ny |
|
import torch |
|
|
|
from fastapi.middleware.cors import CORSMiddleware |
|
from PIL import Image |
|
from fastapi.staticfiles import StaticFiles |
|
from fastapi.responses import HTMLResponse |
|
|
|
from huggingface_hub import InferenceClient |
|
|
|
app = FastAPI() |
|
|
|
|
|
app.add_middleware( |
|
CORSMiddleware, |
|
allow_origins=["*"], |
|
allow_credentials=True, |
|
allow_methods=["*"], |
|
allow_headers=["*"], |
|
) |
|
|
|
class ImageInfo(BaseModel): |
|
|
|
image: UploadFile |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
get_blip = pipeline("image-to-text",model="Salesforce/blip-image-captioning-large") |
|
|
|
|
|
def analyze_face(image): |
|
|
|
image_array = ny.array(image) |
|
face_result = DeepFace.analyze(image_array, actions=['age','gender','emotion'], enforce_detection=False) |
|
|
|
df = pd.DataFrame(face_result) |
|
return df['dominant_gender'][0],df['age'][0],df['dominant_emotion'][0] |
|
|
|
|
|
|
|
|
|
def image_to_base64_str(pil_image): |
|
byte_arr = io.BytesIO() |
|
pil_image.save(byte_arr, format='PNG') |
|
byte_arr = byte_arr.getvalue() |
|
return str(base64.b64encode(byte_arr).decode('utf-8')) |
|
|
|
|
|
def captioner(image): |
|
base64_image = image_to_base64_str(image) |
|
caption = get_blip(base64_image) |
|
return caption[0]['generated_text'] |
|
|
|
|
|
def get_image_info(image): |
|
|
|
image_caption = captioner(image) |
|
|
|
gender, age, emotion = analyze_face(image) |
|
|
|
return image_caption, gender, age, emotion |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def generate_story(image, length): |
|
image_caption, gender, age, emotion = get_image_info(image) |
|
|
|
prompt = f"[INS] Develop a story inspired by the image and its caption: {image_caption}. Factor in the person's age: {age} (e.g., child, teenager, adult, elder), gender: {gender}, and emotion: {emotion}. Adjust the language style accordingly; use simple words and a child-friendly tone for children, a mature tone for adults, and a considerate, reflective tone for elders. The generated story should less than: {length}. Tailor the narrative to fit the specified story length, ensuring a satisfying and conclusive ending. Ensure the narrative resonates with the appropriate age group for a more nuanced and relatable storytelling experience.[/INS]" |
|
stream = client.text_generation(prompt, **generate_kwargs, stream=True, details=True, return_full_text=False) |
|
output = "" |
|
for response in stream: |
|
output += response.token.text |
|
yield output |
|
return output |
|
|
|
|
|
app.mount("/", StaticFiles(directory="static", html=True), name="static") |
|
|
|
|
|
@app.get("/") |
|
async def read_item(): |
|
content = open("app/static/index.html", "r").read() |
|
return HTMLResponse(content=content, status_code=200) |
|
|
|
@app.post("/generate_story") |
|
async def generate_story_endpoint( |
|
image: UploadFile = File(...), |
|
length: int = Form(...) |
|
): |
|
|
|
try: |
|
contents = await image.read() |
|
pil_image = Image.open(io.BytesIO(contents)) |
|
generated_story = generate_story(pil_image, length) |
|
return {"generated_story": generated_story} |
|
except Exception as e: |
|
raise HTTPException(status_code=500, detail=f"Error generating story: {str(e)}") |
|
|
|
@app.post("/generate_story") |
|
async def generate_story_endpoint( |
|
image: UploadFile = File(...), |
|
length: int = Form(...) |
|
): |
|
try: |
|
contents = await image.read() |
|
return {"generated_story": "Story will be generated here"} |
|
except Exception as e: |
|
raise HTTPException(status_code=50) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|