C# PaddleOCR 单字识别效果

C# PaddleOCR  单字识别效果

效果

说明

        根据《百度办公文档识别C++离线SDKV1.2用户接入文档.pdf》,使用C++封装DLL,C#调用。

背景

        为使客户、第三方开发者等能够更快速、方便的接入使用百度办公文档识别 SDK、促进百度 OCR产品赋能更多客户,特设计支持 c++语言的 Windows 高精通用文字识别 SDK,该 SDK 提供 pdf 转图文的能力和通过 pdf 识别文字并可以转存成 word 的能力。

SDK 简介

        本 SDK 适应于 Windows 平台下的人脸识别系统, ,开发者可在 vs2015 下⾯进⾏开发(推荐使⽤,不保证其他版本 vs 都兼容)。SDK 采⽤ c++的动态库 dll 的⽅式。上层 UI 框架支持主流框架如QT,MFC 等。

自动批量授权

        鉴权采用自动激活的方式进行授权,可参考 SDK 示例中,把申请到的授权 key 串码(仅支持批量授权)填入到 license 文件夹的 license.key 文件中,运行 SDK,即可自动激活生成授权文件 license.ini 在license 文件夹中。SDK 授权是通过接口方法 auth_from_file 实现,该方法参数分别是传入授权 key 的串码和授权文件 license.ini 的绝对路径。确保参数正确后,在 SDK 中运行了该方法,就会生成授权license.ini 文件。若授权正确,该方法的返回值为 0,若非 0,则为授权失败,错误原因可根据错误码参考后续文档查看。

离线授权

        离线授权,采用从 sdk 附带的 license_tool 工具,bin 文件夹的 license_tool 下,双击 LicenseTool.exe,再点击拷贝,把设备指纹拷贝到剪贴板中,到百度 OCR 官网进行离线激活,填入得到的设备指纹后,从官网下载离线授权文件,解压,形成 license.key 和 license.ini 两个文件,替换到 SDK 中的 license 文件夹中,运行 SDK,若在 SDK 的授权方法 auth_from_file 中返回 0,则为通过了授权。(具体可参考SDK 中的授权代码示例)

项目

代码

using HightOCRTest.Common;
using Newtonsoft.Json;
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;

namespace HightOCRTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
        string image_path = "";
        bool isDraw = false;
        static IntPtr engine;

        private void button6_Click(object sender, EventArgs e)
        {
            //授权校验 初始化引擎
            string key = "";
            string licenseKeyPath = Application.StartupPath + "\\license\\license.key";
            string licenseFile = Application.StartupPath + "\\license\\license.ini";
            int res = -1;
            string ini_path = "";

            key = File.ReadAllText(licenseKeyPath);

            res = Native.init_license(key, licenseFile);
            if (res != 0)
            {
                MessageBox.Show(res.ToString());
                return;
            }

            engine = Native.create();
            if (engine == null)
            {
                MessageBox.Show("创建引擎失败!");
                return;
            }

            ini_path = Application.StartupPath + "\\resource";
            res = Native.init(engine, "", 6);
            if (res != 0)
            {
                MessageBox.Show(res.ToString());
                return;
            }

            MessageBox.Show("初始化成功!");

            button1.Enabled = true;
            button3.Enabled = true;
            button4.Enabled = true;
            

            button6.Enabled = false;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //image_path = Application.StartupPath + "\\images\\1.jpg";
            image_path = Application.StartupPath + "\\test2.jpg";
            pictureBox1.Image = new Bitmap(image_path);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = fileFilter;
            if (ofd.ShowDialog() != DialogResult.OK) return;
            pictureBox1.Image = null;
            image_path = ofd.FileName;
            pictureBox1.Image = new Bitmap(image_path);
            textBox1.Text = "";
        }

        StringBuilder ocr_result_texts = new StringBuilder(1024 * 10);
        StringBuilder ocr_result_words = new StringBuilder(1024 * 100);

        private void button1_Click(object sender, EventArgs e)
        {
            if (image_path == "")
            {
                return;
            }

            textBox1.Text = "";
            Application.DoEvents();

            ocr_result_texts.Clear();
            ocr_result_words.Clear();
            Mat image = new Mat(image_path);
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            int res = Native.ocr(engine, image.CvPtr, ocr_result_texts, ocr_result_words);

            stopwatch.Stop();
            double totalTime = stopwatch.Elapsed.TotalSeconds;
            textBox1.Text += $"耗时: {totalTime:F2}s";
            textBox1.Text += "\r\n-------------------\r\n";

            if (res == 0)
            {
                textBox1.Text += JsonConvert.SerializeObject(JsonConvert.DeserializeObject(ocr_result_texts.ToString()), Newtonsoft.Json.Formatting.Indented);
                textBox1.Text += "\r\n-------------------\r\n";
                textBox1.Text += JsonConvert.SerializeObject(JsonConvert.DeserializeObject(ocr_result_words.ToString()), Newtonsoft.Json.Formatting.Indented);
            }
            else
            {

                textBox1.Text = "识别失败";
            }
        }

        //绘制文字区域
        private void button3_Click(object sender, EventArgs e)
        {
            if (ocr_result_texts.Length == 0)
            {
                return;
            }

            Mat image = new Mat(image_path);
            List<OcrResTexts> lt = JsonConvert.DeserializeObject<List<OcrResTexts>>(ocr_result_texts.ToString());

            foreach (OcrResTexts item in lt)
            {
                string[] pts = item.coordinator.Split(' ');

                //多边形的顶点
                OpenCvSharp.Point[] points = new OpenCvSharp.Point[]
                {
                        new OpenCvSharp.Point(Convert.ToDouble( pts[0]), Convert.ToDouble( pts[1])),
                        new OpenCvSharp.Point(Convert.ToDouble( pts[2]), Convert.ToDouble( pts[3])),
                        new OpenCvSharp.Point(Convert.ToDouble( pts[4]), Convert.ToDouble( pts[5])),
                        new OpenCvSharp.Point(Convert.ToDouble( pts[6]), Convert.ToDouble( pts[7])),
                };

                // 绘制多边形
                Cv2.Polylines(image, new OpenCvSharp.Point[][] { points }, isClosed: true, color: new Scalar(0, 255, 0), thickness: 2);
            }

            if (pictureBox1.Image != null)
            {
                pictureBox1.Image.Dispose();
                pictureBox1.Image = null;
            }

            pictureBox1.Image = new Bitmap(image.ToMemoryStream());
            image.Dispose();

        }

        //绘制单字区域
        private void button4_Click(object sender, EventArgs e)
        {
            if (ocr_result_words.Length == 0)
            {
                return;
            }

            Mat image = new Mat(image_path);
            List<OcrResWords> lt = JsonConvert.DeserializeObject<List<OcrResWords>>(ocr_result_words.ToString());

            foreach (OcrResWords item in lt)
            {
                string[] pts = item.coordinator.Split(' ');

                //left top width height

                OpenCvSharp.Rect rect = new Rect((int)Convert.ToDouble(pts[0]), (int)Convert.ToDouble(pts[1]), (int)Convert.ToDouble(pts[2]), (int)Convert.ToDouble(pts[3]));

                Cv2.Rectangle(image, rect, color: new Scalar(255, 0, 0), thickness: 1);

            }
            if (pictureBox1.Image != null)
            {
                pictureBox1.Image.Dispose();
                pictureBox1.Image = null;
            }

            pictureBox1.Image = new Bitmap(image.ToMemoryStream());
            image.Dispose();

        }

        //识别小语种→
        private void button5_Click(object sender, EventArgs e)
        {
            //if (image_path == "")
            //{
            //    return;
            //}

            //textBox1.Text = "";
            //Application.DoEvents();

            //ocr_result_texts.Clear();
            //ocr_result_words.Clear();
            //Mat image = new Mat(image_path);
            //Stopwatch stopwatch = new Stopwatch();
            //stopwatch.Start();
            //int res = Native.ocr_other(engine, image.CvPtr, ocr_result_texts, ocr_result_words);

            //stopwatch.Stop();
            //double totalTime = stopwatch.Elapsed.TotalSeconds;
            //textBox1.Text += $"耗时: {totalTime:F2}s";
            //textBox1.Text += "\r\n-------------------\r\n";

            //if (res == 0)
            //{
            //    textBox1.Text += JsonConvert.SerializeObject(JsonConvert.DeserializeObject(ocr_result_texts.ToString()), Newtonsoft.Json.Formatting.Indented);
            //    textBox1.Text += "\r\n-------------------\r\n";
            //    textBox1.Text += JsonConvert.SerializeObject(JsonConvert.DeserializeObject(ocr_result_words.ToString()), Newtonsoft.Json.Formatting.Indented);
            //}
            //else
            //{

            //    textBox1.Text = "识别失败";
            //}
        }
    }
}

using HightOCRTest.Common;
using Newtonsoft.Json;
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;

namespace HightOCRTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
        string image_path = "";
        bool isDraw = false;
        static IntPtr engine;

        private void button6_Click(object sender, EventArgs e)
        {
            //授权校验 初始化引擎
            string key = "";
            string licenseKeyPath = Application.StartupPath + "\\license\\license.key";
            string licenseFile = Application.StartupPath + "\\license\\license.ini";
            int res = -1;
            string ini_path = "";

            key = File.ReadAllText(licenseKeyPath);

            res = Native.init_license(key, licenseFile);
            if (res != 0)
            {
                MessageBox.Show(res.ToString());
                return;
            }

            engine = Native.create();
            if (engine == null)
            {
                MessageBox.Show("创建引擎失败!");
                return;
            }

            ini_path = Application.StartupPath + "\\resource";
            res = Native.init(engine, "", 6);
            if (res != 0)
            {
                MessageBox.Show(res.ToString());
                return;
            }

            MessageBox.Show("初始化成功!");

            button1.Enabled = true;
            button3.Enabled = true;
            button4.Enabled = true;
            

            button6.Enabled = false;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //image_path = Application.StartupPath + "\\images\\1.jpg";
            image_path = Application.StartupPath + "\\test2.jpg";
            pictureBox1.Image = new Bitmap(image_path);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = fileFilter;
            if (ofd.ShowDialog() != DialogResult.OK) return;
            pictureBox1.Image = null;
            image_path = ofd.FileName;
            pictureBox1.Image = new Bitmap(image_path);
            textBox1.Text = "";
        }

        StringBuilder ocr_result_texts = new StringBuilder(1024 * 10);
        StringBuilder ocr_result_words = new StringBuilder(1024 * 100);

        private void button1_Click(object sender, EventArgs e)
        {
            if (image_path == "")
            {
                return;
            }

            textBox1.Text = "";
            Application.DoEvents();

            ocr_result_texts.Clear();
            ocr_result_words.Clear();
            Mat image = new Mat(image_path);
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            int res = Native.ocr(engine, image.CvPtr, ocr_result_texts, ocr_result_words);

            stopwatch.Stop();
            double totalTime = stopwatch.Elapsed.TotalSeconds;
            textBox1.Text += $"耗时: {totalTime:F2}s";
            textBox1.Text += "\r\n-------------------\r\n";

            if (res == 0)
            {
                textBox1.Text += JsonConvert.SerializeObject(JsonConvert.DeserializeObject(ocr_result_texts.ToString()), Newtonsoft.Json.Formatting.Indented);
                textBox1.Text += "\r\n-------------------\r\n";
                textBox1.Text += JsonConvert.SerializeObject(JsonConvert.DeserializeObject(ocr_result_words.ToString()), Newtonsoft.Json.Formatting.Indented);
            }
            else
            {

                textBox1.Text = "识别失败";
            }
        }

        //绘制文字区域
        private void button3_Click(object sender, EventArgs e)
        {
            if (ocr_result_texts.Length == 0)
            {
                return;
            }

            Mat image = new Mat(image_path);
            List<OcrResTexts> lt = JsonConvert.DeserializeObject<List<OcrResTexts>>(ocr_result_texts.ToString());

            foreach (OcrResTexts item in lt)
            {
                string[] pts = item.coordinator.Split(' ');

                //多边形的顶点
                OpenCvSharp.Point[] points = new OpenCvSharp.Point[]
                {
                        new OpenCvSharp.Point(Convert.ToDouble( pts[0]), Convert.ToDouble( pts[1])),
                        new OpenCvSharp.Point(Convert.ToDouble( pts[2]), Convert.ToDouble( pts[3])),
                        new OpenCvSharp.Point(Convert.ToDouble( pts[4]), Convert.ToDouble( pts[5])),
                        new OpenCvSharp.Point(Convert.ToDouble( pts[6]), Convert.ToDouble( pts[7])),
                };

                // 绘制多边形
                Cv2.Polylines(image, new OpenCvSharp.Point[][] { points }, isClosed: true, color: new Scalar(0, 255, 0), thickness: 2);
            }

            if (pictureBox1.Image != null)
            {
                pictureBox1.Image.Dispose();
                pictureBox1.Image = null;
            }

            pictureBox1.Image = new Bitmap(image.ToMemoryStream());
            image.Dispose();

        }

        //绘制单字区域
        private void button4_Click(object sender, EventArgs e)
        {
            if (ocr_result_words.Length == 0)
            {
                return;
            }

            Mat image = new Mat(image_path);
            List<OcrResWords> lt = JsonConvert.DeserializeObject<List<OcrResWords>>(ocr_result_words.ToString());

            foreach (OcrResWords item in lt)
            {
                string[] pts = item.coordinator.Split(' ');

                //left top width height

                OpenCvSharp.Rect rect = new Rect((int)Convert.ToDouble(pts[0]), (int)Convert.ToDouble(pts[1]), (int)Convert.ToDouble(pts[2]), (int)Convert.ToDouble(pts[3]));

                Cv2.Rectangle(image, rect, color: new Scalar(255, 0, 0), thickness: 1);

            }
            if (pictureBox1.Image != null)
            {
                pictureBox1.Image.Dispose();
                pictureBox1.Image = null;
            }

            pictureBox1.Image = new Bitmap(image.ToMemoryStream());
            image.Dispose();

        }

        //识别小语种→
        private void button5_Click(object sender, EventArgs e)
        {
            //if (image_path == "")
            //{
            //    return;
            //}

            //textBox1.Text = "";
            //Application.DoEvents();

            //ocr_result_texts.Clear();
            //ocr_result_words.Clear();
            //Mat image = new Mat(image_path);
            //Stopwatch stopwatch = new Stopwatch();
            //stopwatch.Start();
            //int res = Native.ocr_other(engine, image.CvPtr, ocr_result_texts, ocr_result_words);

            //stopwatch.Stop();
            //double totalTime = stopwatch.Elapsed.TotalSeconds;
            //textBox1.Text += $"耗时: {totalTime:F2}s";
            //textBox1.Text += "\r\n-------------------\r\n";

            //if (res == 0)
            //{
            //    textBox1.Text += JsonConvert.SerializeObject(JsonConvert.DeserializeObject(ocr_result_texts.ToString()), Newtonsoft.Json.Formatting.Indented);
            //    textBox1.Text += "\r\n-------------------\r\n";
            //    textBox1.Text += JsonConvert.SerializeObject(JsonConvert.DeserializeObject(ocr_result_words.ToString()), Newtonsoft.Json.Formatting.Indented);
            //}
            //else
            //{

            //    textBox1.Text = "识别失败";
            //}
        }
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[初始计算机]——计算机网络的基本概念和发展史及OSI参考模型

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;网络通信基础TCP/IP专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年5月30日11点59分 &#x1f004;️文章质量&#xff1a;96分 ​ 目录 &#x1f310;计算机网络概述 &#x1f4af;…

定点化和模型量化(二)

1.量化器的种类——均匀/ https://arxiv.org/pdf/1806.08342 1.1 Uniform Affine Quantizer 这是一种最朴素的量化&#xff1a; s表示step&#xff0c;可以看作量化的最小单位&#xff1b;z是zero point&#xff0c;因为当浮点x0时&#xff0c;对应的量化结果就是z。 可以看…

【SQL学习进阶】从入门到高级应用(七)

文章目录 ✨数据处理函数✨if函数✨cast函数✨加密函数 ✨分组函数✨max✨min✨avg✨sum✨count✨分组函数组合使用✨分组函数注意事项 ✨分组查询✨group by✨having✨组内排序 ✨总结单表的DQL语句 &#x1f308;你好呀&#xff01;我是 山顶风景独好 &#x1f495;欢迎来到我…

推荐系统三十六式学习笔记:01|你真的需要个性化推荐系统吗?

目录 什么是推荐系统你需要推荐系统吗总结 什么是推荐系统 让我们来换一个角度回答三个问题&#xff0c;从而重新定义什么是推荐系统: 1、它能做什么&#xff1f; 2、它需要什么&#xff1f; 3、它怎么做。 对于第一个问题“它能做什么”&#xff0c;我的回答是&#xff1a;推…

跨境电商如何收款?6大常用收款方式对比!

收款是跨境中关键的一环&#xff0c;选择一个安全、高效、成本合理的收款工具很重要。每个跨境人都要先想好选择合适的收款方式&#xff0c;今天就给跨境人们总结了6个主流的跨境收款工具&#xff0c;大家可以根据自己的实际情况进行对比选择。 1、PayPal 适用平台&#xff1a;…

Vue3使用mitt进行组件通信

mitt&#xff1a;事件总线&#xff0c;是第三方插件。 Vue2.x 使用 EventBus 事件总线进行兄弟组件通信&#xff0c;而在Vue3中 EventBus 事件总线模式已经被移除&#xff0c;官方建议使用外部的、实现了事件触发器接口的库&#xff0c;例如 mitt 或 tiny-emitter。 比起 Vue…

华为大咖说 | 企业应用AI大模型的“道、法、术”—— 法:场景篇

本文作者&#xff1a;郑岩&#xff08;华为云AI变革首席专家&#xff09;全文约5000字&#xff0c;阅读约需10分钟 这是我的AI应用系列第二篇&#xff0c;想谈谈“如何找个好场景”。场景找对了&#xff0c;那就成功一大半&#xff0c;这个道理放在AI大模型的应用上&#xff0c…

谷歌为其AI搜索结果辩护,称问题出在“数据空白”和边缘案例|TodayAI

近日&#xff0c;谷歌 Google 在推出其AI生成的搜索结果后&#xff0c;引发了广泛争议。该公司表示&#xff0c;一些不准确的搜索结果是由于“数据空白”和边缘案例导致的。 上周&#xff0c;谷歌向数百万用户推出了AI搜索结果&#xff0c;旨在提供更好的搜索体验。然而&#…

[Redis]Hash类型

基本命令 hset命令 设置 hash 中指定的字段&#xff08;field&#xff09;的值&#xff08;value&#xff09; 返回值&#xff1a;添加的字段的个数&#xff08;注意是添加的个数&#xff0c;而不包括修改的&#xff09; hset key field value [field value ...] hget命令 …

RabbitMQ(三)SpringBoot整合,可靠性投递,死信队列,延迟队列,消费端限流,消息超时

文章目录 整合Springboot概述消费者生产者 消息可靠性投递故障原因解决方案生产者端消息确认机制&#xff08;故障情况1&#xff09;故障情况2解决方案故障情况3解决方案 消费端限流概念 消息超时概念队列层面&#xff1a;配置队列过期消息本身&#xff1a;配置消息过期 死信队…

GUI 01:GUI 编程概述,AWT 相关知识,Frame 窗口,Panel 面板,及监听事件的应用

一、前言 记录时间 [2024-05-30] 疑问导航 GUI 是什么&#xff1f;GUI 如何使用&#xff1f;GUI 有哪些应用&#xff1f; 学习目的 写一些自己心中的小工具&#xff1b;Swing 界面的维护&#xff1b;了解 MVC 架构&#xff0c;以及监听事件。 本文对图形用户界面&#xff08…

Django——Admin站点(Python)

#前言&#xff1a; 该博客为小编Django基础知识操作博客的最后一篇&#xff0c;主要讲解了关于Admin站点的一些基本操作&#xff0c;小编会继续尽力更新一些优质文章&#xff0c;同时欢迎大家点赞和收藏&#xff0c;也欢迎大家关注等待后续文章。 一、简介&#xff1a; Djan…

【Spring Cloud】微服务日志收集系统-ELK+Kafka

目录 任务背景本文相关文件资料Elasticsearch特性 LogstashKibanaELKELK的缺点引入消息中间件 ELKKafkaKafka概念 ELKKafka环境搭建1.将安装素材上传至服务器 cd /usr/local/soft2.防止Elasticsearch因虚拟内存问题启动失败3.创建镜像li/centos7-elasticsearch4.创建容器5.验证…

编译安装PHP服务(LAMP3)

目录 1.初始化设置&#xff0c;将安装PHP所需软件包传到/opt目录下 &#xff08;1&#xff09;关闭防火墙 &#xff08;2&#xff09;上传软件包到/opt目录 2.安装GD库和GD库关联程序&#xff0c;用来处理和生成图片 3.配置软件模块 4.编译及安装 5.优化把PHP 的可执行程…

先导微型数控桌面式加工中心

随着数控技术、传感器技术、人工智能等技术的不断发展&#xff0c;制造业的快速发展和技术的不断进步&#xff0c;小型五轴加工中心的性能将不断提升&#xff0c;五轴联动技术作为解决异性复杂零件高效优质加工问题的重要手段&#xff0c;使其具有更广泛的应用前景。小型五轴加…

【康耐视国产案例】智能AI相机:深度解析DataMan 380大视野高速AI读码硬实力

随着读码器技术的不断更新迭代&#xff0c;大视野高速应用成为当前工业读码领域的关键发展方向。客户对大视野高速读码器的需求源于其能显著减少生产成本并提升工作效率。然而&#xff0c;大视野应用场景往往伴随着对多个条码的读取需求&#xff0c;这无疑增加了算法的处理负担…

Playwright 自动化操作

之前有见同事用过playwright进行浏览器模拟操作&#xff0c;但是没有仔细了解&#xff0c;今天去详细看了下&#xff0c;发现playwright着实比selenium牛逼多了 Playwright 相对于selenium优点 1、自动下载chromnium, 无需担心chrome升级对应版本问题&#xff1b; 2、支持录屏操…

突破 LST/LRT 赛道中心化困境,Puffer Finance 何以重塑以太坊再质押未来

纵观过去的 2023 年&#xff0c;LST 赛道竞争进入“白热化”状态。去中心化、DeFi 增强、全链化成为市场争夺关键词&#xff0c;诸多 LST 赛道老牌项目纷纷陷入“中心化矛盾”&#xff0c;指责对方在以太坊去中心化进程中的不利作为。 在这样的竞争情形下&#xff0c;以太坊联…

从Socket到WebSocket

前言 不知道大家在学习网络编程的时候都是怎样的一种方式&#xff0c;我谨以此文章来记录我自己从头开始学习C网络编程时的经历&#xff0c;中间有许多我自己的一些想法和思考。当然作为一个刚开始学习的新手来说&#xff0c;有些内容也许不那么正确&#xff0c;只是代表了我在…

flink 操作mongodb的例子

简述 该例子为从一个Collection获取数据然后插入到另外一个Collection中。 Flink的基本处理过程可以清晰地分为以下几个阶段&#xff1a; 数据源&#xff08;Source&#xff09;&#xff1a; Flink可以从多种数据源中读取数据&#xff0c;如Kafka、RabbitMQ、HDFS等。Flink会…