当前位置: 首页 > news >正文

C#,人工智能,深度学习,目标检测,OpenCV级联分类器数据集的制作与《层级分类器一键生成器》源代码

一、目标识别技术概述

1、摘要

目标检测是计算机视觉中最基本和最具挑战性的问题之一,它试图从自然图像中的大量预定义类别中定位目标实例。深度学习技术已成为直接从数据中学习特征表示的强大策略,并在通用目标检测领域取得了显著突破。鉴于这一快速发展时期,本文的目标是全面综述深度学习技术在这一领域的最新成就。这项调查包括300多项研究贡献,涵盖了通用对象检测的许多方面:检测框架、对象特征表示、对象提议生成、上下文建模、训练策略和评估指标。我们通过确定未来研究的前景来完成调查。

2、介绍

作为计算机视觉中的一个长期、基本和具有挑战性的问题,目标检测(如图1所示)几十年来一直是一个活跃的研究领域(Fischler和Elschlager 1973)。目标检测的目标是确定图像中是否存在来自给定类别(如人类、汽车、自行车、狗或猫)的任何对象实例,如果存在,则返回每个对象实例的空间位置和范围(例如,通过边界框Everingham等人2010;Russakovsky等人2015)。作为图像理解和计算机视觉的基石,目标检测是解决复杂或高级视觉任务的基础,例如分割、场景理解、目标跟踪、图像字幕、事件检测和活动识别。目标检测支持广泛的应用,包括机器人视觉、消费电子、安全、自动驾驶、人机交互、基于内容的图像检索、智能视频监控和增强现实。

最近,深度学习技术(Hinton和Salakhutdinov 2006;LeCun等人,2015)已成为从数据中自动学习特征表示的强大方法。特别是,如图3所示,这些技术在对象检测方面提供了重大改进。

如图2所示,物体检测可以分为两种类型之一(Grauman和Leibe 2011;Zhang等人,2013):特定实例的检测与广泛类别的检测。第一种类型旨在检测特定对象的实例(例如唐纳德·特朗普的脸、埃菲尔铁塔或邻居的狗),本质上是一个匹配问题。第二种类型的目标是检测某些预定义对象类别(例如人、汽车、自行车和狗)的实例(通常以前未看到)。历史上,目标检测领域的大部分工作都集中在单个类别(通常是人脸和行人)或几个特定类别的检测上。相比之下,在过去几年中,研究界已开始朝着更具挑战性的目标迈进,即建立通用目标检测系统,在该系统中,目标检测能力的广度与人类相当。

Krizhevsky等人(2012a)提出了一种称为AlexNet的深度卷积神经网络(DCNN),该网络在大规模视觉识别挑战(ILSVRC)中实现了破纪录的图像分类精度(Russakovsky等人,2015)。自那时以来,计算机视觉的大多数方面的研究重点都是深度学习方法,实际上包括通用对象检测领域(Girshick等人2014;He等人2014;Girshick 2015;Sermanet al.2014;Ren等人2017)。虽然已经取得了巨大的进步,如图3所示,但我们不知道在过去5年中对这一主题进行了全面的调查。鉴于进展速度异常迅速,本文试图跟踪最新进展并总结其成果,以便更清楚地了解通用目标检测中的当前全景。

3、与之前算法的比较

如表1所示,已经发布了许多著名的物体检测调查。其中包括许多关于特定物体检测问题的优秀调查,例如行人检测(Enzweiler和Gavrila 2009;Geronimo等人2010;Dollar等人2012)、人脸检测(Yang等人2002;Zafeiriou等人2015)、车辆检测(Sun等人2006)和文本检测(Ye和Doermann 2015)。除了张等人(2013)就对象类检测主题进行的调查外,最近直接关注一般对象检测问题的调查相对较少。然而,在Grauman和Leibe(2011)、Andreopoulos和Tsotsos(2013)以及Zhang等人(2013)中回顾的研究大多是在2012年之前,因此在深度学习和相关方法最近取得显著成功并占据主导地位之前。

深度学习允许计算模型学习极其复杂、微妙和抽象的表示,推动了广泛问题的重大进展,如视觉识别、物体检测、语音识别、自然语言处理、医学图像分析、药物发现和基因组学。在不同类型的深度神经网络中,DCNN(LeCun等人,1998、2015;Krizhevsky等人,2012a)在处理图像、视频、语音和音频方面取得了突破。可以肯定的是,已经发表了许多关于深度学习的调查,包括Bengio等人(2013)、LeCun等人(2015)、Litjens等人(2017)、Gu等人(2018),以及最近在ICCV和CVPR的教程中发表的调查。

相比之下,虽然已经提出了许多基于深度学习的目标检测方法,但我们不知道最近有任何全面的调查。全面回顾和总结现有工作对于目标检测的进一步进展至关重要,特别是对于希望进入该领域的研究人员而言。由于我们的重点是一般物体检测,因此将不考虑针对特定物体检测的DCNN的广泛工作,例如人脸检测(李等人2015a;张等人2016a;胡等人2017)、行人检测(张等人2016b;何桑等人2015)、车辆检测(周等人2016b)和交通标志检测(朱等人2016b)。

4、范围

基于深度学习的通用目标检测的论文数量惊人。事实上,有如此之多的内容,以至于对最新技术的任何全面综述都超出了任何合理篇幅的论文的范围。因此,有必要制定选择标准,将我们的重点限制在顶级期刊和会议论文上。由于这些局限性,我们真诚地向那些作品未包含在本文中的作者道歉。有关相关主题工作的调查,读者请参阅表1中的文章。本综述主要关注过去5年的主要进展,我们将注意力限制在静态图片上,将视频对象检测这一重要课题作为未来单独考虑的主题。

二、OpenCV级联分类器(CascadeClassifier)生成方法

OpenCV级联分类器数据(比如:cascade.xml)用于实现目标识别的核心数据。

CascadeClassifier则是opencv下objdetect模块中用来做目标检测的级联分类器的一个类;简而言之是滑动窗口机制+级联分类器的方式;早期opencv版本仅支持haar特征的目标检测,分别在opencv2.2和2.4之后开始支持LBP和HOG特征的目标检测。

使用现成的级联分类器数据局限性太多了,工业软件都是自己制作。

1、级联分类器数据的制作流程

2、图片准备与预处理

(1)图片最好用现场拍摄的照片,尽量不要过多的处理,原本最好!

(2)文件夹、文件名等,最好不要有汉字等,数字与字母最好;文件夹最好不要有空格!

(3)本文的《层级分类器集成生成环境》可以帮助你一键生成同样大小、黑白以及按数字命名的正样本图片及负样本图片。

3、正样本 Positive Images(Samples)

正样本图片,是告诉程序,这些 或 接近的就是目标!一般来说,数量至少在 1000 以上。本文只是示意性的,仅仅给出几十个图片,这是不够的哈。

(1)正样本 一般要求 20x20,24x24,64x64;

(2)现在有了本文的《层级分类器集成生成环境》,你随便,正样本只要截取的是正方形(其实也不一定)的即可。

(3)彩色?黑白?无所谓。

(4)正样本文件 pos.txt 是为了生成 正样本矢量化数据 pos.vec 准备的;

posdata/001.jpg 1 0 0 20 20
posdata/002.jpg 1 0 0 20 20
posdata/003.jpg 1 0 0 20 20
posdata/004.jpg 1 0 0 20 20
posdata/005.jpg 1 0 0 20 20
posdata/006.jpg 1 0 0 20 20
posdata/007.jpg 1 0 0 20 20
posdata/008.jpg 1 0 0 20 20
posdata/009.jpg 1 0 0 20 20
posdata/010.jpg 1 0 0 20 20
posdata/011.jpg 1 0 0 20 20
posdata/012.jpg 1 0 0 20 20

 正样本文件 pos.txt 每行的格式是:

文件名 样本目标数 起点x 起点 y 宽度 高度

文件名可以用相对路径。样本数建议为1。起点建议为(0,0)。

本文的《层级分类器集成生成环境》可以帮助你一键生成 pos.txt 文件。图片尺寸自动提取。

4、正样本 矢量化

正样本矢量化数据 pos.vec 是训练必须的基础数据,是归一化、标准化、矢量化的 正样本数据,可以不再使用正样本图片及其数据,因而大大提高训练效率。

正样本矢量化数据 pos.vec 用 opencv_createsamples.exe 生成。

Windows cmd:

opencv_createsamples.exe -vec pos.vec -info pos.txt -num 12 -w 20 -h 20

Windows PowerShell:

.\opencv_createsamples.exe -vec pos.vec -info pos.txt -num 12 -w 20 -h 20

参数简要说明:

-vec pos.vec 生成的矢量文件
-info pos.txt 正样本文件
-num 12 正样本数量
-w 20 正样本尺寸(宽)
-h 20 正样本尺寸(高)

本文的《层级分类器集成生成环境》可以帮助你一键生成 pos.vec 文件。不需要进入 cmd 或 PowerShell 去敲键盘!

5、负样本 Negative Images(Samples)

(1)负样本 是告诉识别程序,哪些元素是目标中没有的!数量至少是正样本的 3 倍。不好凑!可以多复制几份哈。可以凑合的。

(2)负样本,大小无所谓;唯一的要求是不能含有正样本的物体;建议尺寸为 320x240 -- 640x480 ;

(3)负样本文件 neg.txt

C:/Downloads/Baidu/opencv_bin/negdata/001.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/002.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/003.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/004.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/005.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/006.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/007.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/008.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/009.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/010.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/011.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/012.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/013.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/014.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/015.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/016.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/017.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/018.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/019.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/020.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/021.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/022.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/023.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/024.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/025.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/026.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/027.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/028.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/029.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/030.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/031.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/032.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/033.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/034.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/035.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/036.jpeg
C:/Downloads/Baidu/opencv_bin/negdata/037.jpeg

负样本文件,只需要指定用于训练的 负样本图片即可。绝对地址!绝对地址!绝对地址!

本文的《层级分类器集成生成环境》可以帮助你一键生成 neg.txt 文件。

正样本数 :负样本数 至少是 1:3

6、训练 Cascade Trainning

有了  pos.vec 与 neg.txt 文件,就可以进行训练了。这个过程 坑 比较多。

Windows cmd:

opencv_traincascaded.exe -data xml -vec pos.vec -bg neg.txt -numPos 12 -numNeg 37 -numStages 20 -w 20 -h 20 -maxFalseAlarmRate 0.5 -mode ALL

Windows PowerShell:

.\opencv_traincascaded.exe -data xml -vec pos.vec -bg neg.txt -numPos 12 -numNeg 37 -numStages 20 -w 20 -h 20 -maxFalseAlarmRate 0.5 -mode ALL

注意几点:

(1)先检查  pos.vec ,neg.txt 文件是否存在?是否符合要求?

(2)建议创建子目录 posdata 放置 正样本 图片;子目录 negdata 放置 负样本图片;

(3)必须创建 xml 子目录;生成结果就在这个子目录下;

(4)无需生成 neg.vec

这个过程很吃资源,很慢慢慢慢慢慢慢慢慢慢慢慢慢慢慢慢慢慢慢慢慢慢慢慢慢慢慢慢慢慢慢慢慢慢慢慢慢慢慢慢慢慢慢,要花很长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长的时间。

敲击这些参数,很麻烦的。经过漫长的等待,最终生成 xml/cascade.xml 文件,大功告成!

本文的《层级分类器集成生成环境》可以帮助你一键做好上述工作,自动完成训练,生成 cascade.xml 文件!!!!!

三、《层级分类器集成生成环境》源代码

1、老老程序员的唠叨

自己制作 级联分类器数据 不是一件轻松、简单的事情,但没有级联分类器数据几乎无法开展后续的工作。因而不得不硬着头皮做下去。

看到大多数朋友都喜欢进入 cmd 去 key key key,效率实在是太低了。

我们这些从 DOS 过来的骨灰级程序员,有了 Windows 或 iOS 的 GUI ,终于摆脱了 KEY KEY KEY ,看到没有 GUI 的程序简直是受罪。关键是效率太低了。3天的活,本来1小时可以搞掂。

为了提高效率,很多年前就写了 《层级分类器集成生成环境》,现在按 Visual Studio 2022 做些改动与改进,放出来分享。

代码并不完善,有很多不足,请自行修改完善之。

2、准备工作

首先需要有 openCV 训练器相关程序:

(1)使用 openCV 开源,自己或使用别人编译好的 build ;

(2)去 OpenCV 官网下载 release:

OpenCV 官网下载icon-default.png?t=O83Ahttps://opencv.org/releases/

(3)(多动症儿童〄的博客_CSDN博客-百度AI,笔记领域博主)提供的下载:

https://pan.baidu.com/s/1vCdmWnRRjRNmOCKm30602w?pwd=zur8icon-default.png?t=O83Ahttps://pan.baidu.com/s/1vCdmWnRRjRNmOCKm30602w?pwd=zur8

CVTrainer项目的目录结构是(供参考):

3、图片预处理源代码

功能包括:批量处理;统一尺寸;统一名称;统一后缀; 

#region 图片批量转换/// <summary>
/// 原始文件夹
/// </summary>
private string FromFolder { get; set; } = "";
/// <summary>
/// 目标文件夹
/// </summary>
private string SaveFolder { get; set; } = "";
/// <summary>
/// 图片尺寸信息
/// </summary>
private int[] SaveSizes { get; set; }
/// <summary>
/// 数字型文件名的序列号
/// </summary>
private int SaveIndex { get; set; } = 1;private void tpNormalize_SizeChanged(object sender, EventArgs e)
{txtFrom.Width = tpNormalize.Width - txtFrom.Left - btnFrom.Width - 60;btnFrom.Left = txtFrom.Left + txtFrom.Width + 5;btnFrom.Top = txtFrom.Top;btnFrom.Height = txtFrom.Height;
}/// <summary>
/// 浏览原始文件夹
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnFrom_Click(object sender, EventArgs e)
{if (folderBrowserDialog1.ShowDialog() == DialogResult.OK){FromFolder = folderBrowserDialog1.SelectedPath;txtFrom.Text = FromFolder;SaveSizes = ImageSizes(FromFolder);if (SaveSizes[0] != SaveSizes[1]) txtFromWidth.Text = SaveSizes[0] + "..." + SaveSizes[1];else txtFromWidth.Text = SaveSizes[0] + "";if (SaveSizes[2] != SaveSizes[3]) txtFromHeight.Text = SaveSizes[2] + "..." + SaveSizes[3];else txtFromHeight.Text = SaveSizes[2] + "";txtSaveWidth.Text = SaveSizes[0] + "";txtSaveHeight.Text = SaveSizes[2] + "";}
}/// <summary>
/// 浏览并指定目标文件夹
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSave_Click(object sender, EventArgs e)
{if (folderBrowserDialog1.ShowDialog() == DialogResult.OK){SaveFolder = folderBrowserDialog1.SelectedPath;txtSave.Text = SaveFolder;}
}/// <summary>
/// 图片的批量处理
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnNormalize_Click(object sender, EventArgs e)
{if (FromFolder.Length < 1){MessageBox.Show("browse the source folder.");return;}if (SaveFolder.Length < 1){MessageBox.Show("browse the destination folder.");return;}int w = int.Parse("0" + txtSaveWidth.Text);int h = int.Parse("0" + txtSaveHeight.Text);try{int idx = 0;SaveIndex = 1;DirectoryInfo fd = new DirectoryInfo(FromFolder);FileInfo[] xfiles = fd.GetFiles();progressBar1.Maximum = xfiles.Count();progressBar1.Visible = true;foreach (FileInfo fx in xfiles){progressBar1.Value = idx;progressBar1.Refresh();if (IsImageFile(fx.Extension)){string filename = Path.Combine(SaveFolder, fx.Name);if (cbNumericName.Checked){filename = Path.Combine(SaveFolder, GetNumericalName());}// 如果只是复制if (w == SaveSizes[0] && h == SaveSizes[2] && txtSaveExt.Text.Length == 0){File.Copy(fx.FullName, filename);continue;}else{Image img = Image.FromFile(fx.FullName);if (txtSaveExt.Text.Length > 0){filename = Path.Combine(SaveFolder, fx.Name.Replace(fx.Extension, "") + txtSaveExt.Text);}if (w > 0 && h > 0){Bitmap bmp = new Bitmap(w, h);Graphics g = Graphics.FromImage(bmp);g.DrawImage(img, 0, 0, w, h);if(cbGray.Checked){ToGrayImage(ref bmp);}bmp.Save(filename);}else if (w > 0 && h == 0){h = (int)(w * (double)img.Height / (double)img.Width);Bitmap bmp = new Bitmap(w, h);Graphics g = Graphics.FromImage(bmp);g.DrawImage(img, 0, 0, w, h);if (cbGray.Checked){ToGrayImage(ref bmp);}bmp.Save(filename);}else{w = (int)(h * (double)img.Width / (double)img.Height);Bitmap bmp = new Bitmap(w, h);Graphics g = Graphics.FromImage(bmp);g.DrawImage(img, 0, 0, w, h);if (cbGray.Checked){ToGrayImage(ref bmp);}bmp.Save(filename);}}}}progressBar1.Visible = false;MessageBox.Show("OK!");}catch (Exception ex){MessageBox.Show(ex.Message);}
}/// <summary>
/// 计算下一个可使用的数字型图片文件名
/// </summary>
/// <returns></returns>
private string GetNumericalName()
{while (true){string sname = String.Format("{0:D5}", SaveIndex);if (!File.Exists(Path.Combine(SaveFolder, sname))){return sname;}SaveIndex++;}
}
#endregion

4、正样本处理相关源代码(POWER BY 315SOFT.COM)

一键生成 pos.txt 文件;一键生成 pos.vec 文件。 

#region 正样本private void tabPage1_SizeChanged(object sender, EventArgs e)
{txtPosFolder.Width = tabPage1.Width - txtPosFolder.Left - btnPosFolder.Width - 60;btnPosFolder.Left = txtPosFolder.Left + txtPosFolder.Width + 5;btnPosFolder.Top = txtPosFolder.Top;
}/// <summary>
/// 浏览并指定 正样本 文件夹
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnPosFolder_Click(object sender, EventArgs e)
{if (folderBrowserDialog1.ShowDialog() == DialogResult.OK){txtPosFolder.Text = folderBrowserDialog1.SelectedPath;txtPosCount.Text = CountImageFile(txtPosFolder.Text) + "";}
}/// <summary>
/// 生成 pos.txt 文件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnPosTxt_Click(object sender, EventArgs e)
{if (txtPosFolder.Text.Length < 1){MessageBox.Show("Please browse the folder contains positive images!");return;}try{// 为复制图片做准备string imgPosFolder = Path.Combine(WorkFolder, @"posdata");if (cbPosCopy.Checked){if (!Directory.Exists(imgPosFolder)){Directory.CreateDirectory(imgPosFolder);}}StringBuilder sb = new StringBuilder();DirectoryInfo fd = new DirectoryInfo(txtPosFolder.Text);FileInfo[] xfiles = fd.GetFiles();foreach (FileInfo fx in xfiles){if (IsImageFile(fx.Extension)){// 将样本图片文件复制到工作文件夹/posdataif (cbPosCopy.Checked){string df = Path.Combine(imgPosFolder, fx.Name);File.Copy(fx.FullName, df);}sb.Append("posdata/");sb.Append(fx.Name + " ");sb.Append(txtSampleCount.Text + " ");sb.Append(txtOriginX.Text + " ");sb.Append(txtOriginY.Text + " ");// 自动获取图片尺寸Image img = Image.FromFile(fx.FullName);sb.Append(img.Width + " ");sb.AppendLine(img.Height + "");// 按最小的图片设置 vector 参数if (txtSampleWidth.Text.Length == 0)txtSampleWidth.Text = img.Width + "";else if (Int32.Parse(txtSampleWidth.Text) > img.Width)txtSampleWidth.Text = img.Width + "";if (txtSampleHeight.Text.Length == 0)txtSampleHeight.Text = img.Height + "";else if (Int32.Parse(txtSampleHeight.Text) > img.Height)txtSampleHeight.Text = img.Height + "";}}if (!Directory.Exists(WorkFolder)){Directory.CreateDirectory(WorkFolder);}File.WriteAllText(Path.Combine(WorkFolder, @"pos.txt"), sb.ToString(), Encoding.Default);webBrowser1.DocumentText = sb.ToString().Replace("\r\n", "<br>\r\n");MessageBox.Show(Path.Combine(WorkFolder, @"pos.txt") + " OK!");}catch (Exception ex){MessageBox.Show(ex.Message);}
}/// <summary>
/// 生成 pos.vec 矢量文件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnPosVec_Click(object sender, EventArgs e)
{string filename = Path.Combine(WorkFolder, @"pos.txt");if (!File.Exists(filename)){MessageBox.Show("Should first create pos.txt !");return;}Directory.SetCurrentDirectory(WorkFolder);StringBuilder sb = new StringBuilder();//sb.Append(WorkFolder + "\\");//sb.Append("opencv_createsamples.exe ");sb.Append("-vec pos.vec ");sb.Append("-info pos.txt ");sb.Append("-num " + txtPosCount.Text + " ");sb.Append("-w " + txtSampleWidth.Text + " ");sb.Append("-h " + txtSampleHeight.Text);Process p = new Process();p.StartInfo.FileName = Path.Combine(WorkFolder, @"opencv_createsamples.exe");p.StartInfo.Arguments = sb.ToString();//是否使用操作系统shell启动p.StartInfo.UseShellExecute = false;//接受来自调用程序的输入信息p.StartInfo.RedirectStandardInput = false;//由调用程序获取输出信息p.StartInfo.RedirectStandardOutput = true;//重定向标准错误输出p.StartInfo.RedirectStandardError = true;//不显示程序窗口p.StartInfo.CreateNoWindow = true;//启动程序p.Start();//p.StandardInput.AutoFlush = false;string output = p.StandardOutput.ReadToEnd();//等待程序执行完退出进程p.WaitForExit();p.Close();webBrowser1.DocumentText = output.Replace("\n", "<br>\n");string filenname = Path.Combine(WorkFolder, @"pos.vec");if (File.Exists(filename)){MessageBox.Show(filename + " OK!");}
}#endregion

5、负样本处理相关源代码

一键生成 neg.txt 文件; 

#region 负样本private void tabPage2_SizeChanged(object sender, EventArgs e)
{txtNegFolder.Width = tabPage2.Width - txtNegFolder.Left - btnNegFolder.Width - 60;btnNegFolder.Left = txtNegFolder.Left + txtNegFolder.Width + 5;btnNegFolder.Top = txtNegFolder.Top;
}/// <summary>
/// 浏览并指定 负样本 文件夹
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnNegFolder_Click(object sender, EventArgs e)
{if (folderBrowserDialog1.ShowDialog() == DialogResult.OK){txtNegFolder.Text = folderBrowserDialog1.SelectedPath;txtNegCount.Text = CountImageFile(txtNegFolder.Text) + "";}
}/// <summary>
/// 生成负样本 neg.txt 文件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnNegTxt_Click(object sender, EventArgs e)
{string imgNegFolder = Path.Combine(WorkFolder, @"negdata");StringBuilder sb = new StringBuilder();DirectoryInfo fd = new DirectoryInfo(txtNegFolder.Text);FileInfo[] xfiles = fd.GetFiles();foreach (FileInfo fx in xfiles){if (IsImageFile(fx.Extension)){// 将样本图片文件复制到工作文件夹/negdataif (cbNegCopy.Checked){string df = Path.Combine(imgNegFolder, fx.Name);File.Copy(fx.FullName, df);sb.AppendLine(Path.Combine(imgNegFolder, fx.Name).Replace("\\", "/"));}else{sb.AppendLine(fx.FullName.Replace("\\", "/"));}}}if (!Directory.Exists(WorkFolder)){Directory.CreateDirectory(WorkFolder);}File.WriteAllText(Path.Combine(WorkFolder, @"neg.txt"), sb.ToString(), Encoding.Default);webBrowser1.DocumentText = sb.ToString().Replace("\r\n", "<br>\r\n");MessageBox.Show(Path.Combine(WorkFolder, @"neg.txt") + " OK!");
}#endregion

6、训练源代码

一键生成 xml/cascade.xml 文件;

#region 训练
private void btnTrainning_Click(object sender, EventArgs e)
{string filename = Path.Combine(WorkFolder, @"pos.vec");if (!File.Exists(filename)){MessageBox.Show("Should first create pos.vec !");return;}filename = Path.Combine(WorkFolder, @"neg.txt");if (!File.Exists(filename)){MessageBox.Show("Should first create neg.txt !");return;}Directory.SetCurrentDirectory(WorkFolder);StringBuilder sb = new StringBuilder();sb.Append("-data xml ");sb.Append("-vec " + txtVecFile.Text + " ");sb.Append("-bg " + txtNegFile.Text + " ");sb.Append("-numPos " + txtNumPos.Text + " ");sb.Append("-numNeg " + txtNumNeg.Text + " ");sb.Append("-numStages 20 ");sb.Append("-w " + txtPosWidth.Text + " ");sb.Append("-h " + txtPosHeight.Text + " ");sb.Append("-minHitRate " + txtHitRate.Text + " ");sb.Append("-weightTrimRate " + txtTrimRate.Text + " ");sb.Append("-maxFalseAlarmRate " + txtFalseAlarm.Text + " ");sb.Append("-stagetype " + txtStage.Text + " ");sb.Append("-boosttype " + cxBoost.SelectedItem.ToString() + " ");sb.Append("-featuretype " + cxFeature.SelectedItem.ToString() + " ");sb.Append("-mode " + cxMode.SelectedItem.ToString() + " ");Process p = new Process();p.StartInfo.FileName = Path.Combine(WorkFolder, @"opencv_traincascade.exe");p.StartInfo.Arguments = sb.ToString();//是否使用操作系统shell启动p.StartInfo.UseShellExecute = false;//接受来自调用程序的输入信息p.StartInfo.RedirectStandardInput = false;//由调用程序获取输出信息p.StartInfo.RedirectStandardOutput = true;//重定向标准错误输出p.StartInfo.RedirectStandardError = true;//不显示程序窗口p.StartInfo.CreateNoWindow = true;//启动程序this.Cursor = Cursors.WaitCursor;p.Start();//p.StandardInput.AutoFlush = false;string output = p.StandardOutput.ReadToEnd();//等待程序执行完退出进程p.WaitForExit();p.Close();this.Cursor = Cursors.Default;webBrowser1.DocumentText = output.Replace("\n", "<br>\n");string xmlname = Path.Combine(WorkFolder, @"xml", @"cascade.xml");if (File.Exists(xmlname)){MessageBox.Show(xmlname + " OK!");}
}#endregion

7、基础函数

Form1.cs

using System;
using System.IO;
using System.Text;
using System.Linq;
using System.Drawing;
using System.Diagnostics;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;namespace Legalsoft.CVTrainer
{/// <summary>/// OpenCV 训练集继承生成环境/// 北京联高软件开发有限公司/// Beijing Legal Software Ltd./// </summary>public partial class Form1 : Form{/// <summary>/// 工作目录/// 一般是 CVTrainer.exe 下的 opencv_bin /// </summary>private string WorkFolder { get; set; } = "";public Form1(){InitializeComponent();#region 正样本相关btnPosFolder.Height = txtPosFolder.Height;WorkFolder = Path.Combine(Application.StartupPath, "opencv_bin");lbWorkFolderValue.Text = WorkFolder;cbPosCopy.Checked = true;cbPosCopy.Cursor = Cursors.Hand;btnPosTxt.Cursor = Cursors.Hand;btnPosVec.Cursor = Cursors.Hand;#endregion#region 负样本相关label14.Text = WorkFolder;cbNegCopy.Cursor = Cursors.Hand;btnNegTxt.Cursor = Cursors.Hand;#endregion#region 训练相关label17.Text = WorkFolder;btnTrainning.Cursor = Cursors.Hand;cxBoost.SelectedIndex = 0;cxFeature.SelectedIndex = 0;cxMode.SelectedIndex = 2;#endregion#region 图片预处理相关cbGray.Cursor = Cursors.Hand;txtSaveExt.Text = "";cbNumericName.Cursor = Cursors.Hand;btnNormalize.Cursor = Cursors.Hand;txtFrom.ReadOnly = true;txtFromWidth.ReadOnly = true;txtFromHeight.ReadOnly = true;btnFrom.Cursor = Cursors.Hand;txtSave.ReadOnly = true;btnSave.Cursor = Cursors.Hand;progressBar1.Visible = false;#endregiontabPage1.Text = " Positive Images ";tabPage2.Text = " Negative Images ";tabPage3.Text = " Cascade Train ";tpNormalize.Text = " Image Normalization ";panel1.Dock = DockStyle.Top;tabControl1.Dock = DockStyle.Fill;panel2.Dock = DockStyle.Fill;webBrowser1.Dock = DockStyle.Fill;this.Text = "C#,OpenCV Object Detect Images Trainer ——BEIJING LEGAL SOFTWARE LTD.";this.StartPosition = FormStartPosition.CenterScreen;}private void Form1_Load(object sender, EventArgs e){Summary();}private void tabControl1_SelectedIndexChanged(object sender, EventArgs e){if (tabControl1.SelectedIndex != 0){Summary();}}/// <summary>/// 计算一些概要信息/// </summary>private void Summary(){StringBuilder sb = new StringBuilder();sb.AppendLine("<style>b { font-weight:bold;color:#AA0000; } </style>");sb.AppendLine("Work folder: " + WorkFolder + "<br>");string folder = WorkFolder;if (!Directory.Exists(folder)){sb.AppendLine("!Create Work folder " + WorkFolder + "<br>");MessageBox.Show("Work folder not exist!\nYou can do nothing!");return;}folder = Path.Combine(WorkFolder, "xml");sb.AppendLine("Parameters folder: " + folder + "<br>");if (!Directory.Exists(folder)){sb.AppendLine("!Create parameter(xml) folder " + folder + "<br>");Directory.CreateDirectory(folder);}folder = Path.Combine(WorkFolder, "posdata");sb.AppendLine("Positive folder: " + folder + "<br>");if (!Directory.Exists(folder)){sb.AppendLine("!Create Positive folder " + folder + "<br>");Directory.CreateDirectory(folder);}else{int count = CountImageFile(folder);if (count > 0){sb.AppendLine("There have " + count + " images<br>");txtPosCount.Text = count + "";txtNumPos.Text = count + "";txtPosFolder.Text = folder;}if (File.Exists(Path.Combine(WorkFolder, @"pos.txt"))){sb.AppendLine("There have <b>pos.txt</b><br>");int[] sz = ImageSizes(Path.Combine(WorkFolder, @"posdata"));txtSampleWidth.Text = sz[0] + "";txtSampleHeight.Text = sz[2] + "";txtPosWidth.Text = sz[0] + "";txtPosHeight.Text = sz[2] + "";sb.AppendLine("Image size: " + sz[0] + "," + sz[2] + "<br>");}else{sb.AppendLine("There have't <b>pos.txt</b><br>");}if (File.Exists(Path.Combine(WorkFolder, @"pos.vec"))){sb.AppendLine("There have <b>pos.vec</b><br>");}else{sb.AppendLine("There have <b>not pos.vec</b><br>");}cbPosCopy.Checked = (count == 0);}folder = Path.Combine(WorkFolder, "negdata");sb.AppendLine("Negative folder: " + folder + "<br>");if (!Directory.Exists(folder)){sb.AppendLine("!Create Negative folder " + folder + "<br>");Directory.CreateDirectory(folder);}else{int count = CountImageFile(folder);if (count > 0){sb.AppendLine("There have " + count + " images<br>");txtNegCount.Text = count + "";txtNumNeg.Text = count + "";txtNegFolder.Text = folder;}if (File.Exists(Path.Combine(WorkFolder, @"neg.txt"))){sb.AppendLine("There have <b>neg.txt</b><br>");}else{sb.AppendLine("There have <b>not neg.txt</b><br>");}cbNegCopy.Checked = (count == 0);}webBrowser1.DocumentText = sb.ToString();}//...// 这里添加上面的其他代码}
}

基础函数:

#region 基础函数/// <summary>
/// 文件是图片吗?
/// 按文件后缀判别;可自行添加;
/// </summary>
/// <param name="ext"></param>
/// <returns></returns>
private bool IsImageFile(string ext)
{ext = ext.ToLower();if (ext == ".bmp") return true;if (ext == ".gif") return true;if (ext == ".png") return true;if (ext == ".jpg" || ext == ".jpeg") return true;return false;
}/// <summary>
/// 统计指定目录下的图片文件数量
/// </summary>
/// <param name="folder"></param>
/// <returns></returns>
private int CountImageFile(string folder)
{DirectoryInfo fd = new DirectoryInfo(folder);int count = 0;FileInfo[] xfiles = fd.GetFiles();foreach (FileInfo fx in xfiles){if (IsImageFile(fx.Extension)){count++;}}return count;
}/// <summary>
/// 提取指定文件夹下图片的尺寸(最小、最大的高度、宽度)
/// </summary>
/// <param name="folder"></param>
/// <returns></returns>
private int[] ImageSizes(string folder)
{int min_width = Int16.MaxValue;int max_width = 0;int min_height = Int16.MaxValue;int max_height = 0;DirectoryInfo fd = new DirectoryInfo(folder);FileInfo[] xfiles = fd.GetFiles();foreach (FileInfo fx in xfiles){if (IsImageFile(fx.Extension)){Image img = Image.FromFile(fx.FullName);if (img.Width > max_width) max_width = img.Width;if (img.Width < min_width) min_width = img.Width;if (img.Height > max_height) max_height = img.Height;if (img.Height < min_height) min_height = img.Height;}}return new int[] { min_width, max_width, min_height, max_height };
}/// <summary>
/// 图片转为黑白的
/// 简单的代码,看得懂一些;效率低下;
/// 不过,图片不多的够用了。
/// </summary>
/// <param name="bmp"></param>
private void ToGrayImage(ref Bitmap bmp)
{for (int y = 0; y < bmp.Height; y++){for (int x = 0; x < bmp.Width; x++){Color cc = bmp.GetPixel(x, y);int cx = Math.Min(255, (int)(cc.R * 0.299 + cc.G * 0.587 + cc.B * 0.114));bmp.SetPixel(x, y, Color.FromArgb(cx, cx, cx));}}
}#endregion

8、界面相关代码(略)

以上代码经 验证 基本可用,享受编程的乐趣吧。

相关文章:

C#,人工智能,深度学习,目标检测,OpenCV级联分类器数据集的制作与《层级分类器一键生成器》源代码

一、目标识别技术概述 1、摘要 目标检测是计算机视觉中最基本和最具挑战性的问题之一&#xff0c;它试图从自然图像中的大量预定义类别中定位目标实例。深度学习技术已成为直接从数据中学习特征表示的强大策略&#xff0c;并在通用目标检测领域取得了显著突破。鉴于这一快速发…...

调度系统:Luigi 的主要特性和功能

Luigi 是一个开源的 Python 工作流管理工具&#xff0c;用于构建批处理作业管道&#xff0c;特别适用于数据工程领域。它被设计用来编排任务和处理任务间的依赖关系&#xff0c;支持自动化复杂的 ETL 流程、数据分析、模型训练等任务。 Luigi 的主要特性和功能&#xff1a; 任…...

C# 探险之旅:第二节 - 定义变量与变量赋值

欢迎再次踏上我们的C#学习之旅。今天&#xff0c;我们要聊一个超级重要又好玩的话题——定义变量与变量赋值。想象一下&#xff0c;你正站在一个魔法森林里&#xff0c;手里拿着一本空白的魔法书&#xff08;其实就是你的代码编辑器&#xff09;&#xff0c;准备记录下各种神奇…...

AUTOSAR:SOME/IP 概念

文章目录 1. 用例与需求1.1 典型用例1.2 对中间件的要求 2. 协议栈示例3. SOME/IP 概念3.1 中间件整体功能与架构3.2 服务组成元素详细解释 4. 服务发现机制深入剖析5. 总结 1. 用例与需求 1.1 典型用例 信息娱乐系统&#xff1a; 后座娱乐系统连接&#xff1a;允许后排乘客连…...

循序渐进kubenetes Service(Cluster ip、Nodeport、Loadbalancer)

文章目录 部署一个web服务Kubernetes Port ForwardKubernetes ServicesClusterIP ServiceNodePort ServiceLoadBalancer Service 部署一个web服务 准备 Kubernetes 集群后&#xff0c;创建一个名为 web 的新 namespace&#xff0c;然后在该 namespace 中部署一个简单的 web 应…...

深入理解 Apache Shiro:安全框架全解析

亲爱的小伙伴们&#x1f618;&#xff0c;在求知的漫漫旅途中&#xff0c;若你对深度学习的奥秘、JAVA 、PYTHON与SAP 的奇妙世界&#xff0c;亦或是读研论文的撰写攻略有所探寻&#x1f9d0;&#xff0c;那不妨给我一个小小的关注吧&#x1f970;。我会精心筹备&#xff0c;在…...

mac 安装CosyVoice (cpu版本)

CosyVoice 介绍 CosyVoice 是阿里研发的一个tts大模型 官方项目地址&#xff1a;https://github.com/FunAudioLLM/CosyVoice.git 下载项目&#xff08;非官方&#xff09; git clone --recursive https://github.com/v3ucn/CosyVoice_for_MacOs.git 进入项目 cd CosyVoic…...

币安移除铭文市场的深度解读:背后原因及其对区块链行业的影响

引言&#xff1a; 就在昨天&#xff0c;2024年12月10号&#xff0c;币安宣布将移除铭文市场&#xff08;Inscriptions Market&#xff09;。这一消息引发了全球加密货币社区的广泛关注&#xff0c;尤其是在比特币NFT和数字收藏品市场快速发展的背景下。铭文市场自诞生以来迅速…...

深度学习实战野生动物识别

本文采用YOLOv11作为核心算法框架&#xff0c;结合PyQt5构建用户界面&#xff0c;使用Python3进行开发。YOLOv11以其高效的实时检测能力&#xff0c;在多个目标检测任务中展现出卓越性能。本研究针对野生动物数据集进行训练和优化&#xff0c;该数据集包含丰富的野生动物图像样…...

windows安装使用conda

在Windows系统上安装和使用Conda的详细步骤如下&#xff1a; 一、下载Conda安装包 访问Conda的官方网站Anaconda | The Operating System for AI&#xff0c;点击“Downloads”按钮。在下载页面&#xff0c;选择适合您系统的安装包。通常&#xff0c;对于Windows系统&#xf…...

手机租赁系统开发全流程解析与实用指南

内容概要 在如今快速发展的科技时代&#xff0c;手机租赁系统已经成为一种新兴的商业模式&#xff0c;非常符合当下市场需求。那么&#xff0c;在开发这样一个系统的时候&#xff0c;首先要从需求分析和市场调研开始。在这一阶段&#xff0c;你需要了解用户需要什么&#xff0…...

SpringBoot 开发—— YAML文件深度分析

文章目录 一、YAML概述二、数据表示三、YAML 的语法四、YAML 的应用五、YAML 与其他格式的比较1、YAML vs .properties文件可读性和结构数据类型支持扩展性和灵活性使用场景性能和支持2、YAML vs. JSON3、YAML vs. XML六、使用 YAML 的注意事项七、总结YAML 是非常流行的一种配…...

复合机器人整体解决方案

复合机器人是一种集成移动机器人和协作机器人两项功能为一身的新型机器人&#xff0c;更符合人们想象中“脑、眼、手、脚”融合的机器人终极形态。复合机器人的整体解决方案通常涉及多个方面&#xff0c;包括机器人本体、控制系统、感知系统、执行系统以及周边配套设备等。以下…...

【Oracle11g SQL详解】日期和时间函数:SYSDATE、TO_DATE、TO_CHAR 等

日期和时间函数&#xff1a;SYSDATE、TO_DATE、TO_CHAR 等 在 Oracle 数据库中&#xff0c;日期和时间函数用于处理日期和时间数据。它们在记录创建时间、分析时间间隔、格式化输出等场景中非常重要。本文将详细讲解常用的日期和时间函数及其应用。 一、SYSDATE&#xff1a;获…...

VSCode设置字体

参考文章&#xff1a;【面向小白】vscode最佳实践&#xff08;2&#xff09;—— 字体设置&#xff08;fira code更纱黑体&#xff09;&#xff0c;这篇文章末尾给了安装字体的链接。 配置的字体还是很好看的。 ‘Fira Code Retina’, ‘Sarasa Mono Sc’ 需要注意的一个点&am…...

shell编程入门之提取字符并设置rtc时间

awk用法 awk是一款文本处理工具&#xff0c;通常在Unix和Linux操作系统中使用&#xff0c;用于以行为单位对文本进行处理和操作。它可以读取输入文本&#xff0c;对其进行处理&#xff0c;生成报表、统计信息等&#xff0c;并将结果输出到标准输出设备中。 它主要有以下特点&…...

react 不可变数据更新(Immutable Update)合并对象 类似与Java 的BeanUtils.copyProperties‌

{ ...state, // 保留原有的 state 的其他部分data: { ...state.data, // 保留 state.data 中的其他字段...action.payload // 使用 action.payload 覆盖 state.data 中需要更新的字段} }这段代码是 Redux 中常见的一种状态更…...

Linux GCC基础用法⑦

在 CentOS 7 系统中使用 GCC 与编写 99 乘法表 一、GCC 简介 GCC&#xff08;GNU Compiler Collection&#xff09;是一套功能强大的编程语言编译器&#xff0c;在 CentOS 7 系统中广泛用于编译 C、C等多种编程语言的程序。它能够将源代码转换为可执行文件&#xff0c;让计算…...

PyTorch 切片运算 (Slice Operator)

PyTorch 切片运算 {Slice Operator} 1. [:, -1, :]2. [:, [-1], :]References 1. [:, -1, :] https://github.com/karpathy/llama2.c/blob/master/model.py import torchlogits torch.arange(1, 16) print("logits.shape:", logits.shape) print("logits:\n&…...

SpringSecurity Oauth2 -账号密码实现多因子身份认证

1. 密码策略问题 CREATE TABLE t_storage (id bigint(20) NOT NULL AUTO_INCREMENT COMMENT 自增主键,nameSpace varchar(64) NOT NULL COMMENT 隔离字段,groupId varchar(128) NOT NULL COMMENT 分组&#xff0c;比如不同app,dataId varchar(64) NOT NULL COMMENT 数据存储id…...

【CSS in Depth 2 精译_071】11.4 思考字体颜色的对比效果 + 11.5 本章小结

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第四部分 视觉增强技术 ✔️【第 11 章 颜色与对比】 ✔️ 11.1 通过对比进行交流 11.1.1 模式的建立11.1.2 还原设计稿 11.2 颜色的定义 11.2.1 色域与色彩空间11.2.2 CSS 颜色表示法 11.2.2.1 RGB…...

Y3编辑器文档4:触发器1(对话、装备、特效、行为树、排行榜、不同步问题)

文章目录 一、触发器简介1.1 触发器界面1.2 ECA语句编辑及快捷键1.3 参数设置1.4 变量设置1.5 实体触发器1.6 函数库与触发器复用 二、触发器的多层结构2.1 子触发器&#xff08;在游戏内对新的事件进行注册&#xff09;2.2 触发器变量作用域2.3 复合条件2.4 循环2.5 计时器2.6…...

趣味编程:猜拳小游戏

1.简介 这个系列的第一篇以猜拳小游戏开始&#xff0c;这是源于我们生活的灵感&#xff0c;在忙碌的时代中&#xff0c;我们每个人都在为自己的生活各自忙碌着&#xff0c;奔赴着自己所走向的那条路上&#xff0c;即使遍体鳞伤。 但是&#xff0c;生活虽然很苦&#xff0c;也不…...

软件工程 概述

软件 不仅仅是一个程序代码。程序是一个可执行的代码&#xff0c;它提供了一些计算的目的。 软件被认为是集合可执行的程序代码&#xff0c;相关库和文档的软件。当满足一个特定的要求&#xff0c;就被称为软件产品。 工程 是所有有关开发的产品&#xff0c;使用良好定义的&…...

CountDownLatch阻塞后countDown未执行会如何?

背景 某项目封装了 Kafka 消费者 API&#xff0c;根据传递的消费者线程数&#xff0c;创建 N 个消费者线程同时消费对应 topic 的数据&#xff0c;并在线程启动后收集到全局列表中&#xff0c;方便在程序调用 stop 流程时逐个停止。 主控类在创建 Kafka 消费线程时使用了 Cou…...

k8s,operator

相对更加灵活和编程友好的管理“有状态应用”的解决方案&#xff0c;它就是&#xff1a;Operator 会议一下有状态应用&#xff1a; 比如数据库集群&#xff0c;数据挂载需要有顺序维护拓扑关系的应用 使用statefulSet这个对象来描述。 CRD又是什么&#xff1f; Operator的工作…...

使用 pyperclip 进行跨平台剪贴板操作

简介&#xff1a;pyperclip 是一个轻量级的 Python 库&#xff0c;支持在不同操作系统&#xff08;Windows、macOS、Linux&#xff09;中进行剪贴板的复制和粘贴。这个库的设计简单易用&#xff0c;非常适合需要频繁进行文本复制粘贴操作的场景。 历史攻略&#xff1a; 使用f…...

20 设计模式之职责链模式(问题处理案例)

一、什么是职责链模式 职责链模式是一种行为型设计模式&#xff0c;它允许将请求沿着处理者的链进行传递&#xff0c;直到有一个处理者能够处理它为止。换句话说&#xff0c;它将请求的发送者和接收者解耦&#xff0c;使得多个对象都有机会处理这个请求&#xff0c;从而避免了将…...

SpringBoot3集成MybatisPlus3和knife4j(swagger3兼容增强版)

针对Swagger2规范和OpenAPI3规范的说明: 在Spring Boot框架中,Knife4j对于服务端将Spring的开放接口解析成Swagger2或者OpenAPI3规范的框架,也是依赖的第三方框架组件。说明如下: Swagger2规范:依赖Springfox项目,该项目目前几乎处于停更状态,但很多老项目依然使用的是该…...

【MIT-OS6.S081作业1.3】Lab1-utilities primes

本文记录MIT-OS6.S081 Lab1 utilities 的primes函数的实现过程 文章目录 1. 作业要求primes (moderate)/(hard) 2. 实现过程2.1 代码实现 1. 作业要求 primes (moderate)/(hard) Write a concurrent version of prime sieve using pipes. This idea is due to Doug McIlroy, in…...

深圳最好的网站建设/如何在百度推广自己的产品

来源|新榜&#xff08;ID&#xff1a;newrankcn&#xff09;同样是在抖音里化妆、跳舞、才艺展示&#xff0c;甚至都是漂亮小哥哥小姐姐&#xff0c;但有人能拍出100W点赞爆款&#xff0c;有人只有5个&#xff0c;比如本人。虽然人类的本质是复读机&#xff0c;但你一定不甘心只…...

怎样创建网站域名平台/小程序推广50个方法

一、为什么要有Unsfae、我们为什么要了解这个类1. java通常的代码无法直接使用操作底层的硬件&#xff0c;为了使java具备该能力&#xff0c;增加了Unsafe类2.java的并发包中底层大量的使用这个类的功能&#xff0c;了解这个类有助于了解java 并发包&#xff0c;理解为什么并发…...

做网站在线视频如何添加/app推广30元一单

文章目录基于阈值的分割方法Otsu阈值分割自适应阈值分割最大熵阈值分割法迭代阈值分割基于边缘的分割方法基于区域的分割方法基于图论的分割方法基于聚类的分割方法基于能量泛函的分割方法曲线演化理论snake方法水平集(LevelSet)Active Contours Without Edges能量函数用水平集…...

广州网站建设联系新科海珠/建网站公司哪里好

和所有的程序语言都一样&#xff0c;如果使用了变量&#xff0c;但是变量是不同的数据类型&#xff0c;那么就会涉及到类型的转换。 Python 也提供了一些类型转换的函数&#xff0c;能够用于帮你将 Python 的变量类型完成转换。 考察下面的代码&#xff1a; # 类型转换 x s…...

四川蓉和建设公司网站/长尾关键词

alpha,4α alpha,5Α beta,4β beta,5Β gamma,4γ gamma,5Γ delta,4δ delta,5Δ epsilon,4ε epsilon,5Ε zeta,4ζ zeta,5Ζ eta,4η eta,5Η theta,4θ theta,5Θ iota,4ι iota,5Ι kappa,4κ kappa,5Κ lambda,4λ lambda,5Λ mu,4μ mu,5Μ nu…...

做设计那个素材网站最好/企业seo关键字优化

1&#xff0c;git安装完之后&#xff0c;打开git bash 命令行&#xff0c;执行以下命令&#xff1a; ssh-keygen -t rsa 然后按三下默认回车 2.执行查看公钥的命令&#xff1a; cat ~/.ssh/id_rsa.pub 3.最后把公钥复制放在阿里云的增加公钥里面 在本地仓库执行初始化&am…...