行空板之“此时此景”吟诗精灵

2024-11-117683
精华项目
AI 快速预览详细 收起
行空板之“此时此景”吟诗精灵是一个结合行空板、USB摄像头和蓝牙音箱的智能图像识别和诗歌创作系统。用户按下按钮后,系统会自动拍摄照片,并通过OpenCV库进行图像处理。接着,将图像上传至百度AI平台,利用fuyu_8b模型生成描述性文本。然后,这些文本被送入百度的大语言模型中,提炼出主题,并据此创作出一首诗歌。最后,通过语音合成技术,将诗歌转化为音频,并通过蓝牙音箱播放。这个项目不仅丰富了人们的表达方式,也使得艺术创作变得更加便捷和普及。
行空板之“此时此景”吟诗精灵图3

【项目背景】

       在日常生活中,我们经常会遇到令人心旷神怡的美景,无论是壮丽的山河、绚烂的日落,还是城市的繁华夜景,这些瞬间总能触动我们的心灵,激发我们想要用言语来表达赞美和情感的冲动。然而,并非每个人都有丰富的词汇量和文学素养,能够即兴创作出优美的诗句来充分表达内心的感受。为了解决这一问题,我们开发了这个项目,旨在通过技术手段帮助人们捕捉和表达对美景的感悟。

【项目设计】

        该项目通过行空板与USB摄像头、蓝牙音箱的结合,利用Python编程,实现了一个智能的图像识别和诗歌创作系统。当用户在看到美景并按下按钮时,系统会自动拍摄照片,并通过OpenCV库进行图像处理。接着,将图像上传至百度AI平台,利用fuyu_8b模型进行图片理解,生成描述性文本。然后,这些文本被送入百度的大语言模型中,提炼出主题,并据此创作出一首诗歌。最后,通过语音合成技术,将诗歌转化为音频,并通过蓝牙音箱播放,让用户能够以一种新颖而富有创意的方式,表达对美景的赞美和情感。这个项目不仅丰富了人们的表达方式,也使得艺术创作变得更加便捷和普及。

【项目硬件】

行空板之“此时此景”吟诗精灵图2


行空板之“此时此景”吟诗精灵图4


行空板之“此时此景”吟诗精灵图5


行空板之“此时此景”吟诗精灵图1

【百度智能云千帆大模型】

        本项目使用百度智能云千帆大模型,⼤语⾔模型使用ERNIE 4.0。

行空板之“此时此景”吟诗精灵图6

        图像理解模型使用Fuyu-8B。

行空板之“此时此景”吟诗精灵图7

【程序编写】

1.OpenCV获取摄像头图像

  1. #  -*- coding: UTF-8 -*-
  2. # MindPlus
  3. # Python
  4. import sys
  5. sys.path.append("/root/mindplus/.lib/thirdExtension/nick-base64-thirdex")
  6. import cv2
  7. from pinpong.board import Board,Pin
  8. from pinpong.extension.unihiker import *
  9. import base64
  10. from io import BytesIO
  11. from PIL import Image
  12. Board().begin()
  13. p_p21_in=Pin(Pin.P21, Pin.IN)
  14. def frame2base64(frame):
  15.     frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
  16.     img = Image.fromarray(frame) #将每一帧转为Image
  17.     output_buffer = BytesIO() #创建一个BytesIO
  18.     img.save(output_buffer, format='JPEG') #写入output_buffer
  19.     byte_data = output_buffer.getvalue() #在内存中读取
  20.     base64_data = base64.b64encode(byte_data) #转为BASE64
  21.     return base64_data #转码成功 返回base64编码
  22. def base642base64(frame):
  23.     #data=str('data:image/png;base64,')
  24.     base64data = str(frame2base64(frame))
  25.     framedata = base64data[2:(len(base64data)-1)]
  26.     #base642base64_data = data + str(framedata)
  27.     base642base64_data =str(framedata)
  28.     return base642base64_data
  29. vd = cv2.VideoCapture()
  30. vd.open(0)
  31. while not (vd.isOpened()):
  32.     pass
  33. cv2.namedWindow("Mind+'s Windows", cv2.WINDOW_NORMAL)
  34. cv2.setWindowProperty("Mind+'s Windows", cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)
  35. while True:
  36.     if vd.grab():
  37.         ret, grab = vd.read()
  38.         cv2.imshow("Mind+'s Windows", grab)
  39.         if cv2.waitKey(20) & 0xff== 27:
  40.             pass
  41.         if (p_p21_in.read_digital()==True):
  42.             picbase64 = base642base64(grab)
  43.             print(picbase64)
复制代码

2.图片理解

  1. import requests
  2. import json
  3. API_KEY = "Ef8EeI3loPIqIbxxTWZnh0av"
  4. SECRET_KEY = "****************************"
  5. def main():
  6.         
  7.     url = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/image2text/fuyu_8b?access_token=" + get_access_token()
  8.    
  9.     payload = json.dumps({
  10.         "prompt": "请描述图中美景",
  11.         "image": ""#base64编码图片
  12.     })
  13.     headers = {
  14.         'Content-Type': 'application/json'
  15.     }
  16.    
  17.     response = requests.request("POST", url, headers=headers, data=payload)
  18.    
  19.     print(response.text)
  20.    
  21. def get_access_token():
  22.     """
  23.     使用 AK,SK 生成鉴权签名(Access Token)
  24.     :return: access_token,或是None(如果错误)
  25.     """
  26.     url = "https://aip.baidubce.com/oauth/2.0/token"
  27.     params = {"grant_type": "client_credentials", "client_id": API_KEY, "client_secret": SECRET_KEY}
  28.     return str(requests.post(url, params=params).json().get("access_token"))
  29. if __name__ == '__main__':
  30.     main()
复制代码
3.写诗
  1. import requests
  2. import json
  3. API_KEY = "**********************"
  4. SECRET_KEY = "……………………………………"
  5. def main():
  6.         
  7.     url = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions_pro?access_token=" + get_access_token()
  8.    
  9.     payload = json.dumps({
  10.         "messages": [
  11.             {
  12.                 "role": "user",
  13.                 "content": "In the image , a city street is shown with several buildings. A person is crossing the street  in the middle of the scene , and there is a bike parked on the right side of the street.\n\nThe street is surrounded by trees, some of which can be seen  on the left side . There are four cars parked on the street , two near the center, one on the right side , and one further to the right . Additionally, there are two pedestrians  in the middle of the street , one closer to the right and the other further to the left .\n\n The overall scene conveys a sense of urban life, with the lush green trees, people, cars, and bicycles contributing to the city scape."
  14.             }
  15.         ],
  16.         "temperature": 0.95,
  17.         "top_p": 0.8,
  18.         "penalty_score": 1,
  19.         "enable_system_memory": True,
  20.         "system_memory_id": "sm-upmjb9yaya0gtr45",
  21.         "system": "你是一位诗人,能根据用户提供的描述,提练出主题,并做诗一首。例如:此时此景,我要吟诗一首……",
  22.         "disable_search": False,
  23.         "enable_citation": False
  24.     })
  25.     headers = {
  26.         'Content-Type': 'application/json'
  27.     }
  28.    
  29.     response = requests.request("POST", url, headers=headers, data=payload)
  30.    
  31.     result=json.loads(response.text)
  32.     print(result['result'])
  33.    
  34. def get_access_token():
  35.     """
  36.     使用 AK,SK 生成鉴权签名(Access Token)
  37.     :return: access_token,或是None(如果错误)
  38.     """
  39.     url = "https://aip.baidubce.com/oauth/2.0/token"
  40.     params = {"grant_type": "client_credentials", "client_id": API_KEY, "client_secret": SECRET_KEY}
  41.     return str(requests.post(url, params=params).json().get("access_token"))
  42. if __name__ == '__main__':
  43.     main()
复制代码
4.语音合成
  1. #  -*- coding: UTF-8 -*-
  2. # MindPlus
  3. # Python
  4. import sys
  5. sys.path.append("/root/mindplus/.lib/thirdExtension/nick-base64-thirdex")
  6. from df_xfyun_speech import XfTts
  7. appId = "5c7a6af2"
  8. apiKey ="94932090baf7bb1eae2200ace714f424"
  9. apiSecret = "*******************"
  10. options = {}
  11. business_args = {"aue":"raw","vcn":"aisjinger","tte":"utf8","speed":50,"volume":50,"pitch":50,"bgs":0}
  12. options["business_args"] = business_args
  13. tts = XfTts(appId, apiKey, apiSecret, options)
  14. tts.synthesis("你好, Mind+", "speech.wav")
复制代码
5.播放音频
  1. import pyaudio
  2. import wave
  3. # 打开WAV文件
  4. wf = wave.open('your_file.wav', 'rb')
  5. # 创建PyAudio对象
  6. p = pyaudio.PyAudio()
  7. # 打开流
  8. stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
  9.                 channels=wf.getnchannels(),
  10.                 rate=wf.getframerate(),
  11.                 output=True)
  12. # 读取数据
  13. data = wf.readframes(1024)
  14. # 播放
  15. while len(data) > 0:
  16.     stream.write(data)
  17.     data = wf.readframes(1024)
  18. # 停止流
  19. stream.stop_stream()
  20. stream.close()
  21. # 关闭PyAudio
  22. p.terminate()
复制代码

6.完整程序
  1. #  -*- coding: UTF-8 -*-
  2. # MindPlus
  3. # Python
  4. import sys
  5. sys.path.append("/root/mindplus/.lib/thirdExtension/nick-base64-thirdex")
  6. import cv2
  7. from pinpong.board import Board,Pin
  8. from pinpong.extension.unihiker import *
  9. import base64
  10. from io import BytesIO
  11. from PIL import Image
  12. import requests
  13. import json
  14. from df_xfyun_speech import XfTts
  15. import pyaudio
  16. import wave
  17. appId = "5c7a6af2"
  18. apiKey ="94932090baf7bb1eae2200ace714f424"
  19. apiSecret = "********************"
  20. options = {}
  21. business_args = {"aue":"raw","vcn":"x2_xiaoqian","tte":"utf8","speed":50,"volume":50,"pitch":50,"bgs":0}
  22. options["business_args"] = business_args
  23. tts = XfTts(appId, apiKey, apiSecret, options)
  24. def get_access_token():
  25.     """
  26.     使用 AK,SK 生成鉴权签名(Access Token)
  27.     :return: access_token,或是None(如果错误)
  28.     """
  29.     url = "https://aip.baidubce.com/oauth/2.0/token"
  30.     params = {"grant_type": "client_credentials", "client_id": API_KEY, "client_secret": SECRET_KEY}
  31.     return str(requests.post(url, params=params).json().get("access_token"))
  32. def image2text(url,base64image):
  33.     payload = json.dumps({
  34.         "prompt": "请描述图中美景",
  35.         "image":base64image
  36.         })
  37.     headers = {
  38.         'Content-Type': 'application/json'
  39.     }
  40.    
  41.     response = requests.request("POST", url, headers=headers, data=payload)
  42.    
  43.     return(response.text)
  44. cv2.namedWindow("Mind+'s Windows", cv2.WINDOW_NORMAL)
  45. cv2.setWindowProperty("Mind+'s Windows", cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)
  46. img = cv2.imread("back.png", cv2.IMREAD_UNCHANGED)
  47. img = cv2.rotate(img,cv2.ROTATE_90_CLOCKWISE)
  48. cv2.imshow("Mind+'s Windows", img)
  49. if cv2.waitKey(20) & 0xff== 27:
  50.     pass
  51. Board().begin()
  52. p_p21_in=Pin(Pin.P21, Pin.IN)
  53. def frame2base64(frame):
  54.     frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
  55.     img = Image.fromarray(frame) #将每一帧转为Image
  56.     output_buffer = BytesIO() #创建一个BytesIO
  57.     img.save(output_buffer, format='JPEG') #写入output_buffer
  58.     byte_data = output_buffer.getvalue() #在内存中读取
  59.     base64_data = base64.b64encode(byte_data) #转为BASE64
  60.     return base64_data #转码成功 返回base64编码
  61. def base642base64(frame):
  62.     #data=str('data:image/png;base64,')
  63.     base64data = str(frame2base64(frame))
  64.     framedata = base64data[2:(len(base64data)-1)]
  65.     #base642base64_data = data + str(framedata)
  66.     base642base64_data =str(framedata)
  67.     return base642base64_data
  68. def playwav(result):
  69.             tts.synthesis(result, "speech.wav")
  70.             
  71.             # 打开WAV文件
  72.             wf = wave.open('speech.wav', 'rb')
  73.             # 创建PyAudio对象
  74.             p = pyaudio.PyAudio()
  75.             # 打开流
  76.             stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
  77.                 channels=wf.getnchannels(),
  78.                 rate=wf.getframerate(),
  79.                 output=True)
  80.             # 读取数据
  81.             data = wf.readframes(1024)
  82.             # 播放
  83.             while len(data) > 0:
  84.                 stream.write(data)
  85.                 data = wf.readframes(1024)
  86.             # 停止流
  87.             stream.stop_stream()
  88.             stream.close()
  89.             # 关闭PyAudio
  90.             p.terminate()
  91. vd = cv2.VideoCapture()
  92. vd.open(0)
  93. while not (vd.isOpened()):
  94.     pass
  95. API_KEY = "********"
  96. SECRET_KEY = "************"
  97. url = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/image2text/fuyu_8b?access_token=" + get_access_token()
  98. url2 = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions_pro?access_token=" + get_access_token()
  99. while True:
  100.     if vd.grab():
  101.         ret, grab = vd.read()
  102.         cp_img = grab.copy()
  103.         cp_img = cv2.rotate(cp_img,cv2.ROTATE_90_CLOCKWISE)
  104.         cv2.imshow("Mind+'s Windows", cp_img)
  105.         if cv2.waitKey(20) & 0xff== 27:
  106.             pass
  107.         if (p_p21_in.read_digital()==True):
  108.           playwav('拍照完成,正在识别处理中')
  109.           picbase64 = base642base64(grab)
  110.           print(image2text(url,picbase64))
  111.           content=json.loads(image2text(url,picbase64))
  112.           if "result" in content:
  113.             payload = json.dumps({
  114.         "messages": [
  115.             {
  116.                 "role": "user",
  117.                 "content":content['result']
  118.             }
  119.         ],
  120.         "temperature": 0.95,
  121.         "top_p": 0.8,
  122.         "penalty_score": 1,
  123.         "enable_system_memory": True,
  124.         "system_memory_id": "sm-upmjb9yaya0gtr45",
  125.         "system": "你是一位诗人,能根据用户提供的描述,提练出主题,并做诗一首。例如:此时此情,我要吟诗一首……",
  126.         "disable_search": False,
  127.         "enable_citation": False
  128.     })
  129.             headers = {
  130.         'Content-Type': 'application/json'
  131.     }
  132.    
  133.             response = requests.request("POST", url2, headers=headers, data=payload)
  134.    
  135.             result=json.loads(response.text)
  136.             print(result['result'])
  137.             playwav(result['result'])
复制代码
【演示视频】


创作许可协议

本项目采用 None(不开放任何权利,保留所有权利) 进行许可。

评论(13)
Xiaoyan
Xiaoyan

云天老师总能不断地带来惊喜
rzegkly
rzegkly
漂亮
wsrdj
wsrdj
运行后 摁下按钮会有一串数据
wsrdj
wsrdj回复云天
谢谢指导,成功啦,非常感谢
云天
云天
作者
回复wsrdj
语音合成用的是讯飞,其它用的是百度。API是否都设置正确?
wsrdj
wsrdj
云天老师您好,我在使用您这段代码的时候能出现扫描画面 但是按下按钮后他没有任何反应 , attach://182227.png 然后每按一次 下面会出现很床遗传数据 能帮忙指导一下是什么问题吗/
_深蓝_
_深蓝_
云天老师的作品难度如芝麻开花,很难攀登这个高度
sailing
sailing
好创意
IOHDHQ
IOHDHQ
这大模型写的诗靠谱码?
云天
云天
作者
回复IOHDHQ
结合图片情景,写的打油诗。
微笑的rockets
微笑的rockets

云天老师总能不断地带来惊喜
木子哦
木子哦
云天老师总能不断地带来惊喜
木子哦
木子哦
云天老师总能不断地带来惊喜
木子哦
木子哦
云天老师总能不断地带来惊喜
RRoy
RRoy
赞一个
hnyzcj
hnyzcj
流弊
- 没有更多了 -