OpenCV:norm-范数求解函数
1、OpenCV中矩阵表示形式:
CV_8UC1:一个8位无符号整型单通道矩阵,
CV_32FC2:一个32位浮点型双通道矩阵,
CV_8UC1 CV_8SC1 CV_16UC1 CV_16SC1
CV_8UC2 CV_8SC2 CV_16UC2 CV_16SC2
CV_8UC3 CV_8SC3 CV_16UC3 CV_16SC3
CV_8UC4 CV_8SC4 CV_16UC4 CV_16SC4
CV_32SC1 CV_32FC1 CV_64FC1
CV_32SC2 CV_32FC2 CV_64FC2
CV_32SC3 CV_32FC3 CV_64FC3
CV_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)T
1-范数:║x║1=│x1│+│x2│+…+│xn│//向量中的绝对值求和
2-范数:║x║2=(│x1│2+│x2│2+…+│xn│2)^1/2 //欧几里得距离
∞-范数:║x║∞=max(│x1│,│x2│, … ,│xn│) //向量中的max

4、OpenCV: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<image_count; i++)
{
vector<Point3f> 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<Point2f> 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<Vec2f>(0, j) = Vec2f(image_points2[j].x, image_points2[j].y); //两个通道赋值
tempImagePointMat.at<Vec2f>(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<Vec2f>(0, i) = Vec2f(6, 5);
cur_point1.at<Vec2f>(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
