C# OpenCvSharp DNN 卡证检测矫正

news2024/12/27 11:53:48

目录

说明

效果

模型

项目

代码

下载

参考


说明

源码地址: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 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);
            }
        }
    }
}

下载

源码下载

参考

https://github.com/hpc203/cv_resnet_carddetection_scrfd34gkps-opencv-dnn

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

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

相关文章

前端入门之VUE--ajax、vuex、router,最后的前端总结

前言 VUE是前端用的最多的框架&#xff1b;这篇文章是本人大一上学习前端的笔记&#xff1b;欢迎点赞 收藏 关注&#xff0c;本人将会持续更新。本人不是学前端的&#xff0c;这个是大一的时候上学的和做的笔记&#xff0c;那个时候学的也蒙&#xff0c;故这里对前端做一个总…

要查询 `user` 表中 `we_chat_subscribe` 和 `we_chat_union_id` 列不为空的用户数量

文章目录 1、we_chat_subscribe2、we_chat_union_id 1、we_chat_subscribe 要查询 user 表中 we_chat_subscribe 列不为空的用户数量&#xff0c;你可以使用以下 SQL 查询语句&#xff1a; SELECT COUNT(*) FROM user WHERE we_chat_subscribe IS NOT NULL;解释&#xff1a; …

RocketMQ的集群架构是怎样的?

大家好&#xff0c;我是锋哥。今天分享关于【RocketMQ的集群架构是怎样的?】面试题。希望对大家有帮助&#xff1b; RocketMQ的集群架构是怎样的? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 RocketMQ 是阿里巴巴开源的分布式消息中间件&#xff0c;广泛用于处…

使用DynadotAPI查看域名清仓中的过期域名列表

前言 Dynadot是通过ICANN认证的域名注册商&#xff0c;自2002年成立以来&#xff0c;服务于全球108个国家和地区的客户&#xff0c;为数以万计的客户提供简洁&#xff0c;优惠&#xff0c;安全的域名注册以及管理服务。 Dynadot平台操作教程索引&#xff08;包括域名邮箱&…

uni-app 中使用微信小程序第三方 SDK 及资源汇总

&#x1f380;&#x1f380;&#x1f380;uni-app 跨端开发系列 &#x1f380;&#x1f380;&#x1f380; 一、uni-app 组成和跨端原理 二、uni-app 各端差异注意事项 三、uni-app 离线本地存储方案 四、uni-app UI库、框架、组件选型指南 五、uni-app 蓝牙开发 六、uni-app …

探索 Pencils Swap 的叙事:为 DeFi 的再次爆发蓄力

Pencils Protocol 最初是 Scroll 生态上一个综合性的 DeFi 平台&#xff0c;以 Farming、Vaults 以及 Auction 等系列产品板块为基础&#xff0c;其不仅成为了 Scroll 上重要的流动性、收益枢纽&#xff0c;同时也是重要的 LaunchPad 市场以及流量池&#xff0c;为 Scroll 生态…

基于STM32单片机矿井矿工作业安全监测设计

基于STM32单片机矿井矿工作业安全监测设计 目录 项目开发背景设计实现的功能项目硬件模块组成设计思路系统功能总结使用的模块技术详情介绍总结 1. 项目开发背景 随着矿井矿工作业环境的复杂性和危险性逐渐增加&#xff0c;矿井作业安全问题引起了社会各界的广泛关注。传统的…

数学建模与数学建模竞赛

什么是数学建模&#xff1f; 数学建模是通过数学的方法和工具&#xff0c;对现实世界的一个特定对象&#xff0c;依据其内在规律&#xff0c;做出一些必要的简化假设&#xff0c;从而建立一个数学结构的过程。数学建模的历史和数学的起源几乎同步开始&#xff0c;2000多年前&a…

stm32四联七段数码管,LED8*8点阵

一、七段数码管的整体代码和仿真 1&#xff09;代码 seg74.c #include "stm32f10x.h" // Device headervoid seg74_init(void) {GPIO_InitTypeDef GPIO_InitStruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(…

SpringCloudAlibaba技术栈-Dubbo

1、什么是Dubbo? 简单来说&#xff0c;dubbo就像是个看不见的手&#xff0c;负责专门从注册中心nacos调用注册到nacos上面的服务的&#xff0c;因为在微服务环境下不同的功能模块可能在不同的服务器上。dubbo调用服务就像是在调用本地的服务一样。 分布式调用与高并发处理 Du…

“AI智能安全管理系统:让安全无处不在

嘿&#xff0c;大家好&#xff01;今天咱们来聊聊一个超级酷炫又至关重要的东西——AI智能安全管理系统。想象一下&#xff0c;如果有一个系统可以像私人保镖一样24小时不间断地保护你和你的财产&#xff0c;是不是感觉特别安心&#xff1f;这就是AI智能安全管理系统带给我们的…

【hackmyvm】soul靶机wp

tags: HMVrbash绕过图片隐写PHP配置解析 1. 基本信息^toc 文章目录 1. 基本信息^toc2. 信息收集3. 图片解密3.1. 爆破用户名3.2. 绕过rbash3.3. 提权检测 4. 获取webshell4.1. 修改php配置 5. www-data提权gabriel6. gabriel提取到Peter7. Peter提权root 靶机链接 https://ha…

PaddleOCR训练自己的私有数据集(包括标注、制作数据集、训练及应用)

目录 一、制作数据集 1、进入到PaddleOCR-releas-2.7目录 2、首先启用PPOCRLabel&#xff1a;在终端激活环境 3、接着点击左下角的自动标注 4、确认完成后点击左上角 5、新建gen_ocr_train_val_test.py 二、训练文字检测模型 1、模型下载 2.、配置ppocr检测模型文件 …

网络层协议--ip协议

目录 引言 IP协议 协议头格式 16位标识与3位标志与13位片偏移讲解 网段划分(重要) DHCP技术 CIDR技术 特殊的IP地址 广播主机 IP地址的数量限制 私有IP地址和公网IP地址 路由&#xff1a;在复杂的网络结构中, 找出一条通往终点的路线 简单认识路由器 路由表生成算…

区块链期末复习3.2:比特币脚本

目录 一、输入输出脚本的执行 二、简单脚本实例及压栈过程 1.P2PK&#xff08;pay to public key hash&#xff09; 2、P2PH&#xff08;pay to public key hash&#xff09; 3.多重签名 4.比特币脚本的应用&#xff1a; 三、其他常见指令 1.OP_EQUAL与OP&#xff3f;EQ…

【Mac】终端改色-让用户名和主机名有颜色

效果图 配置zsh 1.打开终端&#xff0c;进入.zshrc配置 cd ~ vim .zshrc2.添加如下配置并保存 # 启用命令行颜色显示 export CLICOLOR1 ## 加载颜色支持 autoload -U colors && colors # 配置 zsh 提示符 PROMPT"%{$fg_bold[red]%}%n%{$reset_color%}%{$fg_bol…

CUDA各种内存和使用方法

文章目录 1、全局内存2、局部内存3、共享内存3.1 静态共享内存3.2 动态共享内存 4、纹理内存5、常量内存6、寄存器内存7、用CUDA运行时API函数查询设备CUDA 错误检测 1、全局内存 特点&#xff1a;容量最大&#xff0c;访问延时最大&#xff0c;所有线程都可以访问。 线性内存…

青少年科普教学系统平台的设计与实现springboot

摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对高校教师成果信息管理混乱&#xff0c;出错率高&#xff0c;信息安…

Vue2:v-for创建echart图表时不能使用动态ref,要使用动态id

项目中需要创建一组图表+表格的组合,一共15组,为了便于维护,希望使用v-for来创建,而不是写出15组<div>,但是动态指定echart的ref时,频繁遭遇init失败,提示“TypeError: this.dom.getContext is not a function”。过程记录如下。 实现效果 要实现的效果如下图,…

Ch9 形态学图像处理

Ch9 形态学图像处理 blog点此处&#xff01;<--------- 四大算子相应性质。 腐蚀、膨胀、开闭之间的含义、关系 文章目录 Ch9 形态学图像处理预备知识(Preliminaries)膨胀和腐蚀(Dilation and Erosion)腐蚀膨胀膨胀与腐蚀的对偶关系 开闭操作(Opening and Closing)开运算闭…