1.网络链接:端口号是与是一种用于网络通信的标识符,用于标识计算机上的不同网络应用程序或服务。在TCP/IP协议中,端口号是一个16位的数字,范围从0到65535。其中0到1023之间的端口号被称为"知名端口",用于标识常见的网络服务,例如HTTP、FTP等。而大于1023的端口号被称为"动态端口",用于临时分配给客户端应用程序。
2.设备链接:串口号是一种用于串行通信的标识符,通常用于连接计算机与外部设备,例如打印机、传感器等。串口号一般由一个数字表示,例如COM1、COM2等,用于标识计算机上的串口接口。串口通信是一种逐位传输数据的方式,数据通过一根串行传输线依次发送和接收。
设备->软件:软件通常会从对应的缓冲区读取信息。及串口链接中serialPort.Read就是从串口缓存区中读取的信息。
软件->设备:设备读取软件发送的信息通常是从缓存区读取的。缓存区是一块内存区域,用于临时存储数据。当软件发送信息时,这些信息会被暂时存放在缓存区中,然后设备会从缓存区中读取这些信息进行处理或传输。
SerialPort类是在C#的System.IO.Ports命名空间中定义的一个类,用于在计算机和串行设备之间进行通信。它提供了一组方法和属性,可以方便地进行读取和写入串行数据。
成员:
portName:表示串口的名称,例如"COM1","COM2"等。
baudRate:表示串口的波特率,即数据传输的速度。
dataBits:表示每个字节的数据位数,通常为8位。
parity:表示奇偶校验方式,有None、Odd、Even等选项。
stopBits:表示停止位的个数,通常为1或2。
ReadTimeout(读取超时):设置读取数据的超时时间,当超过该时间仍未读取到数据时,将引发超时异常。
ReadBufferSize(读取缓冲区大小):设置读取数据时的缓冲区大小,用于存储从串口读取的数据。
WriteBufferSize(写入缓冲区大小):设置写入数据时的缓冲区大小,用于存储待发送到串口的数据。
DtrEnable(DTR 使能):DTR (Data Terminal Ready) 是一个控制信号线,用于指示通信设备是否准备好接收或发送数据。该参数用于启用或禁用 DTR 信号线。
RtsEnable(RTS 使能):RTS (Request To Send) 是一个控制信号线,用于请求发送数据。该参数用于启用或禁用 RTS 信号线。
方法:
open():打开串口,建立与设备的连接。
close():关闭串口,断开与设备的连接。
isOpen():判断串口是否已经打开。
read(size):从串口读取指定大小的数据。
write(data):向串口写入数据。
flush():清空串口的接收缓冲区。
setPortName(port):设置串口的名称。
setBaudRate(baudrate):设置串口的波特率。
setDataBits(databits):设置每个字节的数据位数。
setParity(parity):设置奇偶校验方式。
setStopBits(stopbits):设置停止位的个数。
初始化:
new SerialPort(串口名称,波特率,无奇偶校验位,数据位,停止位)
C#创建线程不仅可以通过函数来创建,还可以使用匿名方法、Lambda 表达式或者委托来创建线程。下面是几种常见的创建线程的方法:
1. 使用Thread类:通过创建Thread类的实例并将要执行的方法作为参数传递给Thread类的构造函数来创建线程。
示例代码:```csharp void MyMethod() { // 线程执行的代码 } Thread thread = new Thread(MyMethod); thread.Start(); ```
2. 使用匿名方法:直接在Thread类的构造函数中定义匿名方法作为线程的执行体。
示例代码:```csharp Thread thread = new Thread(delegate () { // 线程执行的代码 }); thread.Start(); ```
3. 使用Lambda 表达式:使用Lambda 表达式作为线程的执行体。
示例代码:```csharp Thread thread = new Thread(() => { // 线程执行的代码 }); thread.Start(); ```
4. 使用委托:创建委托,并将要执行的方法作为委托的参数传递给Thread类的构造函数。
示例代码:```csharp void MyMethod() { // 线程执行的代码 } Action action = MyMethod; Thread thread = new Thread(new ThreadStart(action)); thread.Start(); ```
UI线程控件指的是用户界面(UI)线程上的控件。在大部分图形用户界面(GUI)应用程序中,包括网页和移动应用程序,UI线程用于处理与用户界面相关的任务,例如处理用户输入、更新界面上的控件等。因此当前控件线程访问其他控件线程会造成访问异常,可以使用来进行忽略线程权限检查。
Control.CheckForIllegalCrossThreadCalls = false; //忽略线程权限检查
// 通过读取配置文件进行数据库连接
public static string connstr = ConfigurationManager.ConnectionStrings["connstr"].ToString();
///
/// 执行增、删、改
///
///
///
private static int UpDate(string sqlstr)
{
MySqlConnection conn = new MySqlConnection(connstr);
MySqlCommand comm = new MySqlCommand(sqlstr, conn);
try
{
conn.Open();
int result = comm.ExecuteNonQuery();
return result;
}
catch (System.Exception ex)
{
// 写入系统日志
throw ex;
}
finally
{
conn.Close();
}
}
///
/// 查询:获取单一结果
///
///
///
public static object GetSingleResult(string sqlstr)
{
MySqlConnection conn = new MySqlConnection(connstr);
MySqlCommand comm = new MySqlCommand(sqlstr, conn);
try
{
conn.Open();
object result = comm.ExecuteScalar();
return result;
}
catch (System.Exception ex)
{
// 写入系统日志
throw ex;
}
conn.Close();
}
///
/// 查询:获取结果集合
///
///
///
public static MySqlDataReader GetDataReader(string sqlstr)
{
MySqlConnection conn = new MySqlConnection(connstr);
MySqlCommand comm = new MySqlCommand(sqlstr, conn);
try
{
conn.Open();
return comm.ExecuteReader(CommandBehavior.CloseConnection);
}
catch (System.Exception ex)
{
// 写入系统日志
conn.Clone();
throw ex;
}
finally
{
conn.Close();
}
}
MySqlDataReader,MySqlConnection和MySqlCommand都是与MySQL数据库交互的类。它们属于ADO.NET框架中的类,用于在C#中连接、查询和读取MySQL数据库。
- MySqlDataReader,数据阅读器,是用于从数据库中读取数据的类。通过执行查询语句并使用ExecuteReader方法,可以获取一个可用于逐行读取查询结果的数据流,从数据库中读取数据时,它会保持与数据库的连接,以便能够连续地从数据库中读取数据。一次性读取一行,可以通过reader.FieldCount指令来获取一行多少列。
- MySqlConnection,Conn,是用于建立与MySQL数据库的连接的类。它提供了连接字符串和一些方法来打开、关闭和管理数据库连接。需要手动打开以及即使关闭。
- MySqlCommand,Comm,是用于在MySQL数据库中执行SQL语句的类。可以通过实例化MySqlCommand对象,并将SQL语句和关联的连接传递给它,然后使用ExecuteNonQuery、ExecuteScalar或ExecuteReader等方法来执行SQL语句。ExecuteReader方法返回的是MySqlDataReader。
在类似于MySQL的关系型数据库中,还有其他一些常用类似的类,用于进行数据库交互。例如:
- SqlDataAdapter: 用于填充 DataSet(数据集)和 DataTable(数据表),可以通过执行SQL语句或存储过程来检索和更新数据。
- SqlCommandBuilder: 用于自动生成用于插入、更新和删除数据的 SQL 语句,它基于已给定的 SELECT 语句。
- SqlDataReader: 用于从数据库中以只进流的方式读取数据,对于大量数据或只需逐行处理数据时比较有效。
- SqlParameter: 用于向 SQL 语句传递参数,并保护代码免受 SQL 注入攻击。
在.NET桌面开发中,具有控件树,可以使用Control类的Find方法来根据变量存放的控件Name获取到对应的控件对象,然后通过该对象来设置控件的属性。
例如,假设您有一个变量存放了一个按钮的Name,您可以使用以下代码来设置该按钮的Text属性:
string controlName = "button1"; // 假设变量存放了按钮的Name
Button button = this.Controls.Find(controlName, true).FirstOrDefault() as Button; // 查找到对应的按钮对象
if (button != null)
{
button.Text = "新的按钮文本"; // 设置按钮的Text属性
}
需要注意的是,Find方法是在当前窗体的控件集合中进行查找,如果需要在整个应用程序中查找,使用Application.OpenForms属性。
C#中有多个数据结构可用,以下是其中一些常见的数据结构:
- 数组(Array):用于存储同类型的元素,并通过索引访问元素。
- 列表(List):使用动态数组实现的有序集合,可以动态添加或删除元素。
- 链表(LinkedList):由节点组成的有序集合,每个节点包含一个值和一个指向下一个节点的引用。
- 栈(Stack):后进先出(LIFO)的数据结构,只允许在栈顶进行插入和删除操作。
- 队列(Queue):先进先出(FIFO)的数据结构,只允许在队列尾部插入元素,在队列头部删除元素。
- 字典(Dictionary):键值对的集合,通过键来访问值,键是唯一的。
- 集合(Set):唯一元素的无序集合,不允许重复元素。
- 哈希表(Hashtable):基于键值对的集合,通过哈希函数将键映射到值。
- 树(Tree):由节点组成的层次结构,每个节点可以有多个子节点。
- 图(Graph):由节点和边组成的非线性结构,节点可以相互连接。
List是 有序集合,所以具有下表标识。
List是一个非常常用的数据结构,它是一个可变长度的数组容器。它提供了一些方便的方法来操作和管理元素,比如添加、删除、查找等。
List是一个泛型类,可以存储任意类型的元素。你可以创建一个List对象,并指定元素的类型,例如:
List numbers = new List(); // 创建一个存储整数的List
List names = new List(); // 创建一个存储字符串的List
List
要向List中添加元素,可以使用Add方法:
numbers.Add(10);
numbers.Add(20);
numbers.Add(30);
要访问List中的元素,可以使用索引。List中的元素从0开始编号,所以第一个元素的索引是0,第二个元素的索引是1,依此类推。也可以通过foreach来进行遍历:
int firstNumber = numbers[0]; // 获取第一个元素
int secondNumber = numbers[1]; // 获取第二个元素
foreach(int i in test) //通过foreach遍历
{
Console.WriteLine(i);
}
可以使用Count属性获取List中元素的数量:
int count = numbers.Count;
要删除List中的元素,可以使用Remove方法:
numbers.Remove(20); // 删除值为20的元素
Hashtable和Dictionary都是用于存储键值对的数据结构,同样是哈希表数据结构,但它们有一些区别。
主要区别如下:
实现方式:Hashtable是通过散列函数将键映射到索引来存储数据,而Dictionary则是使用泛型来实现的键值对集合。
键类型:Hashtable允许使用任意对象作为键,而Dictionary要求键类型必须是可哈希的(即要求实现了GetHashCode方法和Equals方法)。
线程安全性:Hashtable是线程安全的,因为它的所有操作都是同步的。而Dictionary不是线程安全的,如果涉及多个线程同时访问,需要使用额外的同步机制来保证线程安全。
性能:由于Hashtable的线程同步机制,在多线程环境下性能稍低于Dictionary。
Hashtable例子
using System;
using System.Collections;
class Program
{
static void Main()
{
// 创建一个空的 Hashtable
Hashtable myHashtable = new Hashtable();
// 添加键值对
myHashtable["apple"] = 5;
myHashtable["banana"] = 3;
myHashtable["orange"] = 2;
// 访问值
Console.WriteLine(myHashtable["apple"]); // 输出:5
// 检查是否包含某个键
if (myHashtable.Contains("banana"))
{
Console.WriteLine("My hashtable contains 'banana'.");
}
// 遍历所有的键值对
foreach (DictionaryEntry entry in myHashtable)
{
Console.WriteLine("Key: " + entry.Key + ", Value: " + entry.Value);
}
}
}
Dictionary例子
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
// 创建一个空的 Dictionary
Dictionary myDictionary = new Dictionary();
// 添加键值对
myDictionary["apple"] = 5;
myDictionary["banana"] = 3;
myDictionary["orange"] = 2;
// 访问值
Console.WriteLine(myDictionary["apple"]); // 输出:5
// 检查是否包含某个键
if (myDictionary.ContainsKey("banana"))
{
Console.WriteLine("My dictionary contains 'banana'.");
}
// 遍历所有的键值对
foreach (KeyValuePair kvp in myDictionary)
{
Console.WriteLine("Key: " + kvp.Key + ", Value: " + kvp.Value);
}
}
}
DictionaryEntry类型是C#中的一个结构体,用于表示Dictionary
中的键值对。它包含两个属性:Key和Value,分别表示字典或哈希表中的键和对应的值。 DictionaryEntry主要用于遍历字典和哈希表元素,通过迭代器可以逐个访问字典中的键值对。在遍历过程中,每个键值对都被封装成一个DictionaryEntry结构体,方便获取键和值。
set和list都是集合的数据结构,下面是Set和List的一些主要区别:
重复元素:List允许包含重复的元素,而Set不允许。
顺序:List是有序的,可以按照添加顺序或索引进行访问。Set是无序的,没有特定的顺序。
搜索效率:由于List是有序的,可以使用二分搜索算法进行快速搜索。Set使用哈希表实现,因此搜索效率更高。
内存占用:由于Set需要维护唯一性,因此可能会占用更多的内存空间。而List只需按顺序存储元素即可。
JSON优点是值可以是json类型,及就可以实现嵌套。
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
class Program
{
static void Main(string[] args)
{
// 创建一个 JObject 对象
JObject json = new JObject();
// 添加第一层嵌套的属性
json["name"] = "John";
json["age"] = 30;
// 创建一个第二层嵌套的 JObject 对象
JObject address = new JObject();
address["street"] = "123 Main St";
address["city"] = "New York";
address["state"] = "NY";
// 将第二层嵌套的 JObject 对象添加到第一层嵌套的 JObject 对象中
json["address"] = address;
// 创建一个数组
JArray hobbies = new JArray();
hobbies.Add("reading");
hobbies.Add("playing guitar");
hobbies.Add("hiking");
// 将数组添加到第一层嵌套的 JObject 对象中
json["hobbies"] = hobbies;
// 打印 JSON 数据
Console.WriteLine(json.ToString());
}
}
输出
{
“name”: “John”,
“age”: 30,
“address”:
{
“street”: “123 Main St”,
“city”: “New York”,
“state”: “NY”
},
“hobbies”:
[
“reading”,
“playing guitar”,
“hiking”
]
}
数组(Array)用方括号(“
[]
”)表示。对象(0bject)用大括号(“
{}
”)表示。名称/值对(
name/value
)组合成数组和对象。名称(
name
)置于双引号中,值(value
)有字符串、数值、布尔值、null、对象和数组。并列的数据之间用逗号(“
,
”)分隔
json在c#中可以使用.或[]来进行表示,遍历json里面的数据可以通过将json数据提取成动态或静态类型来处理。
dynamic val = JsonConvert.DeserializeObject(JSON);
foreach(var i in val[val])
{
MessageBox.Show(i[test]);
}
for(int i=0;i<((JArray)val["val"]).Count;i++)
{
MessageBox.Show(val[val][i]);
}
动态类型和静态类型是编程语言中常见的两种类型系统。它们的区别主要在于类型检查的时机和方式。
静态类型指的是在编译阶段进行类型检查的类型系统。在静态类型语言中,变量的类型在编译过程中确定,并且类型错误会在编译时被发现。编译器会检查变量的声明和使用是否符合语言定义的类型规则。这样可以提前发现潜在的类型错误,减少运行时错误的风险。
动态类型指的是在运行时进行类型检查的类型系统。在动态类型语言中,变量的类型在运行时确定,并且类型错误会在运行时被发现。变量可以在运行时改变其类型,而不需要提前进行声明或定义。这样可以提供更大的灵活性和简化开发过程,但也增加了运行时错误的风险。
总结来说,静态类型语言在编译阶段进行类型检查,提前发现潜在错误;而动态类型语言在运行时进行类型检查,提供更大的灵活性。
按值传递(默认)和引用传递(ref)。基本类型都是大部分都是默认按值,只有引用类型默认是按地址传递。string因为一经创建就不能修改,虽然也是引用类型,但是默认是按值传递的,因为一经创建实际就是新的string了。
按值
void ChangeValue(int num)
{
num = 10;
}
int value = 5;
ChangeValue(value);
Console.WriteLine(value); // 输出结果为5,原始实参的值不受方法内部的修改影响
引用
void ChangeValue(ref int num)
{
num = 10;
}
int value = 5;
ChangeValue(ref value);
Console.WriteLine(value); // 输出结果为10,原始实参的值受方法内部的修改影响
int downlocation = 0; //可放置控件位置坐标(当前最低控件底边坐标+控件间隔距离)
using (var tempForm = new Form())
{
int tibutton = 0; //提交按钮是否显示
Hashtable conval = new Hashtable();
for (int i=0; i< ((JArray)val["val"]).Count;i++)//控件层
{
if (val["val"][i]["type"] == "Button")
{
tibutton = 1; //提交按钮不显示
int controllerhight = 20; //控件高度
int controllerinterval = 5; //控件间隔
for (int coarray_position = 0; coarray_position < ((JArray)val["val"][i]["val"]["name"]).Count; coarray_position++)
{
string control_name = val["val"][i]["val"]["name"][coarray_position];
string control_value = val["val"][i]["val"]["val"][coarray_position];
Console.WriteLine(control_name);
Console.WriteLine(control_value);
var button = new Button();
button.Text = control_name;
button.Size = new System.Drawing.Size(tempForm.Width, controllerhight);
button.Location = new Point(0, downlocation);
downlocation = downlocation + controllerhight + controllerinterval;
button.Click += (s, ev) =>
{
MessageBox.Show(control_value);
this.Text = control_value;
};
tempForm.Controls.Add(button);
}
}
else if (val["val"][i]["type"] == "Radio")
{
var groupbox = new GroupBox(); //容器
groupbox.Text = val["val"][i]["name"];
int controllerhight = 20; //容器高度=控件最低位置+控件高度+预定值
int controllerinterval = 5; //容器间隔
int radiointerval = 5; //控件间隔
int radioheight = 20; //控件高度
for (int coarray_position = 0; coarray_position < ((JArray)val["val"][i]["val"]["name"]).Count; coarray_position++)
{
string control_name = val["val"][i]["val"]["name"][coarray_position];
string control_value = val["val"][i]["val"]["val"][coarray_position];
Console.WriteLine(control_name);
Console.WriteLine(control_value);
var radiobox = new RadioButton();
radiobox.Text = control_name;
radiobox.Size = new System.Drawing.Size(tempForm.Width, radioheight);
radiobox.Location = new Point(0, controllerhight);
controllerhight = controllerhight + radioheight + radiointerval;
radiobox.Click += (s, ev) =>
{
MessageBox.Show(control_value);
conval[groupbox.Text] = control_value;
};
groupbox.Controls.Add(radiobox);
}
groupbox.Size = new System.Drawing.Size(tempForm.Width, controllerhight); //容器大小
groupbox.Location = new Point(0, downlocation); //容器位置
downlocation = downlocation + controllerinterval + controllerhight; //重新设置最低位置
tempForm.Controls.Add(groupbox);
}
}
if(tibutton==0)
{
var button = new Button(); //提交按钮
button.Text = "提交";
button.Size = new System.Drawing.Size(tempForm.Width, 20);
button.Location = new Point(0, downlocation);
button.Click += (s, ev) =>
{
foreach (DictionaryEntry entry in conval)
{
MessageBox.Show("Key: " + entry.Key + ", Value: " + entry.Value);
}
};
tempForm.Controls.Add(button);
}
tempForm.ShowDialog();
}
}
在这段代码中,conval[groupbox.Text] = control_value;代码因为闭包实现了显示对应的值的功能。并没有一直显示最后一个函数,因为每次当for循环一次后,for循环内部就形成了闭包,内部存储的数据都有单独的存放,之后的循环再次创建以及赋值也不会影响循环内创建或设置的变量。及函数内部创建的变量的值会被保留。
闭包是一种编程概念,它可以让一个函数捕获并保存其所在作用域的状态。换句话说,闭包可以让函数访问其外部作用域中的变量,即使在函数执行完毕后,这些变量也会被保存下来。
当一个嵌套函数(内部函数)引用了外部函数的变量时,就会创建一个闭包。内部函数可以访问外部函数的变量,这是由于内部函数保留了对外部作用域的引用。
闭包的工作原理如下:
当外部函数执行时,会创建一个新的执行上下文,并将该执行上下文添加到调用栈中。在这个执行上下文中,会创建一些局部变量。
如果内部函数引用了外部函数的变量,则会将这些变量添加到内部函数的作用域链中。
当外部函数执行完毕时,它的执行上下文会从调用栈中弹出,但闭包中引用的外部变量不会被销毁。
内部函数可以继续访问和操作闭包中的外部变量,因为它仍然保留了对外部作用域的引用。
闭包的特点:
闭包可以访问和修改外部函数的变量。
外部函数的执行上下文在内部函数执行完毕后不会被销毁,以便内部函数可以继续访问外部变量。
闭包可以作为返回值,或者作为参数传递给其他函数。
try
{
// 可能会抛出异常的代码
}
catch (Exception ex)
{
// 异常处理代码
}
finally
{
// 最终执行代码
}
try语句块:包含有可能会抛出异常的代码,如果在这段代码中发生了异常,那么程序就会跳转到catch语句块来进行异常处理。
catch语句块:用于捕获异常和处理异常。在catch语句块中,我们可以使用Exception类的各种方法来查看捕获到的异常的具体信息,并根据情况进行处理。
finally语句块:无论try语句块中的代码是否有异常,都会执行的代码块。通常在这个块中,我们会进行一些资源的回收或清理工作。
Convert.ToInt32()和int.Parse()都可以将字符串转换为整数类型,但是它们有以下区别:
- Convert.ToInt32()可以将null转换为0,而int.Parse()会抛出异常。
- Convert.ToInt32()可以将一些非数字字符串转换为整数类型,例如"true"会被转换为1,"false"会被转换为0,而int.Parse()会抛出异常。
c#有两种发送和接收模式。
同步传输(阻塞传输)是数据发送或接收后,可以得知数据是否发送成功或者失败,在发送或接收完成之前会阻塞,系统挂起,等待完成。相当于执行到发送指令,系统就把在发送缓存区的数据开始发送。
异步传输(非阻塞传输)是不管数据是否发送成功,继续执行指令,系统不会阻塞。相当于执行到发送指令,系统会把数据存放在发送缓存区,由底部来进行发送,系统并不关心是否发送。
c#默认是同步传输,及传输数据之后就有返回值,可以知道数据是否发送成功。c#的异步传输采用回调函数实现,c#封装好一个异步类,我们把需要执行的函数注册进类即可。
BeginAccept:开始一个异步的Accept操作,等待客户端连接。
EndAccept:结束一个异步的Accept操作,并返回一个新的Socket对象,该对象表示连接的客户端。
BeginConnect:开始一个异步的Connect操作,尝试连接到指定的服务器。
EndConnect:结束一个异步的Connect操作。
BeginReceive:开始一个异步的Receive操作,等待接收数据。
EndReceive:结束一个异步的Receive操作,并返回接收到的数据字节数。
BeginSend:开始一个异步的Send操作,发送数据。
EndSend:结束一个异步的Send操作,并返回发送的数据字节数。
BeginDisconnect:开始一个异步的Disconnect操作,关闭连接。
EndDisconnect:结束一个异步的Disconnect操作。
1553B数据传输通过双绞线进行,每个节点都有一个独特的地址,并且可以作为总线上的发送器或接收器。数据传输分为两种类型:命令/响应(Command/Response)和广播(Broadcast)。命令/响应模式下,一个节点向另一个节点发送指令并等待响应;而广播模式下,则是所有节点都能够接收到同样的信息。
BC:总线控制器, bus controller:它是在总线上唯一被安排为执行建立和启动数据传输任务的终端。
RT:远程终端,remote terminal:它是用户子系统到数据总线上的接口,他在BC的控制下提取数据或接受数据。1553B总线上最多可以连接32个RT设备。每个RT设备都有唯一的地址码,范围从0到31。这些地址码用于识别和寻址特定的RT设备。
BM/MT:总线监视器,bus monitor terminal:它“监控”总线上的信息传输,以完成对总线上的数据源进行记录和分析,但他本身不参与总线的通信。
子地址:每个节点都有一个唯一的主地址和多个子地址。当一个节点发送消息时,它可以选择将消息发送到其主地址或任何一个子地址。如果消息被发送到了一个子地址,那么只有具有该子地址的节点才会接收到该消息。
复用方法:采用了时间分割多路复用(Time Division Multiplexing, TDM)技术。1553B总线中的每个设备都有自己的接收和发送缓冲区,当总线上出现空闲时间时,各个设备会根据优先级依次请求发送数据。总线控制器会根据请求的优先级选择一个设备进行数据传输,在该设备的时间片内,它可以向总线发送数据或者从总线接收数据。当该设备的时间片结束后,总线控制器会选择下一个设备进行数据传输。将一秒分割成好几份,一份即一帧,每个帧周期又被分割成好几份子帧,一个子帧发送数据。
emgucv是opencv的封装,在c#中可以方便的进行调用,不用再创建动态链接库。
Image格式:源自 Bitmap 和 Metafile 的类提供功能的抽象基类。
注: 可以利用PictureBox组件显示Mat格式:Mat是一个类,记录和存储图像数据,主要由两个数据部分组成: < 矩阵头(大小,通道,数据类型等) > 和 < 数据块(像素值) > 。
Bitmap格式:封装 GDI+ 位图,此位图由图形图像及其属性的像素数据组成。 Bitmap 是用于处理由像素数据定义的图像的对象 。
注: 可以利用PictureBox组件显示Image
格式:这个类包含两个泛型参数:TColor和TDepth,定义一个Image对象时,需要指定色彩空间类型和数据深度。
注: 不可以利用PictureBox组件显示UMat格式Mat类型的父类UMat,Mat,只有当你知道自己在做什么时才应该使用。在大多数情况下,您应该使用Matrix类。
注: 不可以利用PictureBox组件显示Matrix格式Matrix是OpenCV的cvMat的包装器。
注: 不可以利用PictureBox组件显示关于Emgu中图像数据格式说明(Mat,Image,BitMap)_emgucv mat转bitmap_啥都亿点点的研究生的博客-CSDN博客
https://blog.csdn.net/lichaoqi1/article/details/131216768
Image类:表示图像数据。它包括多个子类,如Bgr、Gray、Hsv等,分别表示不同的图像颜色空间。
Mat类:与Image类类似,也是表示图像数据。不同的是,Mat类是基于OpenCV的cv::Mat类实现的,而Image类则是Emgu CV自己定义的。Mat类的性能更高。
Bitmap类:表示Windows GDI中的位图数据。
VideoCapture类:表示视频捕获设备,可以用来从摄像机、视频文件、网路视频等获取视频数据。
VideoWriter类:表示视频写入设备,可以用来将视频数据写入到文件、网络流等。
CascadeClassifier类:表示基于Haar特征的目标检测器,可以用来检测人脸、车辆等物体
bitmap------>Image
Image
test = bitmap.ToImage (); bitmap------>mat
Mat bitmat = BitmapExtension.ToMat(bitimg);
Image
------>bitmap Bitmap bitmap = image.ToBitmap
(); Image
------>mat Mat mat = image.Mat;
mat------>bitmap
Bitmap bitmap = mat.ToBitmap();
mat------>Image
Image
immat = mat.ToImage ();
Bitmap:
Bitmap 是 .NET Framework 中的一个类,用于表示由像素组成的位图图像。它常用于 Windows 窗体应用程序中,用于表示界面上的图像。在 EmguCV 中,Bitmap 可以通过 Convert 方法转换为 Image 对象,然后再进行图像处理。
Image
: Image
是 EmguCV 中用于表示彩色图像的类,其中 Bgr 表示像素的顺序为蓝、绿、红,byte 表示像素深度为 8 位。它是 EmguCV 中最基本的图像类型之一,可以进行大部分的图像处理操作。在 EmguCV 中,Image 可以通过 Convert 方法转换为 Bitmap 或 Mat 对象。 Mat:
Mat 是 EmguCV 中用于表示图像的矩阵类。它是 OpenCV 中的一个概念,用于表示一张图像的像素数据。在 EmguCV 中,Mat 可以通过 ToImage 方法转换为 Image 对象,或者通过 ToBitmap 方法转换为 Bitmap 对象。
Mat 对象具有更高的灵活性和可操作性,它可以通过各种方式创建和修改,还可以与各种文件格式交互。在进行图像处理时,Mat 对象通常是最常用的图像类型之一。