C# Winform+Halcon结合标准视觉工具

介绍+

winform与halcon结合标准化工具实例

软件架构

软件架构说明 基于NET6 WINFORM+HALCON

实现标准化视觉检测工具

集成相机通讯

集成PLC通讯

TCP等常见通讯

支持常见halcon算子

  • 图形采集
  • blob分析
  • 高精度匹配
  • 颜色提取
  • 找几何体
  • 二维码提取
  • OCR识别
  • 等等 

输入图片说明

 。。。 

输入图片说明

安装教程

https://dotnet.microsoft.com/zh-cn/download/dotnet/6.0

使用说明

安装 NET6 SDK,编译即可运行

对入门的同学应该有较好的学习意义

本项目涵盖了标准化视觉检测工具的大部分功能,有兴趣的小伙伴可以请我吃一顿肯德基,获取源码进行学习。

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Reflection.Emit;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using HalconDotNet;
using MT_OCR5._0;
using PaddleOCRSharp;

namespace Vision.Winform.Algorithm
{   //识别各种二维码,一维码, 字符识别

    namespace MT_code
    {
        public class QR
        {
            public ToolPar toolPar = new ToolPar();
            public bool status = true;
            internal HObject image = null;

            //二维码识别句柄
            internal HTuple modelID = null;

            public string CodeType = "QR Code";
            public string ParamName = "default_parameters";
            public string ParamValue = "standard_recognition";

            private void creathandle()
            {
                try
                {
                    switch (toolPar.RunPar.QrMode)
                    {
                        case QrMode.QR:
                            CodeType = "QR Code";
                            break;
                        case QrMode.DM:
                            CodeType = "Data Matrix ECC 200";
                            break;
                    }

                    switch (toolPar.RunPar.QrRecognition)
                    {
                        case QRRecognition.standard_recognition:
                            ParamValue = "standard_recognition";
                            break;
                        case QRRecognition.enhanced_recognition:
                            ParamValue = "enhanced_recognition";
                            break;
                        case QRRecognition.maximum_recognition:
                            ParamValue = "maximum_recognition";
                            break;
                    }
                    if(modelID == null)
                    {
                        HOperatorSet.CreateDataCode2dModel((HTuple)CodeType, (HTuple)ParamName, (HTuple)ParamValue, out modelID);
                    }

                }
                catch (Exception)
                {
                    status = false;
                }

                //return 0;
            }

            private void clearhandle()
            {
                HOperatorSet.ClearDataCode2dModel(modelID);
            }

            public void run()
            {
                creathandle();
                try
                {
                    toolPar.ResultPar.CodeResult = new List<BarcodeResult>();
                    if (modelID == null)
                    {
                        status = false;
                        return;
                    }
                    if (toolPar.InputPar.图像 != null)
                    {
                        if (toolPar.InputPar.ROI != null)
                        {
                            HOperatorSet.ReduceDomain(toolPar.InputPar.图像, toolPar.InputPar.ROI, out image);
                        }
                        else
                        {
                            image = toolPar.InputPar.图像;
                        }
                        //设置极性
                        string codePolarity= "dark_on_light";
                        switch (toolPar.RunPar.CodePolarity)
                        {
                            case CodePolarity.any: codePolarity = "any"; break;
                            case CodePolarity.positive: codePolarity = "dark_on_light"; break;
                            case CodePolarity.negative: codePolarity = "light_on_dark"; break;
                        }
                        HOperatorSet.SetDataCode2dParam(modelID, "polarity", codePolarity);
                        HOperatorSet.SetDataCode2dParam(modelID, "timeout", toolPar.RunPar.TimeOut);
                        HObject xlds;
                        HTuple strtmp, resultHandles;
                        HOperatorSet.FindDataCode2d(image,
                            out xlds,
                            modelID,
                            "stop_after_result_num", toolPar.RunPar.CodeNum,
                            out resultHandles,
                            out strtmp);


                        //把结果塞进去
                        for (int i = 0; i < strtmp.Length; i++)
                        {
                            BarcodeResult tmp;
                            HObject region;
                            HOperatorSet.GenRegionContourXld(xlds, out region, "filled");
                            tmp.region = region;
                            tmp.code = strtmp[i].S;
                            toolPar.ResultPar.CodeResult.Add(tmp);
                        }
                        toolPar.ResultPar.CodeNum = strtmp.Length;

                        //HOperatorSet.clear

                    }
                    else
                    {
                        status = false;
                        return;
                    }

                }
                catch (Exception)
                {
                    clearhandle();
                    status = false;
                }
                clearhandle();
            }

            [Serializable]
            public class ToolPar : ToolParBase
            {
                private InputPar _inputPar = new InputPar();
                public InputPar InputPar
                {
                    get { return _inputPar; }
                    set { _inputPar = value; }
                }

                private RunPar _runPar = new RunPar();
                public RunPar RunPar
                {
                    get { return _runPar; }
                    set { _runPar = value; }
                }

                private ResultPar _resultPar = new ResultPar();
                public ResultPar ResultPar
                {
                    get { return _resultPar; }
                    set { _resultPar = value; }
                }
            }
            [Serializable]
            public class InputPar
            {
                private HObject _图像;
                public HObject 图像
                {
                    get { return _图像; }
                    set { _图像 = value; }
                }

                private HObject _ROI;
                public HObject ROI
                {
                    get { return _ROI; }
                    set { _ROI = value; }
                }

                private HObject _屏蔽区域;
                public HObject 屏蔽区域
                {
                    get { return _屏蔽区域; }
                    set { _屏蔽区域 = value; }
                }

                public int FindCodeNum { set; get; } = 1;


            }
            [Serializable]
            public class RunPar
            {
                public QRRecognition QrRecognition { get; set; }
                public QrMode QrMode { get; set; }
                public CodePolarity CodePolarity { get; set; }

                public int TimeOut { get; set; }

                public int CodeNum { get; set; }
            }
            [Serializable]
            public class ResultPar
            {
                private List<BarcodeResult> _CodeResult;
                public List<BarcodeResult> CodeResult
                {
                    get { return _CodeResult; }
                    set { _CodeResult = value; }
                }

                private int _CodeNum;
                public int CodeNum
                {
                    get { return _CodeNum; }
                    set { _CodeNum = value; }
                }
            }
        }

        public class One_dimension
        {
            public ToolPar toolPar = new ToolPar();
            public bool status = true;
            internal HObject image = null;

            //条形码识别句柄
            internal HTuple modelID = null;
            internal HTuple codetype = "auto";

            private void creathandle()
            {
                try
                {
                    HOperatorSet.CreateBarCodeModel(new HTuple(), new HTuple(), out modelID);
                }
                catch (Exception)
                {
                    status = false;
                }

                //return 0;
            }

            private void clearhandle()
            {
                HOperatorSet.ClearBarCodeModel(modelID);
            }

            public void run()
            {
                creathandle();
                toolPar.ResultPar.CodeResult = new List<BarcodeResult>();
                try
                {
                    if (modelID == null)
                    {
                        status = false;
                        return;
                    }
                    if (toolPar.InputPar.图像 != null)
                    {
                        if (toolPar.InputPar.ROI != null)
                        {
                            HOperatorSet.ReduceDomain(toolPar.InputPar.图像, toolPar.InputPar.ROI, out image);
                        }
                        else
                        {
                            image = toolPar.InputPar.图像;
                        }
                        HObject region;
                        HTuple strtmp;

                        HOperatorSet.SetBarCodeParam(modelID, "timeout", toolPar.RunPar.TimeOut);
                        HOperatorSet.SetBarCodeParam(modelID, "stop_after_result_num", toolPar.RunPar.CodeNum);

                        设置极性
                        //string codePolarity = "dark_on_light";
                        //switch (toolPar.RunPar.CodePolarity)
                        //{
                        //    case CodePolarity.any: codePolarity = "any"; break;
                        //    case CodePolarity.positive: codePolarity = "dark_on_light"; break;
                        //    case CodePolarity.negative: codePolarity = "light_on_dark"; break;
                        //}
                        //HOperatorSet.SetBarCodeParam(modelID, "polarity", codePolarity);
                        HOperatorSet.FindBarCode(image, out region, modelID, codetype, out strtmp);

                        //把结果塞进去
                        for (int i = 0; i < strtmp.Length; i++)
                        {
                            BarcodeResult tmp;
                            tmp.region = region;
                            tmp.code = strtmp[i].S;
                            toolPar.ResultPar.CodeResult.Add(tmp);
                        }
                        toolPar.ResultPar.CodeNum = strtmp.Length;

                        //HOperatorSet.clear

                    }
                    else
                    {
                        status = false;
                        return;
                    }

                }
                catch (Exception)
                {
                    clearhandle();
                    status = false;
                }
                clearhandle();
            }


            [Serializable]
            public class ToolPar : ToolParBase
            {
                private InputPar _inputPar = new InputPar();
                public InputPar InputPar
                {
                    get { return _inputPar; }
                    set { _inputPar = value; }
                }

                private RunPar _runPar = new RunPar();
                public RunPar RunPar
                {
                    get { return _runPar; }
                    set { _runPar = value; }
                }

                private ResultPar _resultPar = new ResultPar();
                public ResultPar ResultPar
                {
                    get { return _resultPar; }
                    set { _resultPar = value; }
                }
            }
            [Serializable]
            public class InputPar
            {
                private HObject _图像;
                public HObject 图像
                {
                    get { return _图像; }
                    set { _图像 = value; }
                }

                private HObject _ROI;
                public HObject ROI
                {
                    get { return _ROI; }
                    set { _ROI = value; }
                }

                private HObject _屏蔽区域;
                public HObject 屏蔽区域
                {
                    get { return _屏蔽区域; }
                    set { _屏蔽区域 = value; }
                }

            }
            [Serializable]
            public class RunPar
            {
                //public BarRecognition BarRecognition { get; set; }
                public BarMode BarMode { get; set; }
                public CodePolarity CodePolarity { get; set; }

                public int TimeOut { get; set; }

                public int CodeNum { get; set; }
            }
            [Serializable]
            public class ResultPar
            {
                private List<BarcodeResult> _CodeResult;
                public List<BarcodeResult> CodeResult
                {
                    get { return _CodeResult; }
                    set { _CodeResult = value; }
                }

                private int _CodeNum;
                public int CodeNum
                {
                    get { return _CodeNum; }
                    set { _CodeNum = value; }
                }
            }
        }

        public class OCR
        {
            public ToolPar toolPar = new ToolPar();
            public bool status = true;
            internal HObject image = null;
            RunPar runPar=new RunPar ();
            public void run()
            {

                try
                {
                    if (toolPar.InputPar.图像 != null)
                    {
                        if (toolPar.InputPar.ROI != null && toolPar.InputPar.屏蔽区域 != null)
                        {
                            HObject reduce_region = new HObject();
                            reduce_region.Dispose();
                            HOperatorSet.Difference(toolPar.InputPar.ROI, toolPar.InputPar.屏蔽区域, out reduce_region);
                            //image.Dispose();
                            HOperatorSet.ReduceDomain(toolPar.InputPar.图像, reduce_region, out image);
                            HOperatorSet.CropDomain(image, out image);
                            reduce_region.Dispose();
                        }
                        else if (toolPar.InputPar.ROI != null && toolPar.InputPar.屏蔽区域 == null)
                        {
                            HOperatorSet.GenEmptyObj(out image);
                            HOperatorSet.ReduceDomain(toolPar.InputPar.图像, toolPar.InputPar.ROI, out image);
                            HOperatorSet.CropDomain(image, out image);
                        }
                        else if (toolPar.InputPar.ROI == null && toolPar.InputPar.屏蔽区域 != null)
                        {
                            HObject reduce_region = new HObject();
                            reduce_region.Dispose();
                            HOperatorSet.Difference(toolPar.InputPar.图像, toolPar.InputPar.屏蔽区域, out reduce_region);
                            //image.Dispose();
                            HOperatorSet.ReduceDomain(toolPar.InputPar.图像, reduce_region, out image);
                            HOperatorSet.CropDomain(image, out image);
                            reduce_region.Dispose();
                        }
                        else
                        {
                            if (image != null)
                                image.Dispose();
                            image = toolPar.InputPar.图像;
                        }
                    }
                    else
                    {
                        status = false;
                        return;
                    }
                    //初始化
                    //ocr_engine.OCR_INIT();
                    //HObject img;
                    //HOperatorSet.GenEmptyObj(out img);
                    //img = image;
                    检测
                    //string ocr_result = ocr_engine.OCR_Dect(img);
                    //ocr_engine.engine.Dispose();
                    //toolPar.ResultPar.OCRResult = ocr_result;
                    //ocr_result = String.Empty;

                    HOperatorSet.CountChannels(image, out var channels);
                    Bitmap img;
                    HObject multiChannelImage;
                    HOperatorSet.GenEmptyObj(out multiChannelImage);
                    if (channels == 3)
                    {
                        img=runPar.Honject2Bitmap24(image);
                    }
                    else
                    {
                        HOperatorSet.Compose3(image, image, image, out multiChannelImage);
                        img = runPar.Honject2Bitmap24(multiChannelImage);
                    }
                    runPar.ocrResult= runPar.engine.DetectText(img);
                    toolPar.ResultPar.OCRResult = runPar.ocrResult.Text;
                }
                catch (Exception)
                {
                    status = false;
                }
            }

            [Serializable]
            public class ToolPar : ToolParBase
            {
                private InputPar _inputPar = new InputPar();
                public InputPar InputPar
                {
                    get { return _inputPar; }
                    set { _inputPar = value; }
                }

                private RunPar _runPar = new RunPar();
                public RunPar RunPar
                {
                    get { return _runPar; }
                    set { _runPar = value; }
                }

                private ResultPar _resultPar = new ResultPar();
                public ResultPar ResultPar
                {
                    get { return _resultPar; }
                    set { _resultPar = value; }
                }
            }
            [Serializable]
            public class InputPar
            {
                private HObject _图像;
                public HObject 图像
                {
                    get { return _图像; }
                    set { _图像 = value; }
                }

                private HObject _ROI;
                public HObject ROI
                {
                    get { return _ROI; }
                    set { _ROI = value; }
                }

                private HObject _屏蔽区域;
                public HObject 屏蔽区域
                {
                    get { return _屏蔽区域; }
                    set { _屏蔽区域 = value; }
                }
            }
            [Serializable]
            public class RunPar
            {
                public OCRModelConfig config = null;

                public OCRParameter oCRParameter = new OCRParameter();

                public OCRResult ocrResult = new OCRResult();

                public PaddleOCREngine engine;

                public RunPar()
                {
                    engine = new PaddleOCREngine(config, oCRParameter);
                }

                [DllImport("kernel32.dll")]
                public static extern void CopyMemory(int Destination, int add, int Length);

                public Bitmap Honject2Bitmap24(HObject hObject)
                {
                    HTuple width = new HTuple();
                    HTuple height = new HTuple();
                    HTuple pointer = new HTuple();
                    HTuple type = new HTuple();
                    HTuple width2 = new HTuple();
                    HTuple height2 = new HTuple();
                    HObject interleavedImage = new HObject();
                    HOperatorSet.GetImageSize(hObject, out width, out height);
                    HOperatorSet.InterleaveChannels(hObject, out interleavedImage, "rgb", 4 * width, 0);
                    HOperatorSet.GetImagePointer1(interleavedImage, out pointer, out type, out width2, out height2);
                    IntPtr scan = pointer;
                    return new Bitmap(width2 / 4, height2, width2, PixelFormat.Format24bppRgb, scan);
                }

                public void HObject2Bitmap8(HObject image, out Bitmap res)
                {
                    HOperatorSet.GetImagePointer1(image, out var pointer, out var _, out var width, out var height);
                    res = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
                    ColorPalette palette = res.Palette;
                    for (int i = 0; i <= 255; i++)
                    {
                        palette.Entries[i] = Color.FromArgb(255, i, i, i);
                    }

                    res.Palette = palette;
                    System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, width, height);
                    BitmapData bitmapData = res.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
                    int num = Image.GetPixelFormatSize(bitmapData.PixelFormat) / 8;
                    IntPtr scan = bitmapData.Scan0;
                    IntPtr source = pointer;
                    int num2 = width * height;
                    byte[] array = new byte[num2];
                    Marshal.Copy(source, array, 0, num2);
                    Marshal.Copy(array, 0, scan, num2);
                    res.UnlockBits(bitmapData);
                }
            }
            [Serializable]
            public class ResultPar
            {
                private string _OCRResult { get; set; }
                public string OCRResult { get { return _OCRResult; } set { _OCRResult = value; } }
            }

        }

    }
}
 

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

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

相关文章

C++哈希(个人笔记)

C哈希 1.unordered_mapd1.1unordered_map的构造函数1.2unorder_map的容量1.3unordered_map的迭代器1.4unordered_map的元素访问1.5unorder_map的查找1.6unordered_map的修改操作1.7unordered_map的桶操作 2.unordered_set3.unordered_set和unordered_set的笔试题4.哈希4.1哈希概…

LVS负载均衡超详细入门介绍

LVS 一、LVS入门介绍 1.1.LVS负载均衡简介 1.2.负载均衡的工作模式 1.2.1.地址转换NAT&#xff08;Network Address Translation&#xff09; 1.2.2.IP隧道TUN&#xff08;IP Tunneling&#xff09; 1.2.3.直接路由DR&#xff08;Direct Routing&#xff09; 1.3.…

AI图像生成-原理

一、图像生成流程总结 【AI绘画】深入理解Stable Diffusion&#xff01;站内首个深入教程&#xff0c;30分钟从原理到模型训练 买不到的课程_哔哩哔哩_bilibili 二、如果只是用comfy UI生成图片 1、找到下面几个文件&#xff0c;把对应模型移动到对应文件夹即可使用 2、选择对…

(八)SQL基础知识练习题(选择题)(下)#CDA学习打卡

本文整理了SQL基础知识相关的练习题&#xff0c;共133道&#xff0c;可作为CDA一级的补充习题&#xff0c;也适用于刚入门初级SQL想巩固基础的同学。来源&#xff1a;如荷学数据科学题库&#xff08;技术专项-SQL&#xff09;。暂时按照原题库顺序present&#xff0c;如有需要之…

Android XML的使用详解

一、布局文件&#xff1a; 在layout目录下&#xff0c;使用比较广泛&#xff1b;我们可以为应用定义两套或多套布局&#xff0c;例如&#xff1a;可以新建目录layout_land(代表手机横屏布局)&#xff0c;layout_port(代表手机竖屏布局)&#xff0c;系统会根据不同情况自动找到…

Linux安装MySQL(CentOS 7)

安装步骤 下载的MySQL版本为mysql-8.0.26 进入网站MySQL&#xff0c;点击下载 找到mysql社区版 点击Archive&#xff0c;查看所有相关不同版本 点击MySQL Community Server 注意下载MySQL对应的Linux版本&#xff0c;CentOS7 对应 Linux7&#xff0c;如果下成Linux 8 则后面…

【文末福利送资料】深度探索GPT模型,竟然10个字都不会说?

目录 导读 自回归模型 那么什么时候停下呢&#xff1f; 该停下来&#xff0c;但是概率不让啊 GPT欠缺的两种能力 目录 导读 自回归模型 那么什么时候停下呢&#xff1f; 该停下来&#xff0c;但是概率不让啊 GPT欠缺的两种能力 缺少规划 反省和修订 所有的人工智能…

Flume 的安装和使用方法(Spark-2.1.0)

一、Flume的安装 1.下载压缩包 https://www.apache.org/dyn/closer.lua/flume/1.7.0/apache-flume-1.7.0-bin.tar.gz 2.上传到linux中 3.解压安装包 cd #进入加载压缩包目录sudo tar -zxvf apache-flume-1.7.0-bin.tar.gz -C /usr/local # 将 apache-flume-1.7.0-bin.tar.g…

透明加密软件推荐:哪款实用又高效?

透明加密软件是一种专门针对文件保密需求的计算机加密工具。 其核心在于“透明”二字&#xff0c;意味着整个加密过程对于使用者来说是无形且无感知的。 当用户进行文件的日常操作&#xff0c;如打开、编辑或保存时&#xff0c;透明加密软件会在后台自动进行加密和解密工作&a…

Microsoft Edge浏览器,便携增强版 v118.0.5993.69

01 软件介绍 Microsoft Edge浏览器&#xff0c;便携增强版&#xff0c;旨在无需更新组件的情况下提供额外的功能强化。这一增强版专注于优化用户体验和系统兼容性&#xff0c;具体包含以下核心功能的提升&#xff1a; 数据保存&#xff1a;通过优化算法增强了其数据保存能力&…

AI系列:大语言模型的RAG(检索增强生成)技术(下)-- 使用LlamaIndex

目录 前言什么是LlamaIndex?LlamaIndex代码设置embedding模型设置LLM模型索引查询机 验证使用感受参考资料 前言 继上一篇文章AI系列&#xff1a;大语言模型的RAG&#xff08;检索增强生成&#xff09;技术&#xff08;上&#xff09;&#xff0c;这篇文章主要以LlamaIndex为…

2024最新网络安全零基础入门学习路线,学网安看这篇就够了!

前言 一、什么是网络安全 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“ 安全运维”则研究防御技术。 无论网络、Web、移动、桌面、云等哪个领域&#xff0c;都有攻与…

高通QCC3071 ANC调试录音新方法

1, 从QCC307X和QCC517X的芯片开始ANC调试录音不再使用QACT软件了,而是使用Qualcomm ANC Filter Designer使用耳机进入Recording模式,再使用第三方的音频编辑软件来播放和录取声音。 2, 本文以QCC3071做Hybrid ANC,FF MIC使用数字MIC FB MIC使用模拟MEMS MIC为例来讲解具体…

IDEA里面数据库编辑数据库链接/重命名库的操作

选中数据库图标&#xff0c;点击号&#xff0c;打开MySql 图片的每一处都可以修改&#xff0c;改完再点test connection&#xff0c;没问题再点确定按钮就可以

4万字一文带你看懂车载摄像头技术、市场、发展前景

1、小孔成像 在战国初期&#xff0c;我国学者墨子&#xff08;公元前468年-公元前376年&#xff09;和弟子们完成了世界上第一个小孔成像的实验&#xff0c;并记录在《墨经》中&#xff1a;“景到&#xff0c;在午有端&#xff0c;与景长。说在端。”“景。光之人&#xff0c;煦…

从旺店通·企业奇门到金蝶云星空通过接口配置打通数据

从旺店通企业奇门到金蝶云星空通过接口配置打通数据 接通系统&#xff1a;旺店通企业奇门 慧策最先以旺店通ERP切入商家核心管理痛点——订单管理&#xff0c;之后围绕电商经营管理中的核心管理诉求&#xff0c;先后布局流量获取、会员管理、仓库管理等其他重要经营模块。慧策的…

Spring事务和事务传播机制(@Transactional)

文章目录 Spring事务&#xff08;Transactional详解&#xff09;什么是事务为什么需要事务事务的操作(sql) Spring中的事务实现Spring编程式事务Spring声明式事务 TransactionalTransactional可以用来修饰方法或类对异常进行捕获细节&#xff1a; Transactional详解三个属性1. …

牛客NC363 开锁【中等 BFS Java/Go/PHP】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/e7cbabbf7e0a41ec98055ee5f3d33bbe https://www.lintcode.com/problem/796 思路 Java代码 import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#x…

在PyQt5中实现点击按钮打开新窗口功能—窗口的跳转功能实现

百度搜索“pyqt5中如何点击按钮打开新的窗口”&#xff0c;自动生成以下参考代码。 在PyQt5中&#xff0c;要实现点击按钮打开新窗口&#xff0c;你需要定义一个新的窗口类&#xff0c;并在按钮的点击信号&#xff08;clicked&#xff09;处理函数中创建并显示这个新窗口。以下…

Eclipse 里如何建立SAP应用服务层的CDS

关于Core Data Service(CDS) CDS:Core Data Ser vice.核心数据服务。CDS 是使用基于 SQL的数据定义语言(DDL)定义的&#xff0c;该语言基于标准 SQL 并带有一些附加概念。使用类似 SQL的灵活表达式可以进行复杂的数据建模。有两种类型的 CDS:ABAP CDS 和 HANA CDS。 S/4 HANA…