距离的定义是一个宽泛的概念,只要满足非负、自反、三角不等式就可以称之为距离。范数是一种强化了的距离概念,它在定义上比距离多了一条数乘的运算法则。有时候为了便于理解,我们可以把范数当作距离来理解。在数学上,范数包括向量范数和矩阵范数,向量范数表征向量空间中向量的大小,矩阵范数表征矩阵引起变化的大小。一种非严密的解释就是,对应向量范数,向量空间中的向量都是有大小的,这个大小如何度量,就是用范数来度量的,不同的范数都可以来度量这个大小,就好比米和尺都可以来度量远近一样;对于矩阵范数,学过线性代数,我们知道,通过运算AX=B,可以将向量X变化为B,矩阵范数就是来度量这个变化大小的。本文主要介绍:OpenCV矩阵表示形式,范数定义;范数性质;OpenCV三种范数格式;应用实例;数学概念;
1OpenCV中矩阵表示形式:CV_8UC1:一个8位无符号整型单通道矩阵,CV_32FC2:一个32位浮点型双通道矩阵, CV_8UC1 CV_8SC1 CV_16UC1 CV_16SC1CV_8UC2 CV_8SC2 CV_16UC2 CV_16SC2CV_8UC3 CV_8SC3 CV_16UC3 CV_16SC3CV_8UC4 CV_8SC4 CV_16UC4 CV_16SC4 CV_32SC1 CV_32FC1 CV_64FC1CV_32SC2 CV_32FC2 CV_64FC2CV_32SC3 CV_32FC3 CV_64FC3CV_32SC4 CV_32FC4 CV_64FC4通道表示每个点能存放多少个数,类似于RGB彩色图中的每个像素点有三个值,即三通道。图像中的深度表示每个值由多少位来存储,是一个精度问题,一般图像是8bit(位)的,则深度是8。
2范数的定义║x║:设,满足①正定性:║x║≥0,║x║=0 if x=0②齐次性:║cx║=│c│║x║,③三角不等式:║x+y║≤║x║+║y║则称Cn中定义了向量范数,║x║为向量x的范数.
3范数的性质:向量范数是向量的一种具有特殊性质的实值函数。常用向量范数有,令x=( x1, x2, … ,xn)T1-范数:║x║1=│x1│+│x2│+…+│xn│//向量中的绝对值求和2-范数:║x║2=(│x1│2+│x2│2+…+│xn│2)^1/2 //欧几里得距离∞-范数:║x║∞=max(│x1│,│x2│, … ,│xn│) //向量中的max
4OpenCV:norm范数求解函数三种格式:①double norm(InputArray src1,int normType=NORM_L2,InputArray mask=noArray() )②double norm(InputArray src1,InputArray src2,int normType=NORM_L2,InputArray mask=noArray())③double norm(const SparseMat& src, int normType)
5应用实例:用于评估相机标定的内外参质量程序如下:cout << '每幅图像的标定误差:' << endl; for (int i = 0; i tempPointSet = object_Points[i]; /*object_Points是图像棋盘格角点世界坐标的容器,其是三通道的XYZ,其中Z通道为0。棋盘格以左上角为原点,方块大小是12mm和12mm*/ /*依据摄像机内外参数,对空间的三维点进行重投影计算;tempPointSet为12mm*12mm的棋盘格标定板角点世界坐标,image_points2是重投影后的图像像素角点坐标*/ projectPoints(tempPointSet,rotation_vectors[i],translation_vectors[i],intrinsic_matrix,distortion_coeffs,image_points2); /*图像亚像素角点坐标tempImagePoint */ /*image_points2和tempImagePoint进行误差计算,评估出其内外参的质量*/ vector tempImagePoint = corners_Seq[i]; //定义双通道的Mat矩阵,每个点表示两个数据,分别为棋盘格角点的x和y// Mat tempImagePointMat = Mat(1, tempImagePoint.size(), CV_32FC2); Mat image_points2Mat = Mat(1, image_points2.size(), CV_32FC2); for (int j = 0; j < tempImagePoint.size(); j++) { image_points2Mat.at(0, j) = Vec2f(image_points2[j].x, image_points2[j].y); //两个通道赋值 tempImagePointMat.at(0, j) = Vec2f(tempImagePoint[j].x, tempImagePoint[j].y); } err = norm(image_points2Mat, tempImagePointMat, NORM_L2);//2范数 total_err += err /= point_counts[i]; cout << '第' << i + 1 << '幅图像的平均误差:' << err << '像素' << endl; } cout << '总体平均误差:' << total_err / image_count << '像素' << endl; cout << '评价完成!' << endl; 【注】:OpenCV的norm函数是将两个通道分开计算(X1-X2)^2的值,然后统一求和,开根号;即2范数;
6数学概念(补充)例如:Mat common_point1 = Mat(1, 3, CV_32FC2); Mat cur_point1 = Mat(1, 3, CV_32FC2); for (size_t i = 0; i < 3; i++) { common_point1.at(0, i) = Vec2f(6, 5); cur_point1.at(0, i) = Vec2f(4,4); } err = norm(common_point1, cur_point1, NORM_L2); printf('err为 : %f个像素 \n', err); 结果为:sqrt((6-4)^2+(5-4)^2+(6-4)^2+(5-4)^2+(6-4)^2+(5-4)^2)=3.87