【项目原理】多点触摸屏驱动原理

news2024/12/28 12:32:57

一、屏幕介绍

ATK-7016 这款屏幕其实是由 TFT LCD+触摸屏组合起来的。底下是 LCD 面板,上面是触摸面板,将两个封装到一起就成了带有触摸屏的 LCD 屏幕。电容触摸屏也是需要一个驱动 IC的,驱动 IC 一般会提供一个 I2C 接口给主控制器,主控制器可以通过 I2C 接口来读取驱动 IC里面的触摸坐标数据。ATK-7016、ATK-7084 这两款屏幕使用的触摸控制 IC 是 FT5426,ATK-4342 使用的驱动 IC 是 GT9147,ATK-4384 使用的驱动 IC 是 GT1151。这些电容屏触摸 IC 都是 I2C 接口的,使用方法基本一样。

ATK-4384 的电容触摸屏部分有 4 个 IO 用于连接主控制器:SCL、SDA、RST 和 INT,SCL 和 SDA 是 I2C 引脚,RST 是复位引脚,INT 是中断引脚。一般通过 INT 引脚来通知主控制器有触摸点按下,然后在 INT 中断服务函数中读取触摸数据。也可以不使用中断功能,采用轮询的方式不断查询是否有触摸点按下,本章实验我们使用中断方式来获取触摸数据。


二、触摸驱动分析

1、驱动框架分析

按照https://blog.csdn.net/qq_41709234/article/details/128661071的说法:

驱动程序编写主要参考《正点原子开发指南》,在裸机开发中进行触摸屏的驱动,主要流程如下:

  ①、电容触摸屏是IIC接口的,需要触摸 IC,以正点原子的 ATK4384 为例,其所使用的触
摸屏控制 IC 为GT1151,因此所谓的电容触摸驱动就是 IIC设备驱动。 
  ②、触摸IC提供了中断信号引脚(INT),可以通过中断来获取触摸信息。 
  ③、电容触摸屏得到的是触摸位置绝对信息以及触摸屏是否有按下。 
  ④、电容触摸屏不需要校准,当然了,这只是理论上的,如果电容触摸屏质量比较差,或
者触摸玻璃和 TFT 之间没有完全对齐,那么也是需要校准的。 

那么电容触摸屏的Linux驱动主要需要以下几个驱动框架的组合:

  ①、IIC 设备驱动,因为电容触摸IC基本都是IIC接口的,因此大框架就是IIC设备驱动。 
  ②、通过中断引脚(INT)向linux内核上报触摸信息,因此需要用到linux中断驱动框架。
标的上报在中断服务函数中完成。 
  ③、触摸屏的坐标信息、屏幕按下和抬起信息都属于linux的input子系统,因此向 linux 内
核上报触摸屏坐标信息就得使用input子系统。

2、多点触摸(MT)协议详解 

MT 协议隶属于 linux的 input 子系统,驱动通过大量的 ABS_MT 事件向 linux 内核上报多点触摸坐标数据。根据触摸 IC 的不同,分为 Type A 和 Type B 两种类型,目前使用最多的是 Type B 类型。

老版本的 linux 内核是不支持多点电容触摸的(Multi-touch,简称 MT),MT 协议是后面加入的,因此如果使用 2.x 版本 linux 内核的话可能找不到 MT 协议。

触摸点的信息通过一系列的 ABS_MT 事件(有的资料也叫消息)上报给 linux 内核,只有ABS_MT 事件是用于多点触摸的:

852 #define ABS_MT_SLOT        0x2f /* MT slot being modified */ 
853 #define ABS_MT_TOUCH_MAJOR  0x30 /* Major axis of touching ellipse */ 
854 #define ABS_MT_TOUCH_MINOR  0x31 /* Minor axis (omit if circular) */ 
855 #define ABS_MT_WIDTH_MAJOR  0x32 /* Major axis of approaching ellipse */ 
856 #define ABS_MT_WIDTH_MINOR  0x33 /* Minor axis (omit if circular) */ 
857 #define ABS_MT_ORIENTATION  0x34 /* Ellipse orientation */ 
858 #define ABS_MT_POSITION_X   0x35 /* Center X touch position */ 
859 #define ABS_MT_POSITION_Y   0x36 /* Center Y touch position */ 
860 #define ABS_MT_TOOL_TYPE    0x37 /* Type of touching device */ 
861 #define ABS_MT_BLOB_ID       0x38 /* Group a set of packets as a blob */ 
862 #define ABS_MT_TRACKING_ID  0x39 /* Unique ID of initiated contact */ 
863 #define ABS_MT_PRESSURE     0x3a /* Pressure on contact area */ 
864 #define ABS_MT_DISTANCE      0x3b /* Contact hover distance */ 
865 #define ABS_MT_TOOL_X        0x3c /* Center X tool position */ 
866 #define ABS_MT_TOOL_Y        0x3d /* Center Y tool position */ 

🎍 TypeA

对于 Type A 类型的设备,通过 input_mt_sync()函数来隔离不同的触摸点数据信息:

void input_mt_sync(struct input_dev *dev) 

该函数会触发 SYN_MT_REPORT 事件,此事件会通知接收者获取当前触摸数据,并且准备接收下一个触摸点数据。 

不管是哪个类型的设备,最终都要调用 input_sync()函数来标识多点触摸信息传输完成,告诉接收者处理之前累计的所有消息,并且准备好下一次接收。

对于 Type A 类型的设备,发送触摸点信息的时序如下所示,这里以 2 个触摸点为例:

ABS_MT_POSITION_X x[0]// ABS_MT_POSITION_X 、 ABS_MT_POSITION_Y事件
ABS_MT_POSITION_Y y[0]// input_report_abs来完成坐标上报
SYN_MT_REPORT// input_mt_sync()函数会触发SYN_MT_REPORT事件
ABS_MT_POSITION_X x[1]
ABS_MT_POSITION_Y y[1]
SYN_MT_REPORT
SYN_REPORT

 实例:

static irqreturn_t st1232_ts_irq_handler(int irq, void *dev_id)
{
    ...
    // 获取所有触摸点的信息
    ret = st1232_ts_read_data(ts);
    if (ret < 0)
        goto end;

    /* multi touch protocol */
    for (i = 0; i < MAX_FINGERS; i++) {
        if (!finger[i].is_valid)
            continue;
        
        // 按照TypeA时序上报所有触摸点的信息
        input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, finger[i].t);/ ABS_MT_TOUCH_MAJOR常数用于表示触摸接触区域的主轴长度
        input_report_abs(input_dev, ABS_MT_POSITION_X, finger[i].x);
        input_report_abs(input_dev, ABS_MT_POSITION_Y, finger[i].y);
        input_mt_sync(input_dev);
        count++;
    }


/* SYN_REPORT */
input_sync(input_dev);


end: 
     return IRQ_HANDLED; 
} 

🎍 TypeB

Type B 使用 slot 协议区分具体的触摸点,Type B 设备驱动需要给每个识别出来的触摸点分配一个 slot,后面使用这个 slot 来上报触摸点信息。可以通过 slot 的 ABS_MT_TRACKING_ID 来新增、替换或删除触摸点。

ABS_MT_TRACKING_ID跟踪ID:一个非负数的 ID 表示一个有效的触摸点,-1 这个 ID 表示未使用 slot。一个以前不存在的 ID 表示这是一个新加的触摸点,一个 ID 如果再也不存在了就表示删除了。

上报触摸点信息的时候需要通过 input_mt_slot()函数区分是哪一个触摸点:

void input_mt_slot(struct input_dev *dev, int slot) 

该函数会触发 ABS_MT_SLOT 事件,此事件会告诉接收者当前正在更新的是哪个触摸点(slot)的数据。 

不管是哪个类型的设备,最终都要调用 input_sync()函数来标识多点触摸信息传输完成,告诉接收者处理之前累计的所有消息,并且准备好下一次接收。

对于 Type B 类型的设备,发送触摸点信息的时序如下所示,这里以 2 个触摸点为例: 

ABS_MT_SLOT 0// 使用 input_mt_slot 函数上报当前触摸点的 ABS_MT_SLOT 事件,触摸IC提供
ABS_MT_TRACKING_ID 45// input_mt_report_slot_state完成 Type B 的要求,即每个 SLOT 必须关联一个ABS_MT_TRACKING_ID
ABS_MT_POSITION_X x[0]
ABS_MT_POSITION_Y y[0]
ABS_MT_SLOT 1
ABS_MT_TRACKING_ID 46
ABS_MT_POSITION_X x[1]
ABS_MT_POSITION_Y y[1]
SYN_REPORT// 当所有的触摸点坐标都上传完毕以后就得发送 SYN_REPORT 事件,使用 input_sync 函数来完成。 

// 当一个触摸点移除以后
ABS_MT_TRACKING_ID -1 // 负1表示这个ID不使用SLOT,同样使用input_mt_report_slot_state函数,第三个参数为false即可,无需手动置为-1
SYN_REPORT// 使用input_sync函数表示上报结束

实例: 

static void ili210x_report_events(struct input_dev *input, const struct touchdata *touchdata)
{
    int i;
    bool touch;
    unsigned int x, y;
    const struct finger *finger;

    // 循环上报所有触摸点
    for (i = 0; i < MAX_TOUCHES; i++) {
        input_mt_slot(input, i);// ABS_MT_SLOT事件

        finger = &touchdata->finger[i];

        touch = touchdata->status & (1 << i);
        input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);// 上报ABS_MT_TRACKING_ID事件,也就是给 SLOT 关联一个ABS_MT_TRACKING_ID。
        if (touch) {
            x = finger->x_low | (finger->x_high << 8);
            y = finger->y_low | (finger->y_high << 8);

            input_report_abs(input, ABS_MT_POSITION_X, x);
            input_report_abs(input, ABS_MT_POSITION_Y, y);
        }
    }

    input_mt_report_pointer_emulation(input, false);
    input_sync(input);// 上报SYN_REPORT事件
}

🎍 MT触摸协议A、B总结 

🎍 疑问及解答

1.TypeA和TypeB两种类型的区别如下: 

1.TypeA协议

  1. 触摸点数量:TypeA协议可以检测到屏幕上同时触摸的触摸点数量,通常只能检测到一个或多个点。

  2. 触摸点的持续时间:TypeA协议可以检测到每个触摸点的持续时间,即触摸点在屏幕上停留的时间。

  3. 触摸点的坐标:TypeA协议不能直接获取每个触摸点的具体位置信息,但可以通过触摸点数量和持续时间等参数来判断触摸点的大致位置。

需要注意的是,TypeA协议是一种较为简单的触摸协议,主要用于实现一些简单的触摸操作,如滑动、点击和长按等。

2.TypeB协议

相比于TypeA协议,TypeB协议支持多点触控,并且能够获取更为详细的触摸信息:

  1. 触摸点数量:TypeB协议可以检测到屏幕上同时触摸的多个触摸点数量,通常可以检测到两个或更多个点。

  2. 触摸点的坐标:TypeB协议可以获取每个触摸点的具体位置信息,包括横纵坐标和压力值等。

  3. 触摸点的面积:TypeB协议可以获取每个触摸点的面积,即触摸点在屏幕上占据的面积大小。

  4. 触摸点的速度和方向:TypeB协议可以根据触摸点的坐标和时间信息,计算触摸点的速度和方向,从而实现手势识别等功能。

  5. 多点触控:TypeB协议支持多点触控,可以同时处理多个触摸点的信息,从而实现更为复杂的触摸操作,如缩放、旋转和拖拽等。

TypeB协议相比于TypeA协议,需要更高级的硬件支持,如电容式触摸屏等,而且在一些低端设备上可能无法使用。

3.总结

TypeA协议主要关注触摸点的数量,但并不追踪每个触摸点的具体位置。相反,TypeB协议会为每个触摸点分配一个slot,这个slot包含了触摸点的识别信息(ID)和位置信息。

4.举例说明

假设你有一个触摸屏,用户同时按下了两个点。在TypeA协议下,你只能知道屏幕上有两个点被按下,但无法得知这两个点的具体位置。这会导致触摸不够准确,因为你无法区分这两个点的具体信息。

而在TypeB协议下,每个触摸点都会被分配一个slot。例如,第一个触摸点被分配到slot 0,第二个触摸点被分配到slot 1。这样一来,你就可以知道每个触摸点的具体位置了。

2.什么是slot?什么是ID?

  1. slot:是一个用于存储触摸点信息的容器,包括触摸点的ID和位置信息。每个触摸点都会被分配一个slot,以便系统能够追踪多个触摸点。
  2. ID:是触摸点的唯一标识符,用于区分不同的触摸点。系统可以通过ID来追踪触摸点的移动。

3.MT多点触摸协议中TypeB中的slot,按下屏幕上的按键,分配一个slot和一个唯一的ID,在不抬起的情况下移动这个点,slot和ID会发生什么变化?

  1. 该触摸点所占用的slot和ID不会发生改变。它会继续使用原来分配给它的那个slot和ID。

  2. 其他新的触摸点如果产生,会分配新的未使用的slot和新的唯一ID。

  3. 如果原来的某个触摸点被抬起,其所占用的slot和ID将被释放,供新触摸点使用。

  4. 如果某个触摸点由于移动越过屏幕边缘被结束,其所占用的slot和ID也将被释放。

4.MT多点触摸协议中TypeB,如果首先按下一个点,再按下一个点,再次按下一个点,然后抬起第二个按下的点,再按下一个新的点,slot和ID如何发生变化?

  1. 首先按下第一个点,分配slot 1和 ID 1;
  2. 按下第二个点,分配slot 2和 ID 2;
  3. 按下第三个点,如果slot 1和2都被占用,会分配slot 3和 ID 3;
  4. 抬起第二个点(ID 2),释放其slot 2;
  5. 按下新的第四个点,由于slot 2已空闲,会分配slot 2和新的唯一ID,例如 ID 4。

​​​​5.为什么需要ID和slot配合,单独使用slot或者ID为什么不能完成多点触摸功能呢?

  1. slot 数量是有限的,并且slot的使用可以确保每个触摸点都分配一个独占的通道来传输触摸相关信息但是,(原因解释),如果在同一帧内,其中4个点(A,B,C和D)持续活动,我们可能会分配slot1-4。如果我们增加了第5个和第6个点E和F,slot 5和6也可能被分配,超出原有范围,在这种情况下,slot冲突就可能发生。另一方面,如果在后续帧中,部分点(例如B和D)不再活动,但新的点(G和H)出现,我们会释放slot 2和4,并分配新的slot 5和6。此时,slot 映射会变得非常混乱和不直观。很难通过slot数来确定某个点的信息通道,也就是说,我想对第二个按下的点进行操作,但是slot2并不对应第二个按下的点。

  2. ID只是用来标识每个触摸点的唯一标志符,并不能告诉我们这些触摸点的位置、状态或其他属性。为了实现多点触摸识别功能,我们需要使用ID和其他信息(如坐标、状态、时间戳等)来跟踪和识别每个触摸点,并进行相应的操作。

6.什么情况下需要使用 input_mt_report_pointer_emulation() 函数禁止指针模拟器?

  1. 硬件设备跟踪到的触摸点数量多于正在上报的触摸点数量,启用指针模拟器可能导致触摸点数量不匹配、误判触摸点位置等问题。

  2. 应用程序需要精确地跟踪多个触摸点的位置和状态,禁用指针模拟器可以确保触摸点信息能够准确地传递到应用程序中,而不受指针模拟器的影响。

  3. 一些应用程序需要使用指针模拟器来模拟单点触控,禁用指针模拟器可能会导致这些应用程序无法正常工作。

  4. 在特殊的应用场景下,例如绘图或游戏等需要高精度触摸控制的应用程序中,禁用指针模拟器可以提高触摸点的准确性和响应性。


三、多点触摸API函数

1、input_mt_init_slots 函数 

用于初始化 MT 的输入 slots,编写 MT 驱动的时候必须先调用此函数初始化 slots:

int input_mt_init_slots(  struct input_dev    *dev,   
                                          unsigned int      num_slots,   
                                          unsigned int      flags) 

dev:  MT 设备对应的 input_dev,因为 MT 设备隶属于 input_dev。 
num_slots:多点触控设备支持的最大触摸点数量。
flags:其他一些 flags 信息,可设置的 flags 如下所示: 

#define INPUT_MT_POINTER    0x0001  /* pointer device, e.g. trackpad */ 
#define INPUT_MT_DIRECT    0x0002  /* direct device, e.g. touchscreen */ 
#define INPUT_MT_DROP_UNUSED 0x0004  /* drop contacts not seen in frame */ 
#define INPUT_MT_TRACK    0x0008  /* use in-kernel tracking */ 
#define INPUT_MT_SEMI_MT    0x0010  /* semi-mt device, finger count handled manually */ 

可以采用‘|’运算来同时设置多个 flags 标识。 
返回值:0,成功;负值,失败。 

2、input_mt_slot 函数

此函数用于 Type B 类型,此函数用于产生 ABS_MT_SLOT 事件,告诉内核当前上报的是哪个触摸点的坐标数据:

void input_mt_slot(struct input_dev    *dev,   
                                 int          slot) 

dev:  MT 设备对应的 input_dev。 
slot:当前发送的是哪个 slot 的坐标信息,也就是哪个触摸点。 
返回值:无。 

3、input_mt_report_slot_state 函数 

此函数用于 Type B 类型,用于产生 ABS_MT_TRACKING_ID 和 ABS_MT_TOOL_TYPE事 件 , ABS_MT_TRACKING_ID 事 件 给 slot 关 联 一 个 ABS_MT_TRACKING_ID ,ABS_MT_TOOL_TYPE 事件指定触摸 型(是笔还是手指等):

void input_mt_report_slot_state(  struct input_dev    *dev, 
                                                      unsigned int      tool_type,   
                                                      bool        active) 

dev:  MT 设备对应的 input_dev。 
tool_type:触摸类型,可以选择 MT_TOOL_FINGER(手指)、MT_TOOL_PEN(笔)或
MT_TOOL_PALM(手掌),对于多点电容触摸屏来说一般都是手指。 
active:true,连续触摸,input 子系统内核会自动分配一个 ABS_MT_TRACKING_ID 给slot。
false,触摸点抬起,表示某个触摸点无效了,input 子系统内核会分配一个-1 给 slot,表示触摸点溢出。 
返回值:无。

4、input_report_abs 函数 

Type A 和 Type B 类型都使用此函数上报触摸点坐标信息,通过 ABS_MT_POSITION_X 和ABS_MT_POSITION_Y 事件实现 X 和 Y 轴坐标信息上报。

void input_report_abs( struct input_dev    *dev,   
                                     unsigned int      code,   
                                     int          value) 

dev:  MT 设备对应的 input_dev。 
code:要上报的是什么数据,可以设置为 ABS_MT_POSITION_X 或ABS_MT_POSITION_Y,也就是 X 轴或者 Y 轴坐标数据。 
value:具体的 X 轴或 Y 轴坐标数据值。   
返回值:无。 

5、input_mt_report_pointer_emulation 函数 

如果追踪到的触摸点数量多于当前上报的数量,驱动程序使用 BTN_TOOL_TAP 事件来通知用户空间当前追踪到的触摸点总数量,然后调用 input_mt_report_pointer_emulation 函数将 use_count 参数设置为 false。否则的话将 use_count 参数设置为 true,表示当前的触摸点数量(此函数会获取到具体的触摸点数量,不需要用户给出):

void input_mt_report_pointer_emulation(struct input_dev   *dev,   
                                                                 bool        use_count) 
dev:  MT 设备对应的 input_dev。 
use_count:true,有效的触摸点数量;false,追踪到的触摸点数量多于当前上报的数量。   
返回值:无。 

四、触摸驱动分析

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

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

相关文章

[实训] 实验1-SPI数据传输基础实验(下)

目录 五、实验测试数据表格记录 六、实验数据分析及处理 七、实验结论与感悟 五、实验测试数据表格记录 实验现象数码管显示见第四节图4.4&#xff0c;示波器测量结果见下列图片。 图5.1 RST、MOSI/MISO波形测量结果 图5.2 SCLK、MOSI/MISO波形测量结果 仅调整示波器波…

C生万物 | 剖析函数指针经典应用 —— 回调函数

不懂函数指针的老铁可以先看看这篇文章【指针函数与函数指针】&#xff0c;上车&#xff0c;准备出发&#x1f697; 文章目录 一、回调函数的概念二、为什么要使用回调函数&#xff1f;三、回调函数使用场景场景一&#xff1a;模拟计算器的加减乘除场景二&#xff1a;模拟qsort…

MySQL集群方案总结与方案原理

前言 在给自己做着玩的一个项目准备数据库集群&#xff0c;顺带自己大致系统复习并记录一下。 单节点mysql存在的常见问题 当数据量和并发量上去后&#xff0c;单节点数据库无法满足大并发时性能上的要求。单节点的MySQL无法满足高可用&#xff0c;数据库宕机或者意外中断等故障…

数据结构学习分享之双向链表详解

数据结构第四课 1.前言2. 结构分析3. 双链表的实现3.1 初始化结构3.2 初始化函数3.3 尾插函数3.4 尾删函数3.5 头插函数3.6 头删函数3.7 销毁链表3.8 其他函数 4. 缓存利用率5. 总结 1.前言 &#x1f493;博主CSDN:杭电码农-NEO&#x1f493;&#x1f389;&#x1f389;&#x…

Python(一) 基础二(语句、文件读写)

1.语句 1.1.if…elif…else 类似于java的if…else if…else语句 1.1.1.判断条件 比较运算符: 、>、<、<、>、!、is、is not、in、not in 1.1.2.和is的区别 list_1 [aaa, bbb] list_2 [aaa, bbb] print(list_1 list_2) #结果:True print(list_1 is list_2)…

async await

async await async await 都是修饰符&#xff0c;修饰函数的。 async/await一定是成对出现的。比如用async也没有什么太大意义。只要函数体中出现了await&#xff0c;则当前函数必须用async来修饰。 用async修饰的函数&#xff0c;相当于用promise包裹起来。其实相当于把同步修…

基于jeecgboot的OA日程安排开发(一)

日程安排也是OA里的一项重要功能&#xff0c;所以基于jeecgboot开发这个日程安排。 日程安排主要涉及以下几个方面&#xff1a; 1、数据库方面&#xff0c;主要是分日历与日程 日历可以分个人日历与工作日历&#xff0c;一般情况下&#xff0c;个人日历只给自己查看&#xff0…

2023-05-02 动态规划简介

动态规划简介 1 动态规划的基本概念 阶段、状态、决策、策略、状态转移方程 1) 阶段和阶段变量 将问题的全过程恰当地分成若干个相互联系的阶段闫氏DP分析法&#xff1a;对应f[i][j]的ij遍历时形成的所有f[i][j]阶段的划分一般根据时间和空间的自然特征去划分阶段的划分便于把…

Nginx原理解析

master和worker 当linux启动的时候&#xff0c;会有两个和nginx相关的进程&#xff0c;一个是master,一个是worker。 master如何工作 当客户端发送请求到nginx之后&#xff0c;master会接收到这个请求&#xff0c;然后通知所有的worker进程&#xff0c;此时&#xff0c;work…

【STL十六】函数对象:包装器(std::function)——绑定器(std::bind)——函数适配器

【STL十六】函数对象&#xff1a;包装器(std::function&#xff09;——绑定器&#xff08;std::bind&#xff09;——函数适配器 一、包装器(std::function&#xff09;1、简介2、头文件3、构造函数4、demo5、异常 二、绑定器&#xff08;std::bind&#xff09;1、简介2、头文…

Nessus漏洞扫描以及OpenSSH漏洞修复验证

主机IP地址资源kali192.168.200.1285GB内存/4CPUCentOS7.5192.168.200.1292GB内存/2CPU https://www.tenable.com/downloads/nessus?loginAttemptedtrue curl --request GET \--url https://www.tenable.com/downloads/api/v2/pages/nessus/files/Nessus-10.5.1-ubuntu1404_am…

云原生Istio案例实战

目录 1 Istio监控功能1.1 prometheus和grafana1.2 访问prometheus1.3 访问grafana 2 项目案例&#xff1a;bookinfo2.1 理解什么是bookinfo2.2 sidecar自动注入到微服务2.3 启动bookinfo2.4 通过ingress方式访问2.5 通过istio的ingressgateway访问2.5.1 确定 Ingress 的 IP 和端…

计算机视觉--图像拼接

图像拼接 单应性变换仿射变换图像扭曲实现图像嵌入&#xff08;图中图&#xff09; RANSAC算法算法介绍图片收集无RANSAC优化和有RANSAC优化的代码实现差别 总结 单应性变换 单应性变换是指一个平面上的点通过一个矩阵变换映射到另一个平面上的点&#xff0c;这个变换矩阵是一…

java聊天室的设计与实现代码

聊天室是一个简单的通信应用&#xff0c;可以帮助您与客户和朋友保持联系&#xff0c;并且可以让您更轻松地与其他员工联系。然而&#xff0c;您将不得不确保每个人都知道他们正在做什么。 一旦聊天室开始&#xff0c;它就会变得非常复杂&#xff0c;因为有许多用户可能会同时登…

【三十天精通Vue 3】第二十五天 Vue3 与 Axios 后端数据交互

✅创作者&#xff1a;陈书予 &#x1f389;个人主页&#xff1a;陈书予的个人主页 &#x1f341;陈书予的个人社区&#xff0c;欢迎你的加入: 陈书予的社区 &#x1f31f;专栏地址: 三十天精通 Vue 3 文章目录 引言一、Vue3 与 Axios 概述二、Axios 安装与基本使用2.1 安装 Ax…

NECCS|全国大学生英语竞赛C类|词汇和语法|语法题|时态|22:30~11:44

15题 10min 10:20&#xff5e;10:25 test2 10:25&#xff5e;10:47 test1订正 10:44&#xff5e;11:47 理论学习 涉及的语法点主要包括&#xff1a; 动词的时态和语态 非谓语动词 虚拟语气 主谓一致 倒装句 强调句 比较级 名词性从句 定语…

【SQL篇】面试篇之子查询

1303 求团队人数 # 写法1 # Write your MySQL query statement below select employee_id, count(*) over(partition by team_id) as team_size from Employee# 写法2 # Write your MySQL query statement below select employee_id, team_size from Employee e join (select t…

优雅编程,从空格、空行、缩进、注释开始

很多初学者的代码其实都不够“漂亮”&#xff0c;那是因为没有养成好的编码习惯。本篇博客以C语言为例&#xff0c;总结一些好习惯。其实&#xff0c;很多习惯都是肌肉记忆&#xff0c;举个例子&#xff1a;请你写一个程序&#xff0c;输入2个整数并输出它们的和。有些朋友可能…

springboot+vue前后端分离项目打包成jar包及运行

将 Spring Boot 和 Vue.js 项目打包成 jar 包需要按照以下步骤操作&#xff1a; 在项目的根目录中&#xff0c;使用命令行进入 Vue.js 项目的根目录&#xff0c;然后运行以下命令&#xff1a; npm run build这个命令将会构建 Vue.js 项目&#xff0c;并在项目的 dist 目录中生…

Rust-Rocket框架笔记

Rust-Rocket框架笔记 Rocket-Learn-docRocket Addr视频地址 What is RocketQuickStart下载Rocket-Rust运行Rust-Rocket-Hello-错误-端口占用解决查看端口占用情况添加Rocket.toml配置文件更改Rocket默认启动端口启动成功 GetStart-Hello world创建项目cargoIDEA 添加依赖添加Ro…