如何自己动手实现一个图片解答小助手

有一张图片如下所示:

Kimi上有一个功能,就是解析图片内容,给出回答:

image-20241008185201298

这样可以用于拍照向AI提问的场景,我自己也有这方面的需求,因此动手实践了一下。

自己动手实现的效果如下所示:

image-20241008185722470

那么自己如何实现呢?

可以通过添加一个OCR的功能来实现。中文图片文字识别也就是OCR效果比较好的是百度开源的PaddleOCR,之前介绍过PaddleOCR的.NET绑定PaddleSharp,见这篇文章:C#使用PaddleOCR进行图片文字识别。

之前使用PaddleOCR的时候,我已经在电脑上安装了一个虚拟环境,因为需求比较简单,就是将图片进行文字识别之后返回文本就行了,因此今天玩个不一样的,不用.NET绑定,直接调用Python脚本就好了。

那么现在拆解任务就是:

C#如何调用Python脚本?

那么就先来试一下,最简单的调用,调用Python脚本输出一个Hello:

print("Hello")

可以使用 System.Diagnostics.Process 类来启动一个外部进程来运行Python脚本:

 string pythonScriptPath = @"D:\学习路线\人工智能\图片文字识别\test.py"; // 替换为你的Python脚本路径string pythonExecutablePath = @"D:\SoftWare\Anaconda\envs\paddle_env\python.exe"; // 替换为你的Python解释器路径                                                                                     ProcessStartInfo start = new ProcessStartInfo();start.FileName = pythonExecutablePath;start.Arguments =$"{pythonScriptPath}";start.UseShellExecute = false;start.RedirectStandardOutput = true;start.RedirectStandardError = true;start.CreateNoWindow = true;using (Process process = Process.Start(start)){using (System.IO.StreamReader reader = process.StandardOutput){string result = reader.ReadToEnd();MessageBox.Show(result);}using (System.IO.StreamReader errorReader = process.StandardError){string errors = errorReader.ReadToEnd();if (!string.IsNullOrEmpty(errors)){MessageBox.Show("Errors: " + errors);}}}      

其中ProcessStartInfo各属性的解释如下:

  1. FileName
    • 含义:指定要启动的程序或文档的名称。
    • 示例:在这里,pythonExecutablePath 是 Python 解释器的路径,如 "C:\path\to\python.exe"
  2. Arguments
    • 含义:指定传递给要启动程序的命令行参数。
    • 示例:在这里,pythonScriptPath 是你要执行的 Python 脚本的路径,如 "C:\path\to\hello.py"
  3. UseShellExecute
    • 含义:指定是否使用操作系统 shell 来启动进程。如果设置为 false,则直接启动进程;如果设置为 true,则通过 shell 启动进程。
    • 示例:在这里,设置为 false,表示不使用 shell 启动进程,而是直接启动 Python 解释器。
  4. RedirectStandardOutput
    • 含义:指定是否将子进程的标准输出重定向到 Process.StandardOutput 流。
    • 示例:在这里,设置为 true,表示将 Python 脚本的输出重定向到 Process.StandardOutput,以便你可以读取它。
  5. RedirectStandardError
    • 含义:指定是否将子进程的标准错误输出重定向到 Process.StandardError 流。
    • 示例:在这里,设置为 true,表示将 Python 脚本的错误输出重定向到 Process.StandardError,以便你可以读取它。
  6. CreateNoWindow
    • 含义:指定是否在新窗口中启动进程。如果设置为 true,则不会创建新窗口;如果设置为 false,则会创建新窗口。
    • 示例:在这里,设置为 true,表示不创建新窗口,即在后台运行 Python 脚本。

现在查看一下运行效果:

image-20241008191313678

获取到了Python脚本输出的值。

那么再拆解一下任务,我们需要在命令行中传入一个参数,该如何实现呢?

import sys# 检查是否有参数传递
if len(sys.argv) > 1:n = sys.argv[1]print(f"hello {n}")
else:print("请提供一个参数")

只需修改下图中,这两处地方即可:

image-20241008191639208

现在再来试下效果:

image-20241008191805671

成功在命令行中传入了一个参数。

那么现在我们的准备工作已经做好了。

PaddleOCR的使用脚本如下:

import sys
import logging
from paddleocr import PaddleOCR, draw_ocr# Paddleocr目前支持的多语言语种可以通过修改lang参数进行切换
# 例如`ch`, `en`, `fr`, `german`, `korean`, `japan`# 检查是否有参数传递
if len(sys.argv) > 1:imagePath = sys.argv[1]
else:print("请提供一个参数")# 配置日志级别为 WARNING,这样 DEBUG 和 INFO 级别的日志信息将被隐藏
logging.basicConfig(level=logging.WARNING)# 创建一个自定义的日志处理器,将日志输出到 NullHandler(不输出)
class NullHandler(logging.Handler):def emit(self, record):pass# 获取 PaddleOCR 的日志记录器
ppocr_logger = logging.getLogger('ppocr')# 移除所有默认的日志处理器
for handler in ppocr_logger.handlers[:]:ppocr_logger.removeHandler(handler)# 添加自定义的 NullHandler
ppocr_logger.addHandler(NullHandler())ocr = PaddleOCR(use_angle_cls=True, lang="ch")  # need to run only once to download and load model into memory
img_path = imagePath
result = ocr.ocr(img_path, cls=True)
for idx in range(len(result)):res = result[idx]   for line in res:print(line[1][0])

在vs code中运行效果如下所示:

image-20241008192131148

现在在WPF应用中调用结果如下:

image-20241009104512270

现在图片文字识别的部分已经搞定了。

现在就需要与大语言模型结合起来了,就是将识别出来的文字,丢给大语言模型。

可以这样写:

 public async IAsyncEnumerable<string> GetAIResponse4(string question, string imagePath){string pythonScriptPath = @"D:\学习路线\人工智能\图片文字识别\test.py"; // 替换为你的Python脚本路径string pythonExecutablePath = @"D:\SoftWare\Anaconda\envs\paddle_env\python.exe"; // 替换为你的Python解释器路径                                                                                         string arguments = imagePath; // 替换为你要传递的参数ProcessStartInfo start = new ProcessStartInfo();start.FileName = pythonExecutablePath;start.Arguments = $"{pythonScriptPath} {arguments}";start.UseShellExecute = false;start.RedirectStandardOutput = true;start.RedirectStandardError = true;start.CreateNoWindow = true;string result = "";using (Process process = Process.Start(start)){using (System.IO.StreamReader reader = process.StandardOutput){result = reader.ReadToEnd();                   }using (System.IO.StreamReader errorReader = process.StandardError){string errors = errorReader.ReadToEnd();if (!string.IsNullOrEmpty(errors)){MessageBox.Show("Errors: " + errors);}}}string skPrompt = """获取到的图片内容:{{$PictureContent}}。根据获取到的信息回答问题:{{$Question}}""";await foreach (var str in _kernel.InvokePromptStreamingAsync(skPrompt, new() { ["PictureContent"] = result, ["Question"] = question })){yield return str.ToString();}}

就可以实现如下的效果了:

image-20241009104837084

全部代码可在https://github.com/Ming-jiayou/SimpleRAG看到。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1558634.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

记录一次fdisk分区成功后lsblk不显示新建的分区

1. 查看vda盘还剩余900G空间 2. 使用fdisk分区vda3并保存 3. 分区后&#xff0c;使用lsblk发现没有显示vda3 4. 使用partprobe或者kpartx -a /dev/vda强制重新读取分区表&#xff0c;后成功显示

Spring系列 Bean的生命周期

文章目录 初始化时机单例初始化流程getBeandoGetBeangetSingleton(String) 获取单例getSingleton(String, ObjectFactory) 创建单例beforeSingletonCreationcreateBeanafterSingletonCreation createBean 创建对象doCreateBeanaddSingletonFactory createBeanInstance 创建 Bea…

文本区域分割系统源码&数据集分享

文本区域分割系统源码&#xff06;数据集分享 [yolov8-seg-EfficientHead&#xff06;yolov8-seg-EfficientRepBiPAN等50全套改进创新点发刊_一键训练教程_Web前端展示] 1.研究背景与意义 项目参考ILSVRC ImageNet Large Scale Visual Recognition Challenge 项目来源AAAI …

STM32(十八):SPI通信

SPI通信&#xff1a; SPI&#xff08;Serial Peripheral Interface&#xff09;是由Motorola公司开发的一种通用数据总线 四根通信线&#xff1a;SCK&#xff08;Serial Clock&#xff09;、MOSI&#xff08;Master Output Slave Input&#xff09;主机输出从机输入、MISO&…

腾讯IM SDK:TUIKit发送多张图片

一、问题描述 在使用腾讯IM DEMO&#xff08;https://github.com/TencentCloud/chat-uikit-vue.git&#xff09;时发现其只支持发送一张图片&#xff1a; 二、解决方案 // src\TUIKit\components\TUIChat\message-input-toolbar\image-upload\index.vue<inputref"inp…

迎接国庆旅游热潮,火山引擎数据飞轮助力景区数智化升级

随着人们生活水平的提高和旅游消费观念的转变&#xff0c;国庆假期成为人们出行旅游的黄金时段。同程旅行发布的报告显示&#xff0c;北京、杭州、重庆、上海、南京、成都等城市仍是 “十一” 假期国内热门的目的地&#xff0c;而一些新兴的宝藏旅游目的地如新疆阿勒泰、云南迪…

人工智能学者荣获2024诺贝尔物理学奖

10月的第一周&#xff0c;诺贝尔物理学奖再次吸引了全球的目光。10月8日&#xff0c;2024年诺贝尔物理学奖授予了两位机器学习领域的杰出科学家——约翰霍普菲尔德&#xff08;John Hopfield&#xff09;和杰弗里辛顿&#xff08;Geoffrey Hinton&#xff09;&#xff0c;以表彰…

PicGo+Gitee搭建Typora图床

PicGoGitee搭建Typora图床 下载PicGo 下载链接&#xff1a;https://picgo.github.io/PicGo-Doc/zh/guide/#%E4%B8%8B%E8%BD%BD%E5%AE%89%E8%A3%85 配置PicGo 插件安装 在PicGo的【插件设置】中搜索gitee-uploader插件并安装 在【图床设置】下配置Gitee repo&#xff1a;用…

免费ppt模板从哪找?一文看这里

国庆假期结束&#xff0c;回工作岗位的你是不是正忙着准备汇报材料&#xff1f;别担心&#xff0c;一份精美的PPT能为你的工作汇报增色不少。 而一个吸引人的PPT背景模板&#xff0c;更是能让你的演示脱颖而出。 为了帮助你们快速找到高质量免费ppt模板背景&#xff0c;以下特…

数字人直播带货操作流程详解!怎样的数字人直播系统能保证效果?

随着人工智能技术的不断成熟&#xff0c;以数字人直播为首的各项应用逐渐被各大中小型企业引进&#xff0c;连带着与之相关的各类话题&#xff0c;如数字人直播带货怎么操作等也开始备受关注。 而就目前的使用情况来看&#xff0c;绝大多数企业都或多或少地遭遇过数字人直播违…

Redis 五种数据类型的操作命令

一、五种数据类型的介绍 五种数据类型如图所示&#xff1a; Redis 是一个开源的键值存储系统&#xff0c;它支持多种数据结构&#xff0c;每种数据结构都有其特定的用例和底层实现。以下是 Redis 的五种主要数据类型&#xff0c;以及它们适合存储的数据类型和底层实现&#xf…

智慧出行:数字孪生三维可视化大屏交通管控系统

智慧出行已成为现代城市发展的重要支柱&#xff0c;数字孪生技术在交通领域的应用不断深化。结合三维可视化技术&#xff0c;打造功能强大的大屏交通管控系统&#xff0c;将对城市交通管理带来巨大变革。该系统通过实时监测和数据分析&#xff0c;提供精准的交通状况显示和预测…

FPUA(1)DIY个人计算机

文章目录 1.需求确定2.硬件选型2.1CPU2.2关于主板2.3硬盘2.4电源2.5散热2.6机箱2.7其他 3.选型成果展示4.组装过程5.欢迎关注技术文章 电脑作为程序员生产力最重要的生产工具&#xff0c;电脑的性能对工作效率有很大影响。电脑组装的每一个环节多少都懂一些&#xff0c;但真正的…

java判断一个字符串是否是回文字符串

代码功能 接收用户输入的字符串&#xff0c;检查该字符串是否为回文&#xff08;即正序和倒序读取都相同&#xff09;&#xff0c;然后输出检查结果。 代码 import java.util.Scanner;public class PalindromeChecker {public static void main(String[] args) {Scanner sc…

微积分-反函数6.6(反三角函数)

在本节中&#xff0c;我们应用 6.1 节的思想来找到所谓反三角函数的导数。在这个任务中&#xff0c;我们遇到了一些困难&#xff1a;由于三角函数不是一对一的&#xff0c;它们没有反函数。这个困难通过限制这些函数的定义域&#xff0c;使其成为一对一的函数&#xff0c;从而得…

软件著作权

软件著作权申请材料 材料一&#xff1a;操作手册 or 设计说明书 操作手册必须有截图&#xff0c;且执行步骤须连贯&#xff0c;从登录开始&#xff0c;到主界面展示&#xff0c;各个界面跳转&#xff0c;以及主要功能介绍&#xff0c;都要符合软件使用者的使用逻辑。文字不能…

气象大模型预测的原理与实践 免费提供气象预测数据

随着气象科学的发展&#xff0c;天气预测技术在过去几十年里取得了显著进步。如今&#xff0c;气象大模型成为了天气预报的核心工具之一。这些模型依赖于复杂的数学、物理和计算方法来模拟大气运动与天气现象&#xff0c;并且在实时数据的支持下&#xff0c;可以预测未来几小时…

YOLO11涨点优化:注意力魔改 | SimAM(无参Attention),一种轻量级的自注意力机制,效果秒杀CBAM、SE

💡💡💡SimAM是一种轻量级的自注意力机制,其网络结构与Transformer类似,但是在计算注意力权重时使用的是线性层而不是点积 💡💡💡本文改进:分别加入到YOLO11的backbone、neck、detect,助力涨点 改进1结构图: 改进2结构图: 改进3结构图: ​ 《YOLOv

OpenHarmony(鸿蒙南向开发)——轻量系统内核(LiteOS-M)【内核通信机制】

往期知识点记录&#xff1a; 鸿蒙&#xff08;HarmonyOS&#xff09;应用层开发&#xff08;北向&#xff09;知识点汇总 鸿蒙&#xff08;OpenHarmony&#xff09;南向开发保姆级知识点汇总~ 持续更新中…… 事件 基本概念 事件&#xff08;Event&#xff09;是一种任务间的…

NVIDIA 多实例 GPU

单个 GPU 中包含七个独立实例。 文章目录 前言一、优势1. 扩展 GPU 的使用范围2. 优化 GPU 利用率3. 运行同步工作负载二、 技术原理1. 根据需要调配和配置实例2. 安全、并行运行工作负载三、Blackwell GPU 中的 MIG四、为 IT 和开发运营而打造1. 从数据中心部署到边缘2. 利用容…