C# OpenCvSharp DNN 卡证检测矫正
目录
说明
效果
模型
项目
代码
下载
参考
说明
源码地址:https://modelscope.cn/models/iic/cv_resnet_carddetection_scrfd34gkps
在实人认证、文档电子化等场景中需要自动化提取卡证的信息,以便进一步做录入处理。这类场景通常存在两类问题,一是识别卡证类型时易受背景干扰,二是卡证拍摄角度造成的文字畸变影响OCR准确率。鉴于证件类数据的敏感性,我们采用大量合成卡证数据做训练(参见:SyntheticCards), 并改造人脸检测SOTA方法SCRFD(论文地址, 代码地址)训练了卡证检测矫正模型,可以对各类国际常见卡证(如,身份证、护照、驾照等)进行检测、定位及矫正,得到去除背景的正视角卡证图像,便于后续卡证分类或OCR内容提取。
效果

模型
Model Properties
-------------------------
---------------------------------------------------------------
Inputs
-------------------------
name:input.1
tensor:Float[1, 3, 640, 640]
---------------------------------------------------------------
Outputs
-------------------------
name:1401
tensor:Float[1, 25600, 1]
name:1455
tensor:Float[1, 6400, 1]
name:1507
tensor:Float[1, 1600, 1]
name:1408
tensor:Float[1, 25600, 4]
name:1461
tensor:Float[1, 6400, 4]
name:1513
tensor:Float[1, 1600, 4]
name:1415
tensor:Float[1, 25600, 8]
name:1467
tensor:Float[1, 6400, 8]
name:1519
tensor:Float[1, 1600, 8]
---------------------------------------------------------------
项目

代码
using OpenCvSharp;
using OpenCvSharp.Dnn;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
namespace OpenCvSharp_Demo
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
string startupPath;
string image_path;
private void Form1_Load(object sender, EventArgs e)
{
startupPath = System.Windows.Forms.Application.StartupPath;
image_path = "1.jpg";
pictureBox1.Image = new Bitmap(image_path);
image = new Mat(image_path);
opencv_net = CvDnn.ReadNetFromOnnx("carddetection_scrfd34gkps.onnx");
}
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = fileFilter;
if (ofd.ShowDialog() != DialogResult.OK) return;
pictureBox1.Image = null;
pictureBox2.Image = null;
textBox1.Text = "";
image_path = ofd.FileName;
pictureBox1.Image = new Bitmap(image_path);
image = new Mat(image_path);
}
Stopwatch stopwatch = new Stopwatch();
Net opencv_net;
Mat BN_image;
Mat image;
Mat result_image;
float[] stride = { 8.0f, 16.0f, 32.0f };
int inpWidth = 640;
int inpHeight = 640;
float confThreshold = 0.5f;
float nmsThreshold = 0.5f;
bool keep_ratio = true;
Mat resize_image(Mat srcimg, ref int newh, ref int neww, ref int top, ref int left)
{
int srch = srcimg.Rows, srcw = srcimg.Cols;
newh = inpHeight;
neww = inpWidth;
Mat dstimg = new Mat();
if (keep_ratio && srch != srcw)
{
float hw_scale = (float)srch / srcw;
if (hw_scale > 1)
{
newh = inpHeight;
neww = (int)(inpWidth / hw_scale);
Cv2.Resize(srcimg, dstimg, new OpenCvSharp.Size(neww, newh));
left = (int)((inpWidth - neww) * 0.5);
Cv2.CopyMakeBorder(dstimg, dstimg, 0, 0, left, inpWidth - neww - left, BorderTypes.Constant, 0);
}
else
{
newh = (int)(inpHeight * hw_scale);
neww = inpWidth;
Cv2.Resize(srcimg, dstimg, new OpenCvSharp.Size(neww, newh));
top = (int)((inpHeight - newh) * 0.5);
Cv2.CopyMakeBorder(dstimg, dstimg, top, inpHeight - newh - top, 0, 0, BorderTypes.Constant, 0);
}
}
else
{
Cv2.Resize(srcimg, dstimg, new OpenCvSharp.Size(neww, newh));
}
return dstimg;
}
unsafe private void button2_Click(object sender, EventArgs e)
{
if (image_path == "")
{
return;
}
stopwatch.Restart();
image = new Mat(image_path);
result_image = image.Clone();
int newh = 0, neww = 0, padh = 0, padw = 0;
Mat img = resize_image(image, ref newh, ref neww, ref padh, ref padw);
Mat blob = new Mat();
BN_image = CvDnn.BlobFromImage(img, 1 / 128.0, new OpenCvSharp.Size(inpWidth, inpHeight), new Scalar(127.5, 127.5, 127.5), true, false);
opencv_net.SetInput(BN_image);
Mat[] outs = new Mat[9] { new Mat(), new Mat(), new Mat(), new Mat(), new Mat(), new Mat(), new Mat(), new Mat(), new Mat() };
string[] outBlobNames = opencv_net.GetUnconnectedOutLayersNames();
opencv_net.Forward(outs, outBlobNames);
//generate proposals
List<float> confidences = new List<float>();
List<Rect> boxes = new List<Rect>();
List<List<int>> landmarks = new List<List<int>>();
float ratioh = (float)image.Rows / newh, ratiow = (float)image.Cols / neww;
int n = 0, i = 0, j = 0, k = 0, l = 0;
for (n = 0; n < 3; n++)
{
int num_grid_x = (int)(inpWidth / stride[n]);
int num_grid_y = (int)(inpHeight / stride[n]);
float* pdata_score = (float*)outs[n * 3].Data; //score
float* pdata_bbox = (float*)outs[n * 3 + 1].Data; //bounding box
float* pdata_kps = (float*)outs[n * 3 + 2].Data; //face landmark
for (i = 0; i < num_grid_y; i++)
{
for (j = 0; j < num_grid_x; j++)
{
for (k = 0; k < 4; k++)
{
if (pdata_score[0] > confThreshold)
{
int xmin = (int)(((j - pdata_bbox[0]) * stride[n] - padw) * ratiow);
int ymin = (int)(((i - pdata_bbox[1]) * stride[n] - padh) * ratioh);
int width = (int)((pdata_bbox[2] + pdata_bbox[0]) * stride[n] * ratiow);
int height = (int)((pdata_bbox[3] + pdata_bbox[1]) * stride[n] * ratioh);
confidences.Add(pdata_score[0]);
boxes.Add(new Rect(xmin, ymin, width, height));
List<int> landmark = new List<int>();
for (l = 0; l < 8; l += 2)
{
landmark.Add((int)(((j + pdata_kps[l]) * stride[n] - padw) * ratiow));
landmark.Add((int)(((i + pdata_kps[l + 1]) * stride[n] - padh) * ratioh));
}
landmarks.Add(landmark);
}
pdata_score++;
pdata_bbox += 4;
pdata_kps += 8;
}
}
}
}
//vector<int> indices;
int[] indices;
CvDnn.NMSBoxes(boxes, confidences, confThreshold, nmsThreshold, out indices);
//draw bbox and kps
for (i = 0; i < indices.Length; ++i)
{
int idx = indices[i];
Rect box = boxes[idx];
Cv2.Rectangle(result_image, new OpenCvSharp.Point(box.X, box.Y), new OpenCvSharp.Point(box.X + box.Width, box.Y + box.Height), new Scalar(0, 0, 255), 2);
for (k = 0; k < 8; k += 2)
{
Cv2.Circle(result_image, new OpenCvSharp.Point(landmarks[idx][k], landmarks[idx][k + 1]), 10, new Scalar(0, 255, 0), -1);
}
//Get the label for the class name and its confidence
string label = confidences[idx].ToString("P2");
//Display the label at the top of the bounding box
int baseLine;
OpenCvSharp.Size labelSize = Cv2.GetTextSize(label, HersheyFonts.HersheySimplex, 0.5, 2, out baseLine);
int top = Math.Max(box.Y, labelSize.Height);
Cv2.PutText(result_image, label, new OpenCvSharp.Point(box.X, top - 10), HersheyFonts.HersheySimplex, 1, new Scalar(0, 255, 0), 2);
}
stopwatch.Stop();
double costTime = stopwatch.Elapsed.TotalMilliseconds;
textBox1.Text = $"耗时:{costTime:F2}ms";
pictureBox2.Image = new Bitmap(result_image.ToMemoryStream());
}
private void button3_Click(object sender, EventArgs e)
{
if (pictureBox2.Image == null)
{
return;
}
Bitmap output = new Bitmap(pictureBox2.Image);
var sdf = new SaveFileDialog();
sdf.Title = "保存";
sdf.Filter = "Images (*.jpg)|*.jpg|Images (*.png)|*.png|Images (*.bmp)|*.bmp";
if (sdf.ShowDialog() == DialogResult.OK)
{
switch (sdf.FilterIndex)
{
case 1:
{
output.Save(sdf.FileName, ImageFormat.Jpeg);
break;
}
case 2:
{
output.Save(sdf.FileName, ImageFormat.Png);
break;
}
case 3:
{
output.Save(sdf.FileName, ImageFormat.Bmp);
break;
}
}
MessageBox.Show("保存成功,位置:" + sdf.FileName);
}
}
}
}
using OpenCvSharp;
using OpenCvSharp.Dnn;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;namespace OpenCvSharp_Demo
{public partial class Form1 : Form{public Form1(){InitializeComponent();}string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";string startupPath;string image_path;private void Form1_Load(object sender, EventArgs e){startupPath = System.Windows.Forms.Application.StartupPath;image_path = "1.jpg";pictureBox1.Image = new Bitmap(image_path);image = new Mat(image_path);opencv_net = CvDnn.ReadNetFromOnnx("carddetection_scrfd34gkps.onnx");}private void button1_Click(object sender, EventArgs e){OpenFileDialog ofd = new OpenFileDialog();ofd.Filter = fileFilter;if (ofd.ShowDialog() != DialogResult.OK) return;pictureBox1.Image = null;pictureBox2.Image = null;textBox1.Text = "";image_path = ofd.FileName;pictureBox1.Image = new Bitmap(image_path);image = new Mat(image_path);}Stopwatch stopwatch = new Stopwatch();Net opencv_net;Mat BN_image;Mat image;Mat result_image;float[] stride = { 8.0f, 16.0f, 32.0f };int inpWidth = 640;int inpHeight = 640;float confThreshold = 0.5f;float nmsThreshold = 0.5f;bool keep_ratio = true;Mat resize_image(Mat srcimg, ref int newh, ref int neww, ref int top, ref int left){int srch = srcimg.Rows, srcw = srcimg.Cols;newh = inpHeight;neww = inpWidth;Mat dstimg = new Mat();if (keep_ratio && srch != srcw){float hw_scale = (float)srch / srcw;if (hw_scale > 1){newh = inpHeight;neww = (int)(inpWidth / hw_scale);Cv2.Resize(srcimg, dstimg, new OpenCvSharp.Size(neww, newh));left = (int)((inpWidth - neww) * 0.5);Cv2.CopyMakeBorder(dstimg, dstimg, 0, 0, left, inpWidth - neww - left, BorderTypes.Constant, 0);}else{newh = (int)(inpHeight * hw_scale);neww = inpWidth;Cv2.Resize(srcimg, dstimg, new OpenCvSharp.Size(neww, newh));top = (int)((inpHeight - newh) * 0.5);Cv2.CopyMakeBorder(dstimg, dstimg, top, inpHeight - newh - top, 0, 0, BorderTypes.Constant, 0);}}else{Cv2.Resize(srcimg, dstimg, new OpenCvSharp.Size(neww, newh));}return dstimg;}unsafe private void button2_Click(object sender, EventArgs e){if (image_path == ""){return;}stopwatch.Restart();image = new Mat(image_path);result_image = image.Clone();int newh = 0, neww = 0, padh = 0, padw = 0;Mat img = resize_image(image, ref newh, ref neww, ref padh, ref padw);Mat blob = new Mat();BN_image = CvDnn.BlobFromImage(img, 1 / 128.0, new OpenCvSharp.Size(inpWidth, inpHeight), new Scalar(127.5, 127.5, 127.5), true, false);opencv_net.SetInput(BN_image);Mat[] outs = new Mat[9] { new Mat(), new Mat(), new Mat(), new Mat(), new Mat(), new Mat(), new Mat(), new Mat(), new Mat() };string[] outBlobNames = opencv_net.GetUnconnectedOutLayersNames();opencv_net.Forward(outs, outBlobNames);//generate proposalsList<float> confidences = new List<float>();List<Rect> boxes = new List<Rect>();List<List<int>> landmarks = new List<List<int>>();float ratioh = (float)image.Rows / newh, ratiow = (float)image.Cols / neww;int n = 0, i = 0, j = 0, k = 0, l = 0;for (n = 0; n < 3; n++){int num_grid_x = (int)(inpWidth / stride[n]);int num_grid_y = (int)(inpHeight / stride[n]);float* pdata_score = (float*)outs[n * 3].Data; //scorefloat* pdata_bbox = (float*)outs[n * 3 + 1].Data; //bounding boxfloat* pdata_kps = (float*)outs[n * 3 + 2].Data; //face landmarkfor (i = 0; i < num_grid_y; i++){for (j = 0; j < num_grid_x; j++){for (k = 0; k < 4; k++){if (pdata_score[0] > confThreshold){int xmin = (int)(((j - pdata_bbox[0]) * stride[n] - padw) * ratiow);int ymin = (int)(((i - pdata_bbox[1]) * stride[n] - padh) * ratioh);int width = (int)((pdata_bbox[2] + pdata_bbox[0]) * stride[n] * ratiow);int height = (int)((pdata_bbox[3] + pdata_bbox[1]) * stride[n] * ratioh);confidences.Add(pdata_score[0]);boxes.Add(new Rect(xmin, ymin, width, height));List<int> landmark = new List<int>();for (l = 0; l < 8; l += 2){landmark.Add((int)(((j + pdata_kps[l]) * stride[n] - padw) * ratiow));landmark.Add((int)(((i + pdata_kps[l + 1]) * stride[n] - padh) * ratioh));}landmarks.Add(landmark);}pdata_score++;pdata_bbox += 4;pdata_kps += 8;}}}}//vector<int> indices;int[] indices;CvDnn.NMSBoxes(boxes, confidences, confThreshold, nmsThreshold, out indices);//draw bbox and kpsfor (i = 0; i < indices.Length; ++i){int idx = indices[i];Rect box = boxes[idx];Cv2.Rectangle(result_image, new OpenCvSharp.Point(box.X, box.Y), new OpenCvSharp.Point(box.X + box.Width, box.Y + box.Height), new Scalar(0, 0, 255), 2);for (k = 0; k < 8; k += 2){Cv2.Circle(result_image, new OpenCvSharp.Point(landmarks[idx][k], landmarks[idx][k + 1]), 10, new Scalar(0, 255, 0), -1);}//Get the label for the class name and its confidencestring label = confidences[idx].ToString("P2");//Display the label at the top of the bounding boxint baseLine;OpenCvSharp.Size labelSize = Cv2.GetTextSize(label, HersheyFonts.HersheySimplex, 0.5, 2, out baseLine);int top = Math.Max(box.Y, labelSize.Height);Cv2.PutText(result_image, label, new OpenCvSharp.Point(box.X, top - 10), HersheyFonts.HersheySimplex, 1, new Scalar(0, 255, 0), 2);}stopwatch.Stop();double costTime = stopwatch.Elapsed.TotalMilliseconds;textBox1.Text = $"耗时:{costTime:F2}ms";pictureBox2.Image = new Bitmap(result_image.ToMemoryStream());}private void button3_Click(object sender, EventArgs e){if (pictureBox2.Image == null){return;}Bitmap output = new Bitmap(pictureBox2.Image);var sdf = new SaveFileDialog();sdf.Title = "保存";sdf.Filter = "Images (*.jpg)|*.jpg|Images (*.png)|*.png|Images (*.bmp)|*.bmp";if (sdf.ShowDialog() == DialogResult.OK){switch (sdf.FilterIndex){case 1:{output.Save(sdf.FileName, ImageFormat.Jpeg);break;}case 2:{output.Save(sdf.FileName, ImageFormat.Png);break;}case 3:{output.Save(sdf.FileName, ImageFormat.Bmp);break;}}MessageBox.Show("保存成功,位置:" + sdf.FileName);}}}
}
下载
源码下载
参考
https://github.com/hpc203/cv_resnet_carddetection_scrfd34gkps-opencv-dnn
相关文章:
C# OpenCvSharp DNN 卡证检测矫正
目录 说明 效果 模型 项目 代码 下载 参考 说明 源码地址:https://modelscope.cn/models/iic/cv_resnet_carddetection_scrfd34gkps 在实人认证、文档电子化等场景中需要自动化提取卡证的信息,以便进一步做录入处理。这类场景通常存在两类问题&…...
Spring Boot 中 Map 的最佳实践
在Spring Boot中使用Map时,请遵循以下最佳实践: 1.避免在Controller中 直接使用Map。应该使用RequestBody 接收-个DTO对象或者 RequestParam接收参数,然后在Service中处 理Map。 2.避免在Service中 直接使用原始的Map。应该使用Autowired 注入-个专门…...
J-LangChain - 智能链构建
介绍 j-langchain是一个Java版的LangChain开发框架,旨在简化和加速各类大模型应用在Java平台的落地开发。它提供了一组实用的工具和类,使得开发人员能够更轻松地构建类似于LangChain的Java应用程序。 依赖 Maven <dependency><groupId>i…...
开源低代码平台-Microi吾码 打印引擎使用
引言 在开发中,会遇到很多记录的表单数据需要下载打印下来使用到线下各种应用场景中。在传统的方法中可能是需要先导出数据,然后将数据填入word表格中在打印下来。 但Microi吾码提供了一项新功能,便是打印引擎。打印引擎即可在线设计…...
【MySQL】索引 面试题
文章目录 适合创建索引的情况创建索引的注意事项MySQL中不适合创建索引的情况索引失效的常见情况 索引定义与作用 索引是帮助MySQL高效获取数据的有序数据结构,通过维护特定查找算法的数据结构(如B树),以某种方式引用数据…...
【高阶数据结构】AVL树
AVL树 1.AVL的概念2.AVL树的实现1.AVL树的结构2.AVL树的插入1.更新平衡因子2.旋转1.右单旋2.左单旋3.左右双旋4.右左双旋 3.AVL树的查找4.AVL树的平衡检测5.AVL树的性能分析6.AVL树的删除 3.总代码1.AVLTree.h2.Test.cpp 1.AVL的概念 AVL树是最先发明的自平衡⼆叉查找树&#…...
【Spring】基于XML的Spring容器配置——<bean>标签与属性解析
Spring框架是一个非常流行的应用程序框架,它通过控制反转(IoC)和依赖注入(DI)来简化企业级应用的开发。Spring容器是其核心部分,负责管理对象的创建、配置和生命周期。在Spring中,XML配置是一种…...
docker mysql5.7安装
一.更改 /etc/docker/daemon.json sudo mkdir -p /etc/dockersudo tee /etc/docker/daemon.json <<-EOF {"registry-mirrors": ["https://do.nark.eu.org","https://dc.j8.work","https://docker.m.daocloud.io","https:/…...
HDR视频技术之十一:HEVCH.265 的 HDR 编码方案
前文我们对 HEVC 的 HDR 编码优化技术做了介绍,侧重编码性能的提升。 本章主要阐述 HEVC 中 HDR/WCG 相关的整体编码方案, 包括不同应用场景下的 HEVC 扩展编码技术。 1 背景 HDR 信号一般意味着使用更多比特,一般的 HDR 信号倾向于使用 10…...
最新的强大的文生视频模型Pyramid Flow 论文阅读及复现
《PYRAMIDAL FLOW MATCHING FOR EFFICIENT VIDEO GENERATIVE MODELING》 论文地址:2410.05954https://arxiv.org/pdf/2410.05954 项目地址: jy0205/Pyramid-Flow: 用于高效视频生成建模的金字塔流匹配代码https://github.com/jy0205/Pyram…...
Effective C++ 条款 11:在 `operator=` 中处理“自我赋值”
文章目录 条款 11:在 operator 中处理“自我赋值”核心问题示例:使用地址比较示例:copy-and-swap 技术设计建议总结 条款 11:在 operator 中处理“自我赋值” 核心问题 自我赋值风险 如果赋值操作符没有处理自我赋值(…...
19、鸿蒙学习——配置HDC命令 环境变量
一、下载Command Line Tools 可参考上篇《鸿蒙学习——配置OHPM、hvigor环境变量》 二、配置hdc环境变量 hdc命令行工具用于HarmonyOS应用/元服务调试所需的工具,该工具存放在命令行工具自带的sdk下的toolchains目录中。为方便使用hdc命令行工具,请将…...
初始 ShellJS:一个 Node.js 命令行工具集合
一. 前言 Node.js 丰富的生态能赋予我们更强的能力,对于前端工程师来说,使用 Node.js 来编写复杂的 npm script 具有明显的 2 个优势:首先,编写简单的工具脚本对前端工程师来说额外的学习成本很低甚至可以忽略不计,其…...
网络工程师常用软件之PING测试工具
老王说网络:网络资源共享汇总 https://docs.qq.com/sheet/DWXZiSGxiaVhxYU1F ☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝ 今天介绍一款好用的PING测试工具,ATKKPING。 ATKKPING的主要功能包括测试…...
深入探索仓颉编程语言:函数与结构类型的终极指南
引言 仓颉编程语言是一种现代化、语法精炼的编程语言,其设计目标是提供高度的灵活性与高性能的执行效率。函数与结构类型是仓颉语言的两大基础模块,也是开发者需要掌握的核心。本文将详细讲解仓颉语言中函数和结构类型的特性,辅以代码实例和…...
Java 对象的内存分配机制详解
在 Java 中,对象的内存分配是一个复杂但非常重要的过程。理解对象在堆中的分配方式,尤其是新生代和老年代的区别,对于优化 Java 应用程序的性能至关重要。本文将详细探讨 Java 对象在堆中的分配机制,包括新生代、老年代、Survivor…...
v8引擎垃圾回收
V8引擎垃圾回收机制 v8引擎负责JavaScript的执行。V8引擎具有内置的垃圾回收机制,用于自动管理内存分配和释放 堆与栈 栈空间 栈空间是小而连续的内存空间,主要用于存储局部变量和函数调用的相关信息,同时栈结构是“先进后出”的策略 栈…...
H5st5.0.0协议分析
签名核心:设备注册 5 8 9段签名校验 其中第八段主要收集了一些指纹信息 需要 对应一致 注册核心加密: fp localTk fp - 16位字符串 localTk - 92位字符串 tls指纹检测 py、js纯算皆可调用 注意:仅供学习交流,与作者无关&am…...
明达助力构建智能变电站新体系
背景概述 随着智能电网技术的飞速进步与电力需求的持续增长,变电站作为电力传输网络的核心节点,其运维效率及安全性能对电网的整体稳定运行起着决定性作用。传统的人工巡检和维护手段已难以匹配现代电网对高效性、实时性及智能化管理的迫切需求。因此&a…...
Flink优化----FlinkSQL 调优
目录 FlinkSQL 调优 1 设置空闲状态保留时间 2 开启 MiniBatch 3 开启 LocalGlobal 3.1 原理概述 3.2 提交案例:统计每天每个 mid 出现次数 3.3 提交案例:开启 miniBatch 和 LocalGlobal 4 开启 Split Distinct 4.1 原理概述 4.2 提交案例&…...
利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
智能AI电话机器人系统的识别能力现状与发展水平
一、引言 随着人工智能技术的飞速发展,AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术,在客户服务、营销推广、信息查询等领域发挥着越来越重要…...
LOOI机器人的技术实现解析:从手势识别到边缘检测
LOOI机器人作为一款创新的AI硬件产品,通过将智能手机转变为具有情感交互能力的桌面机器人,展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家,我将全面解析LOOI的技术实现架构,特别是其手势识别、物体识别和环境…...
MySQL 主从同步异常处理
阅读原文:https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主,遇到的这个错误: Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一,通常表示ÿ…...
自然语言处理——文本分类
文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益(IG) 分类器设计贝叶斯理论:线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别, 有单标签多类别文本分类和多…...
