相机标定张正友、opencv和halcon对比(1)

本文将从基本标定开始,结合实际工作经验,分析张正友、opencv和halcon三者相机标定的深层原理与不同之处,内容比较多,如果出现错误请指正。

相机光学模型

我们使用的镜头都是由多组镜片组成,它实际上是一种厚透镜模型,但是目前所有的相机标定是基于针孔模型来进行标定的,因此在学习标定之前,首先我们要对相机进行建模,这样能从整体上把握坐标系之间的变换关系。当然鱼眼镜头和沙姆镜头需要基于针孔模型进行二次建模,这里不细说了,有想交流的可以私信我。我们的目标就是把厚透镜模型变为针孔模型进行后续的处理。
厚透镜镜片组可能如下(halcon):
在这里插入图片描述

针孔模型

针孔模型如下图所示,小孔处为投影中心,y为物体,y’为倒立的像,a为物距,c为像距,注意这里像距并不等同于镜片的焦距,但我们一般叫焦距
在这里插入图片描述
针孔模型满足下面的相似三角形关系:
在这里插入图片描述
在使用中,一般我们会在投影中心o前方构造虚拟像平面,把像平面和物平面放到同一侧,这样可以使图像坐标系和相机坐标系递增方向对齐:
在这里插入图片描述
在这里插入图片描述

厚透镜模型

可以将镜头看作是两个球心位于同一直线的折射球面组成,两个球面之间为一种均匀介质,镜头两侧为另一种介质,镜头具有一定厚度,如下图所示:
在这里插入图片描述
注意光是从左往右传播的,镜头前面的距离为负,向上为正,向下为负,比如y为正,y’为负,f为负,f’为正。
参数解释如下:
y 物高
y’ 像高
F 物方焦点,像方平行光线过镜头后汇聚在该点
F’ 像方焦点,物方平行光线过镜头后汇聚在该点
f 物方焦距
f’ 像方焦距,两侧介质一样的话,f等于-f’
P 物方主平面,为过像方水平光线与过F的对应光线的交点
P’ 像方主平面,为过物方水平光线与过F’的对应光线的交点
a 物距,为物到物方主平面距离
a’ 像距
N 为物方主平面与光轴交点
N’ 为像方主平面与光轴交点,入射和出射光线角度相同

这里因为有两个主平面,导致直接基于厚透镜是无法建模的。

厚透镜成像法则:

  1. 镜头前平行于光轴的光线,经过F’;
  2. 经过F的光线,通过镜头后和光轴水平;
  3. 过N点的光线,也会过N’点,并且镜头前和镜头后与光轴的夹角不变。

两个关键的公式:
在这里插入图片描述
在这里插入图片描述
这两个公式非常关键,在做相机镜头选型时一定会用到这个公式去推断视野和成像芯片尺寸对镜头型号的影响。

可推导出如下变化:
 物距变小,像距变大,物距变大,像距变小。也就是说,相机固定不动,焦距不变的情况下,聚焦过程其实为改变像距的过程;
 物距无穷远,所有入射光线为平行光,此时a’=f’,像面位于像方焦点上。
 【放大镜虚像】当物放到F点位置,像面会在无穷远处,如果物放到F以内,光线在成像端发散,a’的正负号会发生变化,像变为物体同一侧的虚像:
在这里插入图片描述

厚透镜转针孔模型(halcon)

那么厚透镜到底怎么转为针孔模型呢?这里基于现有资料,这里以halcon为例进行说明。在说明之前我们必须先了解镜头中的两个概念:出瞳和入瞳。

孔径光阑和出瞳入瞳

镜头中都设计有一个可调节大小的环,来控制入射光线的多少。如下图中的D面即为环,同时镜筒本身也会限制到达像平面的光线总量,这些因素统称为光阑,其中起最大程度限制作用的被称为孔径光阑。需要注意的是,并不是最小尺寸的光阑为孔径光阑,因为光在穿过镜筒时,光阑前后的镜片可能放大或缩小光阑的实际尺寸。
在这里插入图片描述
基于孔径光阑,定义了两个重要的虚拟光阑:入瞳(ENP)和出瞳(EXP)。入瞳决定镜头入口可接收的光线面积,是孔径光阑被其前面的光学系统在物方所成的像,通常为虚像。出瞳是孔径光阑被后面的光学系统在像方所成的像,通常为虚像。
主入射光线经过入瞳ENP中心Q,在主平面交点的反向延长线经过出瞳EXP中心Q’,如下图,这里入射角w和出射角w’也是不一样的:
在这里插入图片描述

模型转换

针孔模型中只有一个投影中心,但厚透镜模型中有两个,分别是入瞳和出瞳,同时两个角度w和w’也是不一样的,为了两个w角度一致,且物方w角度不变(因为它取决于物方被测物体的尺寸),我们只能将出瞳移动到入瞳位置(Q’移动到Q上),此时w和w’角度一致。同时我们还需要将像平面虚拟的移动到与入瞳中心距离为c的位置,来保证像平面大小不变。c为主距,也就是halcon相机标定时输入的焦距f,注意这里的主距和f’不相同。
在这里插入图片描述
出瞳移动到入瞳,像平面移动到虚拟像平面的示意图:
在这里插入图片描述
此时,厚透镜模型变转换为了由虚拟像平面、投影中心和物平面构成的针孔模型,影响最关键的参数其实是主距c。
移动后满足下面的等式:
在这里插入图片描述

总结

说了这么多到底有什么用呢,对于普通镜头,我们可以了解到标定出的焦距其实是主距。而对于其他镜头,我认为关键是初始值的选取,尤其是沙姆标定中,我们可以基于镜头参数,推导出理论初始值进行标定,然后控制标定的结果在理想的范围内是非常关键的。
注意这里用的是halcon中的模型转换,opencv中的并没有说明它的模型怎么定义的,但我们用halcon的模型去套用应该也是没问题的。

坐标系转换

接下来是喜闻乐见的坐标系转换了,相信大家都从其他地方也看过很多,这里总结一下容易混淆及懵逼的几个点。
首先列一下坐标系图:
在这里插入图片描述

在这里包含了下面几个坐标系:

  • 图像坐标系 O 0 u v O_{0}uv O0uv,就是我们在屏幕看到的图像,它有一个中心点一般在左上角(0,0),单位是像素;
  • 成像坐标系 O 1 u v O_{1}uv O1uv,在CMOS平面内,它的中心点是光轴和CMOS平面交点,是通过像元长度计算出单位为mm或m的坐标系;
  • 相机坐标系 O 1 X c Y c Z c O_{1}X_{c}Y_{c}Z_{c} O1XcYcZc,它的中心即是投影中心,Zc和光轴重合,Xc和Yc和成像坐标系x轴y轴平行,单位也是mm或m;
  • 世界坐标系 O w X w Y w Z w O_{w}X_{w}Y_{w}Z_{w} OwXwYwZw,它的中心即某个标定板确定的中心,单位也是mm或m。
  • 针孔模型中,要求物点、投影中心和像点必须在同一条直线上。

下面开始公式推导,首先假设成像坐标系原点 O 1 O_{1} O1在图像坐标系中的坐标为 ( u 0 , v 0 ) (u0,v0) (u0,v0),像元物理尺寸为 S x , S y S_{x},S_{y} Sx,Sy,镜头焦距(其实是主距)为 f f f,在图像坐标系中取一点 ( u , v ) (u,v) (u,v)

  • 图像坐标系–>成像坐标系
    图像坐标系点 u , v {u,v} u,v,成像坐标系点 ( x , y ) (x,y) (x,y)
    [ u v 1 ] = [ 1 S x 0 u 0 0 1 S y v 0 0 0 1 ] [ x y 1 ] \begin{bmatrix}u \\ v \\ 1 \end{bmatrix} = \begin{bmatrix} \frac{1}{S_{x}} & 0 & u_{0}\\ 0 & \frac{1}{S_{y}} & v_{0}\\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix}x \\ y \\ 1 \end{bmatrix} uv1 = Sx1000Sy10u0v01 xy1 (1)

  • 成像坐标系 – > 相机坐标系【容易理解错】
    注意,这里的变换是透视投影变换,针对的是两个实际点转到相机坐标系中的变换:

一个是成像坐标系中,CMOS表面的物理点 ,转到相机坐标系中即 ( x , y , f ) (x,y,f) (x,y,f)
一个是世界坐标系中,物体表面对应的物理点,在相机坐标系中即 ( X c Y c Z c ) (X_{c}Y_{c}Z_{c}) (XcYcZc)
目标是将前者转到后者,因为成像坐标系中心和相机坐标系中都在光轴上,可以将该投影变换看成相似三角形的转换:

在这里插入图片描述
转换公式如下:
( Z c [ x y 1 ] = [ f 0 0 0 0 f 0 0 0 0 0 1 ] [ X c Y c Z c 1 ] ) ( Z_{c}\begin{bmatrix}x \\ y \\ 1 \end{bmatrix} = \begin{bmatrix} f & 0 & 0 & 0\\ 0 & f & 0 & 0\\ 0 & 0 & 0 & 1 \end{bmatrix} \begin{bmatrix}X_{c} \\ Y_{c} \\ Z_{c} \\ 1 \end{bmatrix} ) (Zc xy1 = f000f0000001 XcYcZc1 ) (2)
这里的 Z c Z_{c} Zc我们一般称为尺度因子,反正最后会被约掉。

  • 相机坐标系 --> 世界坐标系
    这个变换是说世界坐标中的物理点,从相机坐标转到世界坐标系中,是一个旋转平移的变换:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    综上,整体的变换关系如下:
    在这里插入图片描述
    在这里插入图片描述

这里 M 1 M_{1} M1为内参矩阵, M 2 M_{2} M2为平移旋转矩阵,即我们说的外参, Z c Z_{c} Zc可以计算中自动消除。
而这,正是张正友算法的求解核心原理:利用每组的像素坐标和世界坐标,求出射影变换矩阵 M M M,再分别求出内参和外参的初始值,进行非线性迭代优化。
. [ u v 1 ] = M [ X w Y w Z w 1 ] . .\begin{bmatrix}u \\ v \\ 1 \end{bmatrix} = M \begin{bmatrix}X_{w} \\ Y_{w} \\ Z_{w} \\ 1 \end{bmatrix} . . uv1 =M XwYwZw1 .

镜头畸变对比

镜头畸变包含了径向畸变和切向畸变,径向畸变主要由透镜产生,它的效应主要有两种:枕形和桶形,如图所示。在 CMOS 中心(光学中心)的畸变为 0,随着向边 缘移动,畸变越来越严重。切向畸变来自于透镜安装的整个过程,因为安装时很难保证透镜和成像平面平行。
在这里插入图片描述
具体的公式halcon采用的和张正友是一样的:
在这里插入图片描述
而Opencv最新版本的公式如下:
在这里插入图片描述
可以看到,右边径向畸变系数k,halcon和OpenCV是不一样的,但形式一致,切向是相同的,并且OpenCV还多了 ( s 1 s 2 s 3 s 4 ) (s_{1}s_{2}s_{3}s_{4}) (s1s2s3s4)四个参数。
经过对比验证,最关键的还不是这个,而是左右描述的畸变矫正不一致! 经过查询相关资料,

halcon中的公式等号右边是畸变点,等号左边是未畸变点,而张正友和OpenCV的正好相反。

这个不同点最终的影响不得而知,有谁知道的可以评论一下。
这个不同会导致一个问题,就是解畸变halcon和Opencv的过程是不一样的,halcon解畸变会更加简单,因为等号右边就是畸变的点,可以直接代入求解,但Opencv不是,它解畸变已知的是左边,求的是右边无畸变点,这个二元多次方程到底该怎么解呢?Opencv给出了一个解法。

Opencv解畸变

在 OpenCV 中,解畸变的函数主要包括 cv::undistort 和 cv::undistortPoints,我们这里看一下cv::undistortPoints函数,它里面最关键的是下面这段代码,两个for循环。

//遍历每个点
for( int i = 0; i < n; i++ )
    {
        double x, y, x0 = 0, y0 = 0, u, v;
        u = x; v = y;
        x = (x - cx)*ifx;
        y = (y - cy)*ify;

        if( _distCoeffs ) {
            // compensate tilt distortion
            cv::Vec3d vecUntilt = invMatTilt * cv::Vec3d(x, y, 1);
            double invProj = vecUntilt(2) ? 1./vecUntilt(2) : 1;
            x0 = x = invProj * vecUntilt(0);
            y0 = y = invProj * vecUntilt(1);

            double error = std::numeric_limits<double>::max();
            // compensate distortion iteratively

			//核心:迭代计算畸变点
            for( int j = 0; ; j++ )
            {
                if ((criteria.type & cv::TermCriteria::COUNT) && j >= criteria.maxCount)
                    break;
                if ((criteria.type & cv::TermCriteria::EPS) && error < criteria.epsilon)
                    break;
                double r2 = x*x + y*y;
                //下面这个是公式中的倒数
                double icdist = (1 + ((k[7]*r2 + k[6])*r2 + k[5])*r2)/(1 + ((k[4]*r2 + k[1])*r2 + k[0])*r2);
                if (icdist < 0)  // test: undistortPoints.regression_14583
                {
                    x = (u - cx)*ifx;
                    y = (v - cy)*ify;
                    break;
                }
                double deltaX = 2*k[2]*x*y + k[3]*(r2 + 2*x*x)+ k[8]*r2+k[9]*r2*r2;
                double deltaY = k[2]*(r2 + 2*y*y) + 2*k[3]*x*y+ k[10]*r2+k[11]*r2*r2;
                x = (x0 - deltaX)*icdist;
                y = (y0 - deltaY)*icdist;

				//解出来后再反向带回去,比较一下误差大小
                if(criteria.type & cv::TermCriteria::EPS)
                {
                    double r4, r6, a1, a2, a3, cdist, icdist2;
                    double xd, yd, xd0, yd0;
                    cv::Vec3d vecTilt;

                    r2 = x*x + y*y;
                    r4 = r2*r2;
                    r6 = r4*r2;
                    a1 = 2*x*y;
                    a2 = r2 + 2*x*x;
                    a3 = r2 + 2*y*y;
                    cdist = 1 + k[0]*r2 + k[1]*r4 + k[4]*r6;
                    icdist2 = 1./(1 + k[5]*r2 + k[6]*r4 + k[7]*r6);
                    xd0 = x*cdist*icdist2 + k[2]*a1 + k[3]*a2 + k[8]*r2+k[9]*r4;
                    yd0 = y*cdist*icdist2 + k[2]*a3 + k[3]*a1 + k[10]*r2+k[11]*r4;

                    vecTilt = matTilt*cv::Vec3d(xd0, yd0, 1);
                    invProj = vecTilt(2) ? 1./vecTilt(2) : 1;
                    xd = invProj * vecTilt(0);
                    yd = invProj * vecTilt(1);

                    double x_proj = xd*fx + cx;
                    double y_proj = yd*fy + cy;

                    error = sqrt( pow(x_proj - u, 2) + pow(y_proj - v, 2) );
                }
            }
        }

关于这个公式,右边是无畸变的,现在已知的是左侧带畸变的 x ′ ′ x^{''} x′′,右边无畸变的 x ′ x^{'} x看上去是不好求的。
在这里插入图片描述
opencv使用的是不动点迭代求解非线性方程的根(参考https://blog.csdn.net/weixin_43956164/article/details/124197614),先在最里面的for中,将已知的带畸变的强行代入公式右边,注意设第一个 x ′ x^{'} x是未知的,这样就变成了:
( x ′ ′ − 2 p 1 x ′ ′ y ′ ′ − p 2 ( r 2 + 2 x ′ 2 ) − s 1 r 2 − s 2 r 4 1 + k 1 r 2 + . . . 1 + k 4 r 2 + . . . = x ′ ) (\frac{x^{''} - 2p_{1}x^{''}y^{''}-p_{2}(r^{2}+2x^{'2}) - s_{1}r^{2} - s_{2}r^{4}}{\frac{1+k_{1}r^{2}+...}{1+k_{4}r^{2}+...}}=x^{'} ) (1+k4r2+...1+k1r2+...x′′2p1x′′y′′p2(r2+2x2)s1r2s2r4=x)
求出来的结果,再按 x ′ x^{'} x y ′ y^{'} y代入公式右侧,重新得到畸变的 x ′ ′ x^{''} x′′ y ′ ′ y^{''} y′′,然后和输入的已知进行误差求解,满足误差范围则停止。

初始值设定对比

初始值的设定是很关键的,尤其在复杂的相机模型中比如沙姆模型。这里列一下opencv和张正友标定在初始值设置时的不同:

  • 张正友
    整个过程参考链接:https://zhuanlan.zhihu.com/p/94244568?ivk_sa=1024320u
    核心就是下面三个步骤:

1)、求解内参矩阵与外参矩阵的积;
2)、求解内参矩阵;
3)、求解外参矩阵;
4)、标定畸变系数。

  • opencv
    opencv可以通过传入标记CALIB_USE_INTRINSIC_GUESS来手动控制内参和畸变的初始参数,如果不设置该标记,那么opencv会通过cvInitIntrinsicParams2D计算内参中的焦距(其中的中心位置在该函数中强行设置为了图像中心!),然后根据内参调用cvFindExtrinsicCameraParams2来计算外参,这里全局一个内参矩阵,每个图像对应一个外参,具体的方法参考的张正友但又有不同。可以参考下面两个链接,讲的很详细:
    https://blog.csdn.net/weixin_43956164/article/details/127408933
    https://blog.csdn.net/weixin_43956164/article/details/126771627

  • 总结
    张正友内参是计算得出的,opencv可以传入初始内参,也可以进行估算,两个不同点在于:
    a.opencv把中心点强行设为了图像坐标系中心,而zhang是放到内参中统一估算的;
    b.opencv由于强行让内参的中心点设置为了已知量,所以化简的出了一个ax=b的矩阵,动用cvSolve去解得方程,而zhang更通用,中心点也是求出的,得出一个ax=0的矩阵方程,可以动用svd分解a矩阵,得到UWV,则V矩阵的最后一列即为ax=0的解。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

易基因:人精子H3K4me3 ChIP-seq和DNA甲基化WGBS揭示与生育和发育相关重叠区域

大家好&#xff0c;这里是专注表观组学十余年&#xff0c;领跑多组学科研服务的易基因。 目前&#xff0c;六分之一的夫妇患有不孕不育&#xff0c;其中多达一半的病例由男性因素引起&#xff0c;在过去的40年中&#xff0c;精子数量下降了50%。尽管导致精子质量和数量下降的因…

Javase | Java常用类 (不断补充中...)

目录: 1.Object类2.String类3.StringBuffer类4.Math类5.Random类6.包装类(不断补充中...) 1.Object类 Object类是Java语言中的所有类的超类&#xff0c;即所有类的根。它中描述的所有方法&#xff0c;所有类都可以使用。 equals( ) : 指示其他某个对象与此对象“是否相等” (比…

【C/C++笔试练习】this指针的概念、初始化列表、const对象调用、构造和析构函数、继承和组合、重载和多态、虚函数的定义、计算日期到天数转换、幸运的袋子

文章目录 C/C笔试练习选择部分&#xff08;1&#xff09;this指针的概念&#xff08;2&#xff09;初始化列表&#xff08;3&#xff09;const对象调用&#xff08;4&#xff09;构造和析构函数&#xff08;5&#xff09;继承和组合&#xff08;6&#xff09;重载和多态&#x…

力扣 --- 三数之和

目录 题目描述&#xff1a; 思路描述&#xff1a; 代码&#xff1a; 提交结果&#xff1a; 官方代码&#xff1a; 官方提交结果&#xff1a; 题目描述&#xff1a; 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k…

implementation和api的区别是什么

前言&#xff1a; 平时在做开发的时候&#xff0c;各种依赖三方库。一般就是在build.gradle中添加如下代码&#xff1a; dependencies {implementation com.google.android.material:material:1.9.0 } 这里随便举个例子。 今天在开发的时候&#xff0c;遇到如下错误&#xf…

day32_Git

今日内容 零、 复习昨日 零、 复习昨日 一、引言 在单人开发过程中&#xff0c;需要进行版本管理&#xff0c;以利于开发进度的控制。 在多人开发过程中&#xff0c;不仅需要版本管理&#xff0c;还需要进行多人协同控制。 版本控制(VS) SVN GIT 二、介绍 Git是一个开源的…

vue3+vite搭建cesium项目

1.创建项目 cnpm create vite 2.安装依赖 npm i cesium vite-plugin-cesium vite -D 3.在vite.config.js里进行配置 import { defineConfig } from vite import vue from vitejs/plugin-vue import cesium from vite-plugin-cesium; export default defineConfig({plugins…

vue项目运行时,报错:ValidationError: webpack Dev Server Invalid Options

在运行vue项目中&#xff0c;遇到报错&#xff1a;ValidationError: webpack Dev Server Invalid Options&#xff0c;如下图截图&#xff1a; 主要由于vue.config.js配置文件错误导致的&#xff0c;具体定位到proxy配置代理不能为空&#xff0c;导致运行项目报错&#xff0c;需…

Apache Flink(二):数据架构演变

&#x1f3e1; 个人主页&#xff1a;IT贫道_大数据OLAP体系技术栈,Apache Doris,Clickhouse 技术-CSDN博客 &#x1f6a9; 私聊博主&#xff1a;加入大数据技术讨论群聊&#xff0c;获取更多大数据资料。 &#x1f514; 博主个人B栈地址&#xff1a;豹哥教你大数据的个人空间-豹…

CSS:calc() 函数 / 动态计算长度值 / 不同场景使用

一、理解 css calc() 函数 CSS calc() 函数是一个用于计算 CSS 属性值的函数。它可以在 CSS 属性值中使用数学表达式&#xff0c;从而实现动态计算属性值的效果。calc() 函数可以使用加减乘除四种基本数学运算符来计算属性值&#xff0c;还可以使用括号来改变优先级。 二、ca…

堆在排序中的应用

堆排序 1、堆排序原理 堆排序是利用到了堆这种数据结构&#xff0c;我们首先回顾一下二叉堆的特性&#xff1a; 最大堆的堆顶是整个堆中的最大元素。最小堆的堆顶是整个堆中的最小元素。 以最大堆为例&#xff0c;如果删除一个最大堆的堆顶&#xff08;并不是完全删除&…

【MATLAB】RLMD分解+FFT+HHT组合算法

有意向获取代码&#xff0c;请转文末观看代码获取方式~也可转原文链接获取~ 1 基本定义 RLMD分解FFTHHT组合算法是一种强大的分析方法&#xff0c;结合了局部均值分解&#xff08;LMD&#xff09;、快速傅里叶变换&#xff08;FFT&#xff09;和希尔伯特-黄变换&#xff08;H…

Wireshark之Intro, HTTP, DNS

源码地址&#x1f447; moranzcw/Computer-Networking-A-Top-Down-Approach-NOTES: 《计算机网络&#xff0d;自顶向下方法(原书第6版)》编程作业&#xff0c;Wireshark实验文档的翻译和解答。 (github.com) 目录 &#x1f33c;Introduce &#x1f3a7;前置 &#x1f3a7;过…

基于YOLOv8深度学习的PCB板缺陷检测系统【python源码+Pyqt5界面+数据集+训练代码】目标检测

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能AI、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推荐--…

基于three.js生成动态波浪背景效果

文章目录 前言一、安装three二、新建waves.js文件三、引入waves.js文件比查看效果如有启发&#xff0c;可点赞收藏哟~ 前言 基于three.js生成动态波浪背景效果 一、安装three npm i three -S二、新建waves.js文件 注意geometry.setAttribute和geometry.addAttribute和在不同…

【腾讯地图】【微信小程序】地图选点

【相关文章】 【腾讯地图】【微信小程序】地图选点 【腾讯地图】【微信小程序】路线规划 【腾讯地图】【微信小程序】城市记录&#xff08;基于地图选点入门版&#xff09; 【效果展示】 【官方文档】 微信小程序插件-地图选点插件 【完善流程】 当前操作和官方文档操作有部…

Attacking Fake News Detectors via Manipulating News Social Engagement(2023 WWW)

Attacking Fake News Detectors via Manipulating News Social Engagement----《通过操纵新闻社交互动来攻击假新闻检测器》 摘要 在年轻一代中&#xff0c;获取新闻的主要来源之一是社交媒体。随着新闻在各种社交媒体平台上日益流行&#xff0c;虚假信息和毫无根据的言论的传…

【端到端可微2】链式法则,论文:Introduction to Gradient Descent and Backpropagation Algorithm

论文&#xff1a;Introduction to Gradient Descent and Backpropagation Algorithm 文章目录 0 前言1 链式法则定义作用 2 单神经元的正向传播forward propagation定义z 激活函数 3 损失函数定义 4 损失函数对权重张量的偏导数定义z对w求偏导l对z求偏导 5 多个神经元的正向传播…

企业软件的分类|app小程序网站定制开发

企业软件的分类|app小程序网站定制开发 企业软件是指为满足企业管理和运营需求而设计和开发的一类软件&#xff0c;它通常用于支持企业的各项业务活动和流程。根据其功能和应用领域的不同&#xff0c;可以将企业软件分为以下几类。 1. 企业资源计划&#xff08;ERP&#xff09…

Android性能优化 - 从SharedPreferences到DataStore

前言 对于android开发者们来说&#xff0c;SharedPreferences已经是一个老生常谈的话题了&#xff0c;之所以还在性能优化这个专栏中再次提到&#xff0c;是因为在实际项目中还是会有很多使用到的地方&#xff0c;同时它也有足够的“坑”&#xff0c;比如常见的主进程阻塞&…