QtC++ 调用 tesseract开源库 搭配 Opencv 实现文字识别:从tesseract库基本介绍到实际应用实现

前言

在当今数字化时代,文字识别(OCR)技术已经渗透到我们生活和工作的方方面面,从扫描文档的自动排版到车牌识别、票据信息提取等,都离不开 OCR 技术的支持。而在众多 OCR 实现方案中,QtC++ 结合 tesseract 和 OpenCV 的组合因其高效性、灵活性和跨平台特性,成为许多开发者的首选。
本文将详细介绍如何在 QtC++ 环境下,调用 tesseractOCR 引擎,并搭配 OpenCV 进行图像处理,从而实现高效准确的文字识别功能。重点将围绕 tesseract 的导入方法、核心接口以及在整个 OCR 流程中的作用展开。​

一、文字识别技术与工具链解析​

1.1 文字识别(OCR)的应用场景与技术难点​

文字识别,即 Optical Character Recognition,简称 OCR,是指通过电子设备(如扫描仪、相机等)将图像中的文字转换为可编辑的文本格式的技术。其应用场景极为广泛:如电子文档转换,车牌识别系统的自动识别和管理;金融的票据识别提取支票、发票上的关键信息;翻译类 APP 通过摄像头识别外文并实时翻译,极大地便利了人们的跨语言交流。​
然而,OCR 技术的实现并非易事,面临着诸多技术难点。首先是图像质量的影响,如模糊、倾斜、光照不均、存在噪声等,都会导致文字识别准确率下降。其次,文字的字体、大小、颜色各异,以及可能存在的复杂背景,也会给识别带来挑战。此外,对于手写体文字,由于其个性化强、规范性差,识别难度更大,所以这也是引入OpenCV来搭配处理图像的主要原因。​

1.2 tesseract 与 OpenCV 在 OCR 中的角色​

tesseract 是一款开源的 OCR 引擎,由 Google 维护。它支持多种语言的文字识别,具有较高的识别准确率和良好的扩展性。tesseract 的核心作用是对经过预处理的图像进行分析,提取其中的文字信息并转换为文本。它可以处理不同字体、大小和格式的文字,并且能够通过训练来提高对特定场景文字的识别能力。​
OpenCV 是一个开源的计算机视觉库,包含了大量的图像处理和计算机视觉算法。在 OCR 流程中,OpenCV 主要负责图像的预处理工作,如图像的灰度化、二值化、降噪、倾斜校正等。通过这些预处理操作,可以改善图像的质量,突出文字区域,为后续 tesseract 的文字识别创造良好的条件,从而提高整个 OCR 系统的识别准确率。​

1.3 协同工作的基本流程​

tesseract 和 OpenCV 协同实现文字识别的基本流程如下:​
首先,通过文件操作或摄像头接口获取需要识别的图像文件或实时图像。然后,将获取到的图像传递给 OpenCV 进行预处理,包括灰度化处理(将彩色图像转换为黑白图像,减少计算量)、二值化处理(将图像转换为只有黑白两种颜色,使文字与背景分离)、降噪处理(去除图像中的噪声点,避免干扰识别)、倾斜校正(将倾斜的文字图像校正为水平状态,便于 tesseract 识别)等。​
预处理完成后,将处理后的图像数据传递给 tesseractOCR 引擎。tesseract 对图像进行分析,识别出其中的文字,并将其转换为文本信息。最后,将 tesseract 返回的文本信息进行展示、存储或进一步处理,如通过 UI 界面显示识别结果,或将结果保存到文件中。​

二、开发环境搭建​

2.1 OpenCV 的安装与 Qt 配置​

OpenCV 的安装步骤详情可参考之前的文章,在此就简单说下:​

  1. 从 OpenCV 官网(https://opencv.org/)下载对应操作系统的 OpenCV 安装包,解压到指定目录。​或者自行编译源码得到。
  2. 配置 OpenCV 的环境变量,将 OpenCV 的 bin 目录添加到系统的 PATH 环境变量中,这样在运行程序时,系统能够找到 OpenCV 的动态链接库。​
  3. 在 Qt 项目中配置 OpenCV。打开 Qt Creator,创建一个新的 Qt 项目。然后在项目的.pro 文件中添加 OpenCV 的头文件路径和库文件路径。例如:
INCLUDEPATH += D:/opencv/build/include
LIBS += -LD:/opencv/build/x64/vc15/lib -lopencv_world455d.lib

其中,INCLUDEPATH 指定了 OpenCV 头文件的所在目录,LIBS 指定了 OpenCV 库文件的所在目录以及需要链接的库文件。需要根据实际的 OpenCV 安装路径和版本进行修改。​

2.2 tesseract 的安装与 Qt 配置​

tesseract 的安装和配置相对复杂一些,具体步骤如下:​

  1. 下载 tesseract 安装包。可以从 tesseract 的官方 GitHub 仓库(https://github.com/tesseract-ocr/tesseract)下载源码自行编译,也可以下载别人编译好的库来用。对于 Windows 系统,注意别直接下载tesseract 的安装包,里边只有Dll没有lib静态库,也没有头文件,只能拿他的测试程序来试试效果,没法引入到代码中调用。​
    在这里插入图片描述
    想要代码调用的话,要么就直接下载源码包,自己用CMake搭配VS进行编译,要么就找别人编译好的库(包含动态库,静态库,头文件)。
  2. 安装 tesseract 其实跟OpenCV一样,就是将压缩包或者编译好的文件放置到指定目录即可,然后将 tesseract 的安装目录添加到系统环境变量中。此外,还可以选择安装需要的语言数据包,如英文、中文等,这些语言数据包用于支持对应语言的文字识别。​
  3. 在 Qt 项目中配置 tesseract。首先,需要将 tesseract 的头文件目录和库文件目录添加到 Qt 项目的.pro 文件中。例如:
INCLUDEPATH += C:/Program Files/Tesseract-OCR/include
LIBS += -LC:/Program Files/Tesseract-OCR/lib \-ltesseract51.lib

除了在.pro 文件中配置,还需要将 tesseract 的动态链接库(如 tesseract51.dll)复制到 Qt 项目的可执行文件所在目录,否则程序运行时会出现找不到库文件的错误。

三、tesseract 的深入解析​

3.1 tesseract 的特点​

tesseract 最初是由惠普公司开发的 OCR 引擎,后来被 Google 收购并开源。经过多年的发展和优化,tesseract 已经成为目前最受欢迎的开源 OCR 引擎之一。​
tesseract 具有以下特点:​

  • 开源免费:可以自由使用和修改,无需支付任何费用,降低了开发成本。​
    多语言支持:支持超过 100 种语言的文字识别,包括中文、英文、日文、韩文等,满足不同场景的需求。​
  • 高识别准确率:在经过适当的图像预处理和训练后,tesseract 能够达到较高的识别准确率,尤其是对于印刷体文字。​
  • 跨平台性:可以在 Windows、Linux、Mac 等多个操作系统上运行。​
  • 可扩展性:支持用户自定义训练数据,以提高对特定字体、特定场景文字的识别能力。​

3.2 tesseract 的核心功能与工作原理​

tesseract 的核心功能是对图像中的文字进行识别并转换为文本。其工作原理主要包括以下几个步骤:​

  • 图像预处理:tesseract 首先会对输入的图像进行一些基本的预处理,如二值化、去噪等,但这部分功能相对简单,通常需要结合 OpenCV 进行更复杂的预处理。​
  • 文字区域检测:tesseract 会分析图像,找出其中可能包含文字的区域。​
  • 字符分割:将文字区域中的字符逐个分割出来,以便进行单独识别。​
  • 特征提取:对每个分割出来的字符提取特征,如形状、轮廓、笔画等。​
  • 字符识别:将提取到的字符特征与训练数据中的特征进行比对,从而识别出字符。​
  • 文本输出:将识别出的字符组合成文本,并输出给用户。​

3.3 tesseract 的主要接口及使用说明​

tesseract 提供了丰富的 C++ 接口,方便开发者进行调用。下面介绍一些主要的接口及其使用说明。​

  • tesseract::TessBaseAPI类:这是 tesseract 的核心类,提供了文字识别的主要功能。​
    构造函数:tesseract::TessBaseAPI(),创建一个 TessBaseAPI 对象。​
  • Init方法:用于初始化 tesseract 引擎。其原型为:
int Init(const char* datapath, const char* language, OcrEngineMode oem = OEM_DEFAULT);

其中,datapath是语言数据包所在的目录,如果为 NULL,则使用默认目录;language是要识别的语言,如 “eng” 表示英文,“chi_sim” 表示简体中文;oem是 OCR 引擎模式,默认使用 OEM_DEFAULT。​
例如:

tesseract::TessBaseAPI tess;
if (tess.Init(NULL, "chi_sim+eng") != 0) {qDebug() << "无法初始化tesseract引擎!";return -1;
}

上述代码就是初始化 tesseract 引擎,并设置支持简体中文和英文识别。​

  • SetImage方法:设置要识别的图像。其原型有多种,常用的有:
void SetImage(const unsigned char* imagedata, int width, int height, int bytes_per_pixel, int bytes_per_line);

其中,imagedata是图像数据的指针;width和height是图像的宽度和高度;bytes_per_pixel是每个像素的字节数,如灰度图像为 1,RGB 图像为 3;bytes_per_line是每行图像的字节数。​
调用方法如下(结合 OpenCV):

cv::Mat image = cv::imread("test.png");
if (image.empty()) {qDebug() << "无法读取图像!";return -1;
}
tess.SetImage(image.data, image.cols, image.rows, image.channels(), image.step);

代码中将 OpenCV 读取的图像设置为 tesseract 要识别的图像。​

  • GetUTF8Text方法:获取识别到的 UTF-8 编码的文本。其原型为:
char* GetUTF8Text();

调用如下:

char* outText = tess.GetUTF8Text();
qDebug() << "识别结果:" << QString(outText);
delete[] outText; // 注意释放内存
  • End方法:释放 tesseract 引擎占用的资源。其函数原型为:
void End();

在程序结束时,调用该方法释放资源。​

  • SetPageSegMode方法:设置页面分割模式,用于指定 tesseract 如何分割图像中的文字区域。例如:
tess.SetPageSegMode(tesseract::PSM_AUTO); // 自动页面分割模式
  • SetVariable方法:设置 tesseract 的一些变量参数,以调整识别效果。例如:
tess.SetVariable("tessedit_char_whitelist", "0123456789"); // 只识别数字

3.5 tesseract 在 OCR 流程中的作用​

tesseract 在整个 OCR 流程中扮演着最核心的文字识别角色。在经过 OpenCV 的图像预处理后,图像的质量得到了改善,文字区域更加突出。此时,tesseract 接收预处理后的图像,通过其内部的一系列算法,对图像中的文字进行分析和识别。​
它首先对图像进行文字区域检测,确定哪些部分包含文字;然后将文字区域分割成单个字符;接着提取每个字符的特征,并与训练数据中的特征进行比对,从而识别出字符;最后将识别出的字符组合成完整的文本并输出。​
可以说,tesseract 是 OCR 系统的 “大脑”,负责将图像中的视觉信息转换为文本信息,是实现文字识别功能的关键环节。​

四、OpenCV 图像处理在 OCR 中的应用​

4.1 图像预处理的重要性​

图像预处理是 OCR 流程中至关重要的一步,其质量直接影响后续文字识别的准确率。原始图像可能存在各种问题,如光照不均、噪声干扰、图像倾斜、文字与背景对比度低等,这些都会导致 tesseract 识别困难。通过图像预处理,可以解决这些问题,改善图像质量,使文字更加清晰、突出,从而提高 tesseract 的识别效率和准确率。​

4.2 OpenCV 的主要图像处理功能​

OpenCV 提供了丰富的图像处理函数,以下是在 OCR 中常用的一些功能:​

  1. 图像读取与保存:cv::imread函数用于读取图像,cv::imwrite函数用于保存图像。
cv::Mat image = cv::imread("input.png"); // 读取图像
cv::imwrite("output.png", image); // 保存图像
  1. 灰度化处理:将彩色图像转换为灰度图像,减少图像的通道数,降低计算量。cv::cvtColor函数可以实现这一功能。
cv::Mat grayImage;
cv::cvtColor(image, grayImage, cv::COLOR_BGR2GRAY); // 将BGR彩色图像转换为灰度图像
  1. 二值化处理:将灰度图像转换为二值图像(只有黑白两种颜色),使文字与背景分离。cv::threshold函数是常用的二值化函数。
cv::Mat binaryImage;
cv::threshold(grayImage, binaryImage, 127, 255, cv::THRESH_BINARY); // 简单阈值二值化

其中,127 是阈值,大于阈值的像素被设置为 255(白色),小于等于阈值的像素被设置为 0(黑色)。​

  1. 降噪处理:去除图像中的噪声点,常用的方法有中值滤波、高斯滤波等。
cv::Mat denoisedImage;
cv::medianBlur(binaryImage, denoisedImage, 3); // 中值滤波,3是滤波器大小
  1. 倾斜校正:对于倾斜的文字图像,需要进行校正,使其水平。可以通过霍夫变换检测图像中的线条,计算倾斜角度,然后进行旋转校正。
cv::Mat edges;​
cv::Canny (denoisedImage, edges, 50, 150, 3); // 边缘检测​
cv::Mat lines;​
cv::HoughLinesP (edges, lines, 1, CV_PI / 180, 50, 50, 10); // 霍夫变换检测直线​
double angle = 0;int count = 0;for (int i = 0; i < lines.rows; i++) {​
cv::Vec4i l = lines.atcv::Vec4i(i);double theta = atan2 (l [3] - l [1], l [2] - l [0]) * 180 / CV_PI;if (fabs (theta) < 45 && fabs (theta) > 5) { // 过滤接近水平或垂直的线​
angle += theta;​
count++;}}if (count > 0) {​
angle /= count; // 计算平均倾斜角度​
}​
cv::Point2f center((denoisedImage.cols - 1) / 2.0f, (denoisedImage.rows - 1) / 2.0f);​
cv::Mat rotMat = cv::getRotationMatrix2D(center, angle, 1.0);​
cv::Mat rotatedImage;​
cv::warpAffine(denoisedImage, rotatedImage, rotMat, denoisedImage.size(), cv::INTER_CUBIC, cv::BORDER_REPLICATE);

五、案例:构建一个简单的 OCR 应用程序

5.1 应用程序功能如下:

实战案例将构建一个简单的 OCR 应用程序,具有以下功能:​
支持打开本地图像文件(如 png、jpg、bmp 等格式)。​
对打开的图像进行预处理(灰度化、二值化、降噪、倾斜校正等)。​
显示原始图像和预处理后的图像。​
对预处理后的图像进行文字识别,并显示识别结果。​
支持将识别结果保存为文本文件。

5.2 代码实现:

void MainWindow::on_btn1_clicked()
{// 1. 初始化 Tesseracttesseract::TessBaseAPI *ocrAPI = new tesseract::TessBaseAPI();// 语言包路径(Windows 为安装目录下的 tessdata,Linux 可省略路径)if (ocrAPI->Init(QString("D:/Tesseract_OCR/Tesseract_OCR5/tessdata").toStdString().c_str(), "chi_sim+eng")) {ui->textEdit->setText("初始化失败!检查语言包路径");return;}// 2. 加载图像(使用 OpenCV 读取,转为灰度图优化识别)QString fileName = QFileDialog::getOpenFileName(this,QString("文件对话框"),"/",QString("图片(*.jpg *.png);"));// 读取图像Mat img = imread(fileName.toStdString(), IMREAD_COLOR);if (img.empty()) {qDebug()  << QString("无法读取图像!");return;}cv::cvtColor(img, img, cv::COLOR_BGR2GRAY);  // 转为灰度图cv::threshold(img, img, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);  // 二值化// 3. 设置图像并识别ocrAPI->SetImage(img.data, img.cols, img.rows, 1, img.step);  // 单通道(灰度图)ocrAPI->SetPageSegMode(tesseract::PSM_SINGLE_BLOCK);  // 单块文本模式// 4. 获取识别结果char *outText = ocrAPI->GetUTF8Text();QString ocrResult(outText);ui->textEdit->setText(QString("识别结果:\n%1").arg(ocrResult));// 5. 释放资源delete[] outText;ocrAPI->End();delete ocrAPI;
}

以上即是使用tesseract 开源库实现OCR文字识别的一个基本应用。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据集-目标检测系列- 地球仪 数据集 globe>> DataBall

数据集-目标检测系列- 地球仪 数据集 globe&#xff1e;&#xff1e; DataBall贵在坚持&#xff01;* 相关项目1&#xff09;数据集可视化项目&#xff1a;gitcode: https://gitcode.com/DataBall/DataBall-detections-100s/overview2&#xff09;数据集训练、推理相关项目&…

[Oracle] DUAL数据表

Oracle中的DUAL数据表是一个特殊的单行单列虚拟表结构&#xff1a;1行1列SELECT * FROM DUAL;输出结果&#xff1a;列名默认DUMMY&#xff0c;值为X常见使用DUAL数据表的场景&#xff1a;1.系统函数调用测试当需要测试Oracle函数但不需要真实表数据时&#xff0c;我们可以考虑使…

第五篇: 深入解析基于 SQLAlchemy 的聊天记录持久化模块:`message_model` 与数据库操作封装

深入解析基于 SQLAlchemy 的聊天记录持久化模块:message_model 与数据库操作封装 作者:zgw 标签:SQLAlchemy、Python、FastAPI、数据库持久化、ORM、聊天系统、AI 应用开发 一、前言 在构建大模型应用(如聊天机器人、知识库问答系统)时,对话记录的持久化 是实现“可追溯…

学习游戏制作记录(将各种属性应用于战斗以及实体的死亡)8.5

1.将各种属性应用于战斗我们希望将上节课的CharactorState脚本作为一个父类&#xff0c;而玩家和敌人的属性状态都是继承自它的创建PlayerStats脚本&#xff1a;public class PlayerStats : CharactorState {private Player player;//获取玩家脚本protected override void Star…

Higgsfield平替,地球转场+动物竖中指AI视频教程

大家好&#xff0c;这里是K姐。 一个帮助你把AI真正用起来的女子。 最近TikTok上的网友已经集体疯魔了——刷到的视频总以高空航拍开场&#xff0c;镜头从地球拉近后&#xff0c;要么是橘猫蹲在白宫草坪比中指&#xff0c;要么是柴犬在富士山顶比中指…… 这种堪比好莱坞运镜…

界面规范的其他框架实现-列表-layui实现

另一个要改造的系统使用了layui&#xff0c;改造方式如下&#xff1a;斑马线&#xff1a;.layui-table[lay-even] tr:nth-child(even) {background-color: #f2f2f2 }鼠标滑过&#xff1a;.layui-table tbody tr:hover{background-color: #8dccff }标题行&#xff1a;.layui-tab…

STM32学习笔记2-GPIO的输出模式

GPIOGPIO&#xff1a;通用输入输出口&#xff1b;可配置8种输入输出模式引脚电平&#xff1a;0V-3.3V&#xff0c;部分引脚可容忍5V也可认为高电平&#xff0c;但是对于输出而言&#xff0c;最大就只能输出3.3V&#xff0c;因为供电就只有3.3V&#xff0c;能容忍5v的在以下的引…

Linux系统学习2之磁盘管理

了解磁盘内容&#xff1a;df&#xff1a;df -a &#xff08;-a是列出所有&#xff0c;-k以kb显示&#xff0c;-h以Gb显示&#xff0c;-m以Mbyte显示&#xff0c;-H为用1000b代替1024b&#xff0c;-t为显示文件类型&#xff0c;-i为用inode显示容量&#xff09;&#xff1a;&a…

北大、蚂蚁三个维度解构高效隐私保护机器学习:前沿进展+发展方向

在数据隐私日益重要的 AI 时代&#xff0c;如何在保护用户数据的同时高效运行机器学习模型&#xff0c;成为了学术界和工业界共同关注的难题。北大团队最新完成的综述《Towards Efficient Privacy-Preserving Machine Learning: A Systematic Review from Protocol, Model, and…

计算机网络:如何在实际网络中进行子网划分

在实际网络中,子网划分是通过“借位”将一个大的IP网络分割为多个小的子网,以提高IP地址利用率、增强网络安全性和简化管理。以下是具体的实施步骤、原理和注意事项: 一、子网划分的核心目的 提高IP利用率:避免大网络中IP地址的浪费(例如一个C类地址默认支持254台主机,若…

《第五篇》基于RapidOCR的图片和PDF文档加载器实现详解

基于RapidOCR的图片和PDF文档加载器实现详解 引言 在构建知识库时,我们经常需要处理包含图片和PDF文档的数据。这些文档中的文本信息通常以图像形式存在,需要通过OCR技术来提取。本文将详细介绍如何使用RapidOCR技术实现图片和PDF文档的文本提取加载器。 核心概念 RapidO…

[硬件电路-122]:模拟电路 - 信号处理电路 - 模拟电路与数字电路、各自的面临的难题对比?

数字电路和模拟电路是电子技术的两大基础分支&#xff0c;它们分别处理不同类型的信号&#xff0c;并在设计方法、元件特性、应用场景等方面存在显著差异。以下是两者的详细定义及异同对比&#xff1a;一、定义与核心概念1. 模拟电路&#xff08;Analog Circuit&#xff09;定义…

Linux多线程——线程控制

目录 1.线程知识补充 1.1 线程私有资源 1.2 线程共享资源 1.3 原生线程库 2、线程控制接口 2.1 线程创建 2.1.1 一批线程 2.2 线程等待 2.3 线程终止 2.4 线程实战 2.5 其他接口 2.5.1 关闭线程pthread_cancel 2.5.2 获取线程 ID pthread_self 2.5.3 线pthread_de…

Python爬虫实战:研究spiderfoot工具,构建网络情报收集系统

1. 引言 1.1 研究背景 在数字化时代,互联网公开信息已成为国家治理、企业决策与学术研究的战略资源。据 Statista 统计,2023 年全球互联网数据总量突破 120ZB,其中可通过公开渠道获取的情报信息占比超 30%。传统人工信息收集方式受限于效率与广度,难以应对海量数据处理需…

在路由器openwrt上安装openclas

在路由器openwrt上安装openclas 名词解释 las: lash 运行效果图 安装 安装教程参考&#xff1a; 官方&#xff1a;github.com 官方2&#xff1a;openclas.net 如果安装完成后菜单上没有&#xff0c;重启路由后在“服务”菜单下 点击运行会提示下载内核&#xff0c;按提示…

HIVE 窗口函数处理重复数据

窗口函数row_number()&#xff0c;结合OVER子句中的PARTITION BY和ORDER BY&#xff0c;为数据分组内的每一行生成一个唯一的序号。具体分析如下&#xff1a;函数作用&#xff1a;row_number()&#xff1a;为每个分组内的行分配一个唯一的连续序号&#xff08;从1开始&#xff…

自动驾驶控制算法——MPC控制算法

自动驾驶控制算法——MPC控制算法 文章目录自动驾驶控制算法——MPC控制算法一、MPC 是什么&#xff1f;1.1 定义与核心思想1.2 MPC 与传统控制器&#xff08;如 PID&#xff09;的区别1.3 自动驾驶中 MPC 的典型应用场景&#x1f697; 轨迹跟踪控制&#xff08;Trajectory Tra…

【DL学习笔记】各种卷积操作总结(深度可分离、空洞、转置、可变形)

Vanilla Convolution 普通卷积 卷积通道数&#xff1a; 卷积核的数量决定输出的张量的通道数nnn&#xff0c;输入的张量和每一个核Kernel做卷积运算得到一个channel的输出。输入通道数CinC_{in}Cin​决定每一个卷积核的通道数 卷积输出feature map的尺寸的计算公式&#xff1…

【Ubuntu】请问,`ip -a`显示的“wlo1”是什么呀?

商量AI wlo1 是 Linux 系统中 无线网络接口&#xff08;Wi-Fi 网卡&#xff09;的名称&#xff0c;其命名遵循现代 Linux 的 可预测网络接口命名规则&#xff08;Predictable Network Interface Names&#xff09;。以下是详细解析&#xff1a;命名规则拆解 wlo1 的结构由三部分…

Excel商业智能分析报表 【销售管理分析仪】

1.销售漏斗&#xff08;Sales Funnel&#xff09;分析&#x1f31f;&#x1f31f; 销售漏斗定义&#xff1a;科学反映商机状态及销售效率的销售管理模型。适用场景&#xff1a;关系型销售运营&#xff08;需长期维护客户关系的销售模式&#xff09;。核心功能&#xff1a;按销售…