MovieLife 电影生活

MovieLife 电影生活

今天看到一个很有意思的项目:https://www.lampysecurity.com/post/the-infinite-audio-book

"我有一个看似愚蠢的想法。通常,这类想法只是一闪而过,很少会付诸实践。但这次有所不同。假如你的生活是一部电影,它会讲述什么故事?会发生什么?我的想法就是从这里开始的。随着 AI 的兴起,我想看看是否可以让 AI 实时讲述我的生活。我们的设想是让相机拍摄一张照片,生成对照片的描述,然后由 ChatGPT 基于所看到的内容写一个叙事场景,再将文本转换为语音并播放。"

我的实现

在整个项目中,我使用了笔记本的摄像头进行操作,运行在笔记本上,感觉非常有趣。ChatGPT的描述充满了正能量!最初的代码无法运行,因此我参考了https://platform.openai.com/docs/guides/vision,进行了修改,并成功在我的电脑上运行起来。至于树莓派,我了解得不多,正在考虑是否可以在手机上部署,但还没有深入研究。

项目概念

  • 创意起源:作者反思了人生如电影的概念,探索了使用AI实时叙述他的人生。
  • 技术整合 :该项目利用了OpenAI的各种服务,包括图像识别、语言模型和文字转语音。

硬件设置

  • 选择设备:一个带有Pi相机和Pi Sugar 3电池的Raspberry Pi Zero,以便携带。
  • 其他要求 :
    • 带有micro HDMI的显示器,用于配置。
    • 鼠标/键盘进行交互。
    • USB micro转female A适配器。
    • SD卡用于Raspberry Pi OS。
    • 由于缺乏音频插孔,需要无线耳机。

设计和3D打印

  • 外壳设计:作者修改了现有的3D外壳设计,以适应电池,并使用Bambu Lab P1S 3D Printer。

软件和API集成

  • OpenAI API设置 :
    • 创建账户并生成API密钥。
    • 解释API调用成本和使用情况。

代码实现

  • 编程语言:选择Python来编码项目。

  • 分步细节:

    • 配置文件.env

      OPENAI_API_KEY="这里填入你的API_KEY"
      
    • 导入必要的库。

      python 复制代码
      from pathlib import Path
      from openai import OpenAI
      import requests
      import os
      import cv2
      import base64
      import time
      import pygame
      from dotenv import load_dotenv
      
      
      # 加载 .env 文件
      load_dotenv()
      # OpenAI API key
      client = OpenAI()
      
      # OpenAI API Key
      api_key = os.getenv("OPENAI_API_KEY")
      # Path to your image
      image_path = "vision.jpg"
      
      # Getting the base64 string
      base64_image = "error"
      
      headers = {
          "Content-Type": "application/json",
          "Authorization": f"Bearer {api_key}"
      }
      
      payload = {
        "model": "gpt-4o-mini",
        "messages": [
          {
            "role": "user",
            "content": [
              {
                "type": "text",
                "text": "请描述这张图片?"
              },
              {
                "type": "image_url",
                "image_url": {
                  "url": f"data:image/jpeg;base64,{base64_image}"
                }
              }
            ]
          }
        ],
        "max_tokens": 300
      }
    • 从相机捕获图像。

      python 复制代码
      def capture_webcam_photo(save_directory="webcam_photos"):
          # Create directory if it doesn't exist
          if not os.path.exists(save_directory):
              os.makedirs(save_directory)
      
          # Open default camera (usually the first camera)
          cap = cv2.VideoCapture(1)
      
          # Capture frame-by-frame
          ret, frame = cap.read()
      
          # Generate a unique filename
          filename = os.path.join(save_directory, "webcam_photo.jpg")
      
          # Save the captured frame as an image
          cv2.imwrite(filename, frame)
      
          # Release the capture
          cap.release()
      
          return filename
    • 将图像编码为base64格式,以便提交API。

      python 复制代码
      # Function to encode the image
      def encode_image(image_path):
        with open(image_path, "rb") as image_file:
          return base64.b64encode(image_file.read()).decode('utf-8')
    • 使用OpenAI的模型根据图像描述生成叙述性响应。

      python 复制代码
      def generate_response(prompt):
          name = "BoBo"
          age = "60"
          location = "体操之乡 湖北仙桃"
          response = client.chat.completions.create(
              model="gpt-4o-mini",
              messages=[
                  {"role": "system",
                   "content": "你是一部电影的叙述者,讲述一个名叫 " + name + "。他的年龄  " + age + " ,生活在 " + location + "。当你看到一张场景图片时,你可以从" + name + "的角度描述这张照片,所有人物都用第三人称。 "},
                  {"role": "user", "content": prompt}
              ]
          )
          return response.choices[0].message.content
    • 将文本响应转换为语音并播放。

      python 复制代码
      def text_to_speech(text):
          speech_file_path = Path(__file__).parent / "speech.mp3"
          response = client.audio.speech.create(
            model="tts-1",
            voice="alloy",
            input=text
          )
      
          response.stream_to_file(speech_file_path)
          return speech_file_path
      
      def play_mp3(file_path):
          # Initialize Pygame
          pygame.init()
      
          try:
              # Initialize the mixer
              pygame.mixer.init()
      
              # Load the MP3 file
              pygame.mixer.music.load(file_path)
      
              # Play the MP3 file
              pygame.mixer.music.play()
      
              # Wait until the music finishes playing
              while pygame.mixer.music.get_busy():
                  pygame.time.Clock().tick(10)  # Adjust the playback speed
          except pygame.error as e:
              print(f"Error playing MP3: {e}")
          finally:
              # Cleanup Pygame
              pygame.mixer.music.stop()
              pygame.mixer.quit()
              pygame.quit()

      主函数:

      python 复制代码
      while True:
          start_time = time.time()
      
          saved_path = capture_webcam_photo()
          base64_image = encode_image(saved_path)
      
          # 将图像插入到 payload 中
          payload["messages"][0]["content"][1]["image_url"]["url"] = "data:image/jpeg;base64," + base64_image
      
          # 发送请求
          response = requests.post("https://api.openai.com/v1/chat/completions", headers=headers, json=payload)
      
          # 检查响应状态
          if response.status_code != 200:
              print(f"Error: {response.status_code} - {response.text}")
              continue  # 跳过此次循环,继续尝试
      
          jsonZ = response.json()
      
          # 检查是否有 'choices' 键
          if 'choices' in jsonZ and len(jsonZ['choices']) > 0:
              try:
                  response_text = generate_response(jsonZ["choices"][0]["message"]["content"])
                  output_file = text_to_speech(response_text)  # 
                  play_mp3(output_file)  # 
              except KeyError as e:
                  print(f"KeyError: {e}")
                  print("Received response:", jsonZ)
                  continue  # 跳过此循环并记录错误
          else:
              print("No choices found in response")
      
          # 计算经过的时间
          elapsed_time = time.time() - start_time
      
          # 等待剩余时间
          remaining_time = max(0, 20 - int(elapsed_time))
          time.sleep(remaining_time)

主要功能

  • 连续运行 :主循环每20秒捕获一次图像,通过OpenAI API进行处理,生成叙述,转换为语音,并播放。

完整代码

python 复制代码
'''
@File    : movielife
@Author  : Bobo
@Blog    : https://blog.csdn.net/chinagaobo
@Note    : This code is for learning and communication purposes only
'''

from pathlib import Path
from openai import OpenAI
import requests
import os
import cv2
import base64
import time
import pygame
from dotenv import load_dotenv


# 加载 .env 文件
load_dotenv()
# OpenAI API key
client = OpenAI()

# OpenAI API Key
api_key = os.getenv("OPENAI_API_KEY")
# Path to your image
image_path = "vision.jpg"

# Getting the base64 string
base64_image = "error"

headers = {
    "Content-Type": "application/json",
    "Authorization": f"Bearer {api_key}"
}

payload = {
  "model": "gpt-4o-mini",
  "messages": [
    {
      "role": "user",
      "content": [
        {
          "type": "text",
          "text": "请描述这张图片?"
        },
        {
          "type": "image_url",
          "image_url": {
            "url": f"data:image/jpeg;base64,{base64_image}"
          }
        }
      ]
    }
  ],
  "max_tokens": 300
}


# Function to encode the image
def encode_image(image_path):
    with open(image_path, "rb") as image_file:
        return base64.b64encode(image_file.read()).decode('utf-8')


def generate_response(prompt):
    name = "BoBo"
    age = "60"
    location = "体操之乡 湖北仙桃"
    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[
            {"role": "system",
             "content": "你是一部电影的叙述者,讲述一个名叫 " + name + "。他的年龄  " + age + " ,生活在 " + location + "。当你看到一张场景图片时,你可以从" + name + "的角度描述这张照片,所有人物都用第三人称。 "},
            {"role": "user", "content": prompt}
        ]
    )
    return response.choices[0].message.content


def text_to_speech(text):
    speech_file_path = Path(__file__).parent / "speech.mp3"
    response = client.audio.speech.create(
        model="tts-1",
        voice="alloy",
        input=text
    )

    response.stream_to_file(speech_file_path)
    return speech_file_path


def capture_webcam_photo(save_directory="webcam_photos"):
    # Create directory if it doesn't exist
    if not os.path.exists(save_directory):
        os.makedirs(save_directory)

    # Open default camera (usually the first camera)
    cap = cv2.VideoCapture(0)  # 使用内置摄像头

    # Capture frame-by-frame
    ret, frame = cap.read()

    # Generate a unique filename
    filename = os.path.join(save_directory, "webcam_photo.jpg")

    # Save the captured frame as an image
    cv2.imwrite(filename, frame)

    # Release the capture
    cap.release()

    return filename


def play_mp3(file_path):
    # Initialize Pygame
    pygame.init()

    try:
        # Initialize the mixer
        pygame.mixer.init()

        # Load the MP3 file
        pygame.mixer.music.load(file_path)

        # Play the MP3 file
        pygame.mixer.music.play()

        # Wait until the music finishes playing
        while pygame.mixer.music.get_busy():
            pygame.time.Clock().tick(10)  # Adjust the playback speed
    except pygame.error as e:
        print(f"Error playing MP3: {e}")
    finally:
        # Cleanup Pygame
        pygame.mixer.music.stop()
        pygame.mixer.quit()
        pygame.quit()


while True:
    start_time = time.time()

    saved_path = capture_webcam_photo()
    base64_image = encode_image(saved_path)

    # 将图像插入到 payload 中
    payload["messages"][0]["content"][1]["image_url"]["url"] = "data:image/jpeg;base64," + base64_image

    # 发送请求
    response = requests.post("https://api.openai.com/v1/chat/completions", headers=headers, json=payload)

    # 检查响应状态
    if response.status_code != 200:
        print(f"Error: {response.status_code} - {response.text}")
        continue  # 跳过此次循环,继续尝试

    jsonZ = response.json()

    # 检查是否有 'choices' 键
    if 'choices' in jsonZ and len(jsonZ['choices']) > 0:
        try:
            response_text = generate_response(jsonZ["choices"][0]["message"]["content"])
            output_file = text_to_speech(response_text)  # 
            play_mp3(output_file)  # 
        except KeyError as e:
            print(f"KeyError: {e}")
            print("Received response:", jsonZ)
            continue  # 跳过此循环并记录错误
    else:
        print("No choices found in response")

    # 计算经过的时间
    elapsed_time = time.time() - start_time

    # 等待剩余时间
    remaining_time = max(0, 20 - int(elapsed_time))
    time.sleep(remaining_time)

实测案例

chatGPT的描述:在这张图片中 Bobo看到一个男子坐在桌前 面带微笑 眼镜反射出柔和的光泽 这个男人的手肘支撑在下巴旁 看起来十分放松 似乎正沉浸在与人交流的愉悦中 Bobo想这样的瞬间很难得 尤其是在压力重重的生活中 室内环境给人一种温馨舒适的感觉 整齐的墙面与那扇门形成一种和谐的背景 似乎在提醒每一个人 生活中依旧有着宁静与安详 Bobo的心情也随之变得轻松起来 彷佛可以感受到这个男子所散发出的友好气息 他觉得在这个快速发展的时代 能有这样一份从容不迫和愉快的交流 是多么美好的事情 或许这就是生活的意义所在。

测试案例

相关推荐
请站在我身后28 分钟前
读论文《OmniGen: Unified Image Generation》
人工智能·深度学习·算法·语言模型·transformer
不想CRUD的小凯1 小时前
【AI大语言模型】提示词工程基础及进阶
人工智能·语言模型·自然语言处理
Lisce9603104 小时前
利士策分享,如何在有限的时间内过上富足的生活?
职场和发展·生活
javaDocker5 小时前
大型语言模型(Large Language Models)的介绍
人工智能·语言模型·自然语言处理
JannaLius15 小时前
大学生涯规划
生活
chao_66666615 小时前
OpenAI o1团队突破性论文:『过程推理』中数学推理能力大幅提升,从正确中学习的新方法
人工智能·算法·机器学习·语言模型
DA树聚17 小时前
Transformer模型-5-Multi-Head Attention
人工智能·深度学习·学习·程序人生·语言模型·transformer·easyui
营赢盈英19 小时前
OpenAI GPT-3 API: What is the difference between davinci and text-davinci-003?
ai·gpt-3·openai·openai api
长命百岁️1 天前
【Pytorch】大语言模型中的CrossEntropyLoss
人工智能·pytorch·语言模型