visionpro脚本

visionproToolBlock的脚本的优先级优于工具连线的优先级,一般是照着脚本的执行顺序进行执行对应的工具,最常用的是C#的高级脚本,C#的脚本如下分为5部分。

第一部分:主要是一些库的引用,对于有些类型不知道库的时候,可以通过查询帮助文档输入对应的名称,查询到具体信息,其中就包含他所在的库;

第二部分:主要是一些全局变量的声明,包括标签工具、一些数据类型的声明等等,这里还声明了一个ToolBlock工具,用于该Block的工具的定义、声明、获取Record等用途;

第三部分:主要对基类中的函数进行重写;

第四部分:主要对当前的Record进行操作;

第五部分:主要对整个ToolBlock中的工具运行完成之后的最终结果进行操作,主要包括了标签操作、循环运行时中间结果的保留并附着在最终结果上等。

本片文章主要是进行两个ToolBlock的实现,包含计算两个点之间的距离,寻找某个特征点的坐标。

ToolBlock1

ToolBlock1主要是进行三角形的一个顶点到正方形顶点的距离测量,检测效果如下:

对于该任务,首先需要对三角形进行特征匹配,特征匹配完成之后,根据特征匹配建立一个新的坐标系,该坐标系+之前所建立的坐标系可以完成该图旋转,放大和缩小后的对应特征检测,再根据在这两个坐标系下的定位,找到对应矩形的顶点,完成距离的检测,对应的工作流程如图所示:

该过程基本没有连线操作,主要是通过脚本实现对应的功能,脚本代码如下:

#region namespace imports
using System;
using System.Collections;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using Cognex.VisionPro;
using Cognex.VisionPro.ToolBlock;
using Cognex.VisionPro3D;
using Cognex.VisionPro.CalibFix;
using Cognex.VisionPro.PMAlign;
using Cognex.VisionPro.Caliper;
using Cognex.VisionPro.Dimensioning;
#endregionpublic class CogToolBlockAdvancedScript : CogToolBlockAdvancedScriptBase
{#region Private Member Variablesprivate Cognex.VisionPro.ToolBlock.CogToolBlock mToolBlock;CogGraphicLabel mylabel = new CogGraphicLabel();#endregion/// <summary>/// Called when the parent tool is run./// Add code here to customize or replace the normal run behavior./// </summary>/// <param name="message">Sets the Message in the tool's RunStatus.</param>/// <param name="result">Sets the Result in the tool's RunStatus</param>/// <returns>True if the tool should run normally,///          False if GroupRun customizes run behavior</returns>public override bool GroupRun(ref string message, ref CogToolResultConstants result){// To let the execution stop in this script when a debugger is attached, uncomment the following lines.// #if DEBUG// if (System.Diagnostics.Debugger.IsAttached) System.Diagnostics.Debugger.Break();// #endif// Run each tool using the RunTool function//foreach(ICogTool tool in mToolBlock.Tools)try{CogPMAlignTool cpmatool = mToolBlock.Tools["CogPMAlignTool1"] as CogPMAlignTool;cpmatool.InputImage = (CogImage8Grey) mToolBlock.Inputs["OutputImage"].Value;cpmatool.Run();if(cpmatool.Results.Count != 1){mToolBlock.Outputs["strerr"].Value = "block1 cpmatool fail";return false;}CogFixtureTool cfixtool2 = mToolBlock.Tools["CogFixtureTool2"] as CogFixtureTool;cfixtool2.RunParams.UnfixturedFromFixturedTransform = cpmatool.Results[0].GetPose();cfixtool2.InputImage = cpmatool.InputImage;cfixtool2.Run();if(cfixtool2.InputImage == null){mToolBlock.Outputs["strerr"].Value = "block1 cfixtool2 fail";return false;}//找点1CogFindLineTool cfindltool1 = mToolBlock.Tools["CogFindLineTool1"] as CogFindLineTool;cfindltool1.InputImage = (CogImage8Grey) cpmatool.InputImage;cfindltool1.Run();if(cfindltool1.RunStatus.Result != CogToolResultConstants.Accept){mToolBlock.Outputs["strerr"].Value = "block1 cfindltool1 fail";return false;}CogFindLineTool cfindltool2 = mToolBlock.Tools["CogFindLineTool2"] as CogFindLineTool;cfindltool2.InputImage = (CogImage8Grey) cpmatool.InputImage;cfindltool2.Run();if(cfindltool2.RunStatus.Result != CogToolResultConstants.Accept){mToolBlock.Outputs["strerr"].Value = "block1 cfindltool2 fail";return false;}CogIntersectLineLineTool cinterlinetool1 = mToolBlock.Tools["CogIntersectLineLineTool1"] as CogIntersectLineLineTool;cinterlinetool1.InputImage = (CogImage8Grey) cpmatool.InputImage;cinterlinetool1.LineA = cfindltool1.Results.GetLine();cinterlinetool1.LineB = cfindltool2.Results.GetLine();cinterlinetool1.Run();if(cinterlinetool1.RunStatus.Result != CogToolResultConstants.Accept){mToolBlock.Outputs["strerr"].Value = "block1 cinterlinetool1 fail";return false;}//寻找点2CogFindLineTool cfindltool3 = mToolBlock.Tools["CogFindLineTool3"] as CogFindLineTool;cfindltool3.InputImage = (CogImage8Grey) cpmatool.InputImage;cfindltool3.Run();if(cfindltool3.RunStatus.Result != CogToolResultConstants.Accept){mToolBlock.Outputs["strerr"].Value = "block1 cfindltool3 fail";return false;}CogFindLineTool cfindltool4 = mToolBlock.Tools["CogFindLineTool4"] as CogFindLineTool;cfindltool4.InputImage = (CogImage8Grey) cpmatool.InputImage;cfindltool4.Run();if(cfindltool4.RunStatus.Result != CogToolResultConstants.Accept){mToolBlock.Outputs["strerr"].Value = "block1 cfindltool4 fail";return false;}CogIntersectLineLineTool cinterlinetool2 = mToolBlock.Tools["CogIntersectLineLineTool2"] as CogIntersectLineLineTool;cinterlinetool2.InputImage = (CogImage8Grey) cpmatool.InputImage;cinterlinetool2.LineA = cfindltool3.Results.GetLine();cinterlinetool2.LineB = cfindltool4.Results.GetLine();cinterlinetool2.Run();if(cinterlinetool2.RunStatus.Result != CogToolResultConstants.Accept){mToolBlock.Outputs["strerr"].Value = "block1 cinterlinetool2 fail";return false;}//计算点与点之间的距离CogDistancePointPointTool cdistpptool = mToolBlock.Tools["CogDistancePointPointTool1"] as CogDistancePointPointTool;cdistpptool.InputImage = (CogImage8Grey) cpmatool.InputImage;cdistpptool.StartX = cinterlinetool1.X;cdistpptool.StartY = cinterlinetool1.Y;cdistpptool.EndX = cinterlinetool2.X;cdistpptool.EndY = cinterlinetool2.Y;cdistpptool.Run();if(cdistpptool.RunStatus.Result != CogToolResultConstants.Accept){mToolBlock.Outputs["strerr"].Value = "block1 cdistpptool fail";return false;}mToolBlock.Outputs["strerr"].Value = "success";mToolBlock.Outputs["distance"].Value = cdistpptool.Distance;mylabel.SetXYText(50, 20, "宽度" + cdistpptool.Distance.ToString("F2"));mylabel.Color = CogColorConstants.Cyan;mylabel.Font = new Font("楷体", 15);}catch(Exception e){mToolBlock.Outputs["strerr"].Value = "fail";}return false;}#region When the Current Run Record is Created/// <summary>/// Called when the current record may have changed and is being reconstructed/// </summary>/// <param name="currentRecord">/// The new currentRecord is available to be initialized or customized.</param>public override void ModifyCurrentRunRecord(Cognex.VisionPro.ICogRecord currentRecord){}#endregion#region When the Last Run Record is Created/// <summary>/// Called when the last run record may have changed and is being reconstructed/// </summary>/// <param name="lastRecord">/// The new last run record is available to be initialized or customized.</param>public override void ModifyLastRunRecord(Cognex.VisionPro.ICogRecord lastRecord){mToolBlock.AddGraphicToRunRecord(mylabel,lastRecord,"CogPMAlignTool1.InputImage"," ");}#endregion#region When the Script is Initialized/// <summary>/// Perform any initialization required by your script here/// </summary>/// <param name="host">The host tool</param>public override void Initialize(Cognex.VisionPro.ToolGroup.CogToolGroup host){// DO NOT REMOVE - Call the base class implementation first - DO NOT REMOVEbase.Initialize(host);// Store a local copy of the script hostthis.mToolBlock = ((Cognex.VisionPro.ToolBlock.CogToolBlock)(host));}#endregion}

 对应工具的声明和他所有的成员均可以通过在外面的工具,添加终端中寻找,他所有的成员方法均在此地方能找到。

 ToolBlock2

ToolBlock2实现的主要功能是对三个字符‘R’的左下角进行定位,包含了特征匹配,找线,找交点等操作。结果如下图所示:

对于该任务首先需要特征匹配,匹配完成之后,找线,找交点,对于工具连线操作而言,是无法进行循环操作的,所以此时就必须使用脚本进行操作,才能将三个点均找出。工具和代码如下所示:

脚本代码如下所示:

#region namespace imports
using System;
using System.Collections;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using Cognex.VisionPro;
using Cognex.VisionPro.ToolBlock;
using Cognex.VisionPro3D;
using Cognex.VisionPro.CalibFix;
using Cognex.VisionPro.PMAlign;
using Cognex.VisionPro.Caliper;
using Cognex.VisionPro.Dimensioning;
using System.Collections.Generic;
#endregionpublic class CogToolBlockAdvancedScript : CogToolBlockAdvancedScriptBase
{#region Private Member Variablesprivate Cognex.VisionPro.ToolBlock.CogToolBlock mToolBlock;CogGraphicLabel mylabel = new CogGraphicLabel();private List<ICogRecord> records = new List<ICogRecord>();#endregion/// <summary>/// Called when the parent tool is run./// Add code here to customize or replace the normal run behavior./// </summary>/// <param name="message">Sets the Message in the tool's RunStatus.</param>/// <param name="result">Sets the Result in the tool's RunStatus</param>/// <returns>True if the tool should run normally,///          False if GroupRun customizes run behavior</returns>public override bool GroupRun(ref string message, ref CogToolResultConstants result){// To let the execution stop in this script when a debugger is attached, uncomment the following lines.// #if DEBUG// if (System.Diagnostics.Debugger.IsAttached) System.Diagnostics.Debugger.Break();// #endifmToolBlock.Outputs["strerr"].Value = "";string str = "";try{CogPMAlignTool cpmatool = mToolBlock.Tools["CogPMAlignTool1"] as CogPMAlignTool;cpmatool.InputImage = (ICogImage) mToolBlock.Inputs["InputImage"].Value;cpmatool.Run();if(cpmatool.Results.Count != 3){mToolBlock.Outputs["strerr"].Value = "block2 cpmatool fail";return false;}records.Clear();for(int i = 0;i < cpmatool.Results.Count;i++){CogFixtureTool cfixtool2 = mToolBlock.Tools["CogFixtureTool2"] as CogFixtureTool;cfixtool2.RunParams.UnfixturedFromFixturedTransform = cpmatool.Results[i].GetPose();cfixtool2.InputImage = cpmatool.InputImage;cfixtool2.Run();if(cfixtool2.InputImage == null){mToolBlock.Outputs["strerr"].Value = "block2 cfixtool2 fail";return false;}CogFindLineTool cfindltool1 = mToolBlock.Tools["CogFindLineTool1"] as CogFindLineTool;cfindltool1.InputImage = (CogImage8Grey) cpmatool.InputImage;cfindltool1.Run();if(cfindltool1.RunStatus.Result != CogToolResultConstants.Accept){mToolBlock.Outputs["strerr"].Value = "block2 cfindltool1 fail";return false;}CogFindLineTool cfindltool2 = mToolBlock.Tools["CogFindLineTool2"] as CogFindLineTool;cfindltool2.InputImage = (CogImage8Grey) cpmatool.InputImage;cfindltool2.Run();if(cfindltool2.RunStatus.Result != CogToolResultConstants.Accept){mToolBlock.Outputs["strerr"].Value = "block2 cfindltool2 fail";return false;}CogIntersectLineLineTool cinterlinetool1 = mToolBlock.Tools["CogIntersectLineLineTool1"] as CogIntersectLineLineTool;cinterlinetool1.InputImage = cpmatool.InputImage;cinterlinetool1.LineA = cfindltool1.Results.GetLine();cinterlinetool1.LineB = cfindltool2.Results.GetLine();cinterlinetool1.Run();if(cinterlinetool1.Intersects == false){mToolBlock.Outputs["strerr"].Value = "block2 cinterlinetool1 fail";return false;}PointF p1 = (new PointF(float.Parse(cinterlinetool1.X.ToString("F2")), float.Parse(cinterlinetool1.Y.ToString("F2"))));str += p1.ToString();mToolBlock.Outputs["strerr"].Value = "success";records.Add(cinterlinetool1.CreateLastRunRecord());}mToolBlock.Outputs["respoint"].Value = str;mylabel.SetXYText(50, 5, "坐标" + str);mylabel.Color = CogColorConstants.Black;mylabel.Font = new Font("楷体", 10);}catch(Exception e){str = "Exception: {e.Message}";mToolBlock.Outputs["strerr"].Value = str;}return false;}#region When the Current Run Record is Created/// <summary>/// Called when the current record may have changed and is being reconstructed/// </summary>/// <param name="currentRecord">/// The new currentRecord is available to be initialized or customized.</param>public override void ModifyCurrentRunRecord(Cognex.VisionPro.ICogRecord currentRecord){}#endregion#region When the Last Run Record is Created/// <summary>/// Called when the last run record may have changed and is being reconstructed/// </summary>/// <param name="lastRecord">/// The new last run record is available to be initialized or customized.</param>public override void ModifyLastRunRecord(Cognex.VisionPro.ICogRecord lastRecord){     lastRecord.SubRecords[0].SubRecords.Clear();for(int i = 0;i < 3;i++){lastRecord.SubRecords[0].SubRecords.Add(records[i]);}mToolBlock.AddGraphicToRunRecord(mylabel, lastRecord, "CogPMAlignTool1.InputImage", " ");}#endregion#region When the Script is Initialized/// <summary>/// Perform any initialization required by your script here/// </summary>/// <param name="host">The host tool</param>public override void Initialize(Cognex.VisionPro.ToolGroup.CogToolGroup host){// DO NOT REMOVE - Call the base class implementation first - DO NOT REMOVEbase.Initialize(host);// Store a local copy of the script hostthis.mToolBlock = ((Cognex.VisionPro.ToolBlock.CogToolBlock)(host));}#endregion}

 循环主要是针对特征匹配到的R的数量进行循环次数操作的,这里需要注意,因为visionpro在进行操作的时候,会将之前找到的交点的痕迹覆盖掉,因此需要将中间过程的Record记录下来,因此在一开始需要声明 private List<ICogRecord> records = new List<ICogRecord>()对中间过程的Record记录,添加到列表的操作:records.Add(cinterlinetool1.CreateLastRunRecord()),然后需要在最后lastrunrecord上记录:

public override void ModifyLastRunRecord(Cognex.VisionPro.ICogRecord lastRecord){     lastRecord.SubRecords[0].SubRecords.Clear();for(int i = 0;i < 3;i++){lastRecord.SubRecords[0].SubRecords.Add(records[i]);}mToolBlock.AddGraphicToRunRecord(mylabel, lastRecord, "CogPMAlignTool1.InputImage", " ");}

注意这里的SubRecoRecordrds[i]的编号表示需要在第几个工具结果上添加记录下来的Record,还应该注意标签放置操作应该在这个操作之后,在这个操作之前会被clear掉。

OuterBlock

有时候可能一个工程文件中有多个Block模块,此时需要在外层套一个Block,将所有子Block包含,并且可能不同的Block对应不同的照片进行执行,为了便于在最外层查看lastrunrecord,一般将所有子Block的第一个CogFixtureTool挪动到OuterBlock中,再将其OutputImage传入到各个子Block中,如下所示:

 为了更好的控制某个Block的执行,一般需要在外面添加参数并且通过脚本进行控制实现:

#region namespace imports
using System;
using System.Collections;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using Cognex.VisionPro;
using Cognex.VisionPro.ToolBlock;
using Cognex.VisionPro3D;
using Cognex.VisionPro.CalibFix;
#endregionpublic class CogToolBlockAdvancedScript : CogToolBlockAdvancedScriptBase
{#region Private Member Variablesprivate Cognex.VisionPro.ToolBlock.CogToolBlock mToolBlock;#endregion/// <summary>/// Called when the parent tool is run./// Add code here to customize or replace the normal run behavior./// </summary>/// <param name="message">Sets the Message in the tool's RunStatus.</param>/// <param name="result">Sets the Result in the tool's RunStatus</param>/// <returns>True if the tool should run normally,///          False if GroupRun customizes run behavior</returns>public override bool GroupRun(ref string message, ref CogToolResultConstants result){// To let the execution stop in this script when a debugger is attached, uncomment the following lines.// #if DEBUG// if (System.Diagnostics.Debugger.IsAttached) System.Diagnostics.Debugger.Break();// #endif// Run each tool using the RunTool function//foreach(ICogTool tool in mToolBlock.Tools)//mToolBlock.RunTool(tool, ref message, ref result);CogFixtureTool cfixtool = mToolBlock.Tools["CogFixtureTool1"] as CogFixtureTool;cfixtool.InputImage = (CogImage8Grey) mToolBlock.Inputs["OutputImage"].Value;cfixtool.Run();if(cfixtool.InputImage == null){mToolBlock.Outputs["outtoolblock"].Value = "outtoolblock cfixtool fail ";return false;}CogToolBlock block1 = mToolBlock.Tools["CogToolBlock1"] as CogToolBlock;CogToolBlock block2 = mToolBlock.Tools["CogToolBlock2"] as CogToolBlock;if(cfixtool.OutputImage.Width == 640){block1.Run();}else{block2.Run();}mToolBlock.Outputs["outtoolblock"].Value = block1.Outputs["strerr"].Value.ToString() + block2.Outputs["strerr"].Value.ToString();return false;}#region When the Current Run Record is Created/// <summary>/// Called when the current record may have changed and is being reconstructed/// </summary>/// <param name="currentRecord">/// The new currentRecord is available to be initialized or customized.</param>public override void ModifyCurrentRunRecord(Cognex.VisionPro.ICogRecord currentRecord){}#endregion#region When the Last Run Record is Created/// <summary>/// Called when the last run record may have changed and is being reconstructed/// </summary>/// <param name="lastRecord">/// The new last run record is available to be initialized or customized.</param>public override void ModifyLastRunRecord(Cognex.VisionPro.ICogRecord lastRecord){}#endregion#region When the Script is Initialized/// <summary>/// Perform any initialization required by your script here/// </summary>/// <param name="host">The host tool</param>public override void Initialize(Cognex.VisionPro.ToolGroup.CogToolGroup host){// DO NOT REMOVE - Call the base class implementation first - DO NOT REMOVEbase.Initialize(host);// Store a local copy of the script hostthis.mToolBlock = ((Cognex.VisionPro.ToolBlock.CogToolBlock)(host));}#endregion}

 最后就能实现在距离计算图片输入的时候,执行Block1,找字符R的时候,执行Block2,同时旁边的图片均能显示。

 

 

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

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

相关文章

云服务器开放端口

1. 控制台开放安全组 例如 阿里云 https://ecs.console.aliyun.com/ 网络与安全 > 安全组 新建或者选择一个安全组 入方向 > 手动添加 2. 服务器防火墙放行端口 在 CentOS 7 中可以使用 firewall-cmd 命令来开放指定端口号 16622。以下是具体步骤&#xff1a; 一、…

python库tenacity最后一次重试忽略异常,并返回None

from tenacity import retry, stop_after_attemptretry(stopstop_after_attempt(3), retry_error_callbacklambda x:None) def my_function():print(retry...)print(1/0)result my_function() print(result)效果如下

centos 7.9安装k8s

前言 Kubernetes单词来自于希腊语&#xff0c;含义是领航员&#xff0c;生产环境级别的容器编排技术&#xff0c;可实现容器的自动部署扩容以及管理。Kubernetes也称为K8S&#xff0c;其中8代表中间8个字符&#xff0c;是Google在2014年的开源的一个容器编排引擎技术&#xff…

Linux基础---07文件传输及解决yum安装失效的方法

Linux文件传输地图如下&#xff0c;先选取你所需的场景&#xff0c;若你是需要Linux和Linux之间传输文件就查看SCP工具即可。 一.下载网站文件 前提是有网&#xff1a; 检查网络是否畅通命令&#xff1a;ping www.baidu.com&#xff0c;若有持续的返回值就说明网络畅通。Ctr…

Docker笔记-容器数据卷

Docker笔记-容器数据卷 docker的理念将运行的环境打包形成容器运行&#xff0c;运行可以伴随容器&#xff0c;但是我们对数据的要求是希望持久化&#xff0c;容器 之间可以共享数据&#xff0c;Docker容器产生的数据&#xff0c;如果不通过docker commit生成新的镜像&#xf…

发送成绩的app或小程序推荐

老师们&#xff0c;新学期的第一次月考马上开始&#xff0c;是不是还在为如何高效、便捷地发布成绩而头疼呢&#xff1f;别担心&#xff0c;都2024年了&#xff0c;我们有更智能的方式来解决这个问题&#xff01; 给大家安利一个超级实用的工具——易查分小程序。这个小程序简…

【Unity踩坑】UI Image的fillAmount不起作用

在游戏场景中&#xff0c;我们经常在界面上展示进度条&#xff0c;当然有各种形状的&#xff0c;线性的&#xff0c;长方形的&#xff0c;圆形&#xff0c;环形等等。 Unity中实现这种效果的话&#xff0c;最基本的方法说是改变Image的fillAmout属性。 如果你是初次使用UI Ima…

基于STM32的温度、电流、电压检测proteus仿真系统(OLED、DHT11、继电器、电机)

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于STM32F103C8T6 采用DHT11读取温度、滑动变阻器模拟读取电流、电压。 通过OLED屏幕显示,设置电流阈值为80,电流小阈值为50,电压阈值为60,温度阈值为30 随便哪个超过预祝,则继电器切断,LE…

块匹配算法简介(上)

图像中的运动估计方法大致分为两类:光流法和块匹配算法(BMA,Block Matching Algorithm)。本文将介绍BMA的相关内容,包括基本原理、相似度计算准则与常见的几种搜索方法,如三步法、四步法、钻石搜索法等。 1. 背景 视频中相邻帧往往存在大量的相似内容,即只有局部的一些…

Golang | Leetcode Golang题解之第417题太平洋大西洋水流问题

题目&#xff1a; 题解&#xff1a; type pair struct{ x, y int } var dirs []pair{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}func pacificAtlantic(heights [][]int) (ans [][]int) {m, n : len(heights), len(heights[0])pacific : make([][]bool, m)atlantic : make([][]bool, …

ansible远程自动化运维、常用模块详解

一、ansible是基于python开发的配置管理和应用部署工具&#xff1b;也是自动化运维的重要工具&#xff1b;可以批量配置、部署、管理上千台主机&#xff1b;只需要在一台主机配置ansible就可以完成其它主机的操作。 1.操作模式&#xff1a; 模块化操作&#xff0c;命令行执行…

Vue 依赖注入组件通信:provide / inject 使用详解

引言 在 Vue.js 中&#xff0c;我们经常会遇到组件之间需要共享数据的情况。一种常见的解决方案是通过 props 和 $emit 事件来进行数据传递&#xff0c;但对于多层嵌套的组件结构或共享状态的场景&#xff0c;这种方式显得繁琐而不直观。 幸运的是&#xff0c;Vue.js 提供了一…

web渗透—RCE

一&#xff1a;代码执行 相关函数 1、eval()函数 assert()函数 (1)原理&#xff1a;将用户提交或者传递的字符串当作php代码执行 (2)passby:单引号绕过&#xff1a;闭合注释&#xff1b;开启GPC的话就无法绕过&#xff08;GPC就是将单引号转换为"反斜杠单引号"&a…

希亦超声波清洗机值得购买吗?百元清洁技术之王,大揭秘!

现代社会的高速发展&#xff0c;很多人由于工作繁忙的原因&#xff0c;根本没有时间去清洗自己的日常物品&#xff0c;要知道这些日常物品堆积灰尘之后是很容易就滋生细菌的&#xff0c;并且还会对人体的健康造成一定的危害&#xff01;这个时候很多人就会选择购买一台超声波清…

什么是CSRF攻击,该如何防护CSRF攻击

CSRF攻击&#xff08;跨站请求伪造&#xff0c;Cross-Site Request Forgery&#xff09;是一种网络攻击手段&#xff0c;攻击者利用已通过身份验证的用户&#xff0c;诱导他们在不知情的情况下执行未授权操作。这种攻击通常发生在用户登录到可信网站并且有活动的会话时&#xf…

Python编码系列—Python组合模式:构建灵活的对象组合

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…

cv2.bitwise_or 提取ROI区域

原图如下所示&#xff0c;想提取圆形ROI区域&#xff0c;红色框 img np.ones(ori_img.shape, dtype"uint8") img img * 255 cv2.circle(img, (50,50), 50, 0, -1) self.bitwiseOr cv2.bitwise_or(ori_img, circle)使用一个和原图尺寸一致的图像做mask,图白圆黑 以…

MySQL:索引02——使用索引

目录 引言 1、自动创建索引 2、手动创建索引 2.1 主键索引 2.2 查看索引信息 2.3 唯一索引 2.4 普通索引 2.5 复合索引 3、删除索引 3.1 主键索引 3.2 其他索引 4、查看执行计划 4.1 不加条件&#xff0c;查询所有 4.2 使用主键查询 4.3 子查询使用索引 4.4 普通索…

【架构设计】多级缓存:应用案例与问题解决策略

【架构设计】多级缓存&#xff1a;应用案例与问题解决策略 多级缓存系统的工作原理及其在提升应用性能方面的关键作用。通过对比本地缓存与分布式缓存的特点 | 原创作者/编辑&#xff1a;凯哥Java | 分类&#xff1a;架构设计系列教程 多级缓存…

在基准测试和规划测试中选Flat还是Ramp-up?

Flat测试和Ramp-up测试是各有优势的&#xff0c;下面我们就通过介绍几种实用的性能测试策略来分析这两种加压策略的着重方向。 基准测试 基准测试是一种测量和评估软件性能指标的活动&#xff0c;通过基准测试建立一个已知的性能水平&#xff08;称为基准线&#xff09;&…