OpenCV Python 相机标定

【目标】

  • 摄像机引起的失真类型
  • 如何找到相机的内参和外参
  • 如何基于这些特性校正这些图像

【理论】

一些针孔相机会导致图像发生严重失真,主要有两种,一是径向畸变,一是切向畸变。

径向畸变使直线看起来弯曲。距离图像中心越远的点,径向畸变越大。如下图,棋盘的两个边缘用红线标记。但是,你可以看到,棋盘的边界不是一条直线,与红线不匹配,所有预期的直线都凸出来了,访问 Distortion (optics) 了解更多细节。

径向畸变可以由下面的方程表示:

xdr=x(1+k1r2+k2r4+k3r6)ydr=y(1+k1r2+k2r4+k3r6)x_{dr}=x(1+k_1r^2+k_2r^4+k_3r^6) \\ y_{dr}=y(1+k_1r^2+k_2r^4+k_3r^6) xdr​=x(1+k1​r2+k2​r4+k3​r6)ydr​=y(1+k1​r2+k2​r4+k3​r6)

类似的,切向畸变主要是因为图像拍摄镜头没有完全与成像平面平行对齐。因此,图像中的某些区域可能看起来比预期的更近。切向畸变量可表示为:

xdt=x+[2p1xy+p2(r2+2x2)]ydt=y+[2p2xy+p1(r2+2y2)]x_{dt}=x + [2p_1xy+p_2(r^2+2x^2)] \\ y_{dt}=y + [2p_2xy + p_1(r^2+2y^2)] xdt​=x+[2p1​xy+p2​(r2+2x2)]ydt​=y+[2p2​xy+p1​(r2+2y2)]

其中:

r2=x2+y2r^2=x^2+y^2 r2=x2+y2

简单来说,我们需要555个参数,失真参数如下:

Distortion−coefficients=(k1,k2,p1,p2,k3)Distortion-coefficients=(k_1,k_2, p_1,p_2,k_3) Distortion−coefficients=(k1​,k2​,p1​,p2​,k3​)

除此以外,我们还需要其他一些信息,比如相机的内参和外参;内在参数是相机特有的,他们包括焦距(fx,fy)(f_x,f_y)(fx​,fy​)和光学中心(cx,cy)(c_x,c_y)(cx​,cy​)等信息。焦距和光学中心可以用来创建一个相机矩阵,可以用来消除由于特定相机的镜头造成的失真。相机矩阵对于特定的相机是唯一的,因此一旦计算出来,就可以在同一相机拍摄的其他图像上重复使用。它表示为3x3矩阵:

camera.matrix=[fx0cx0fycy001]camera.matrix=\begin{bmatrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{bmatrix} camera.matrix=⎣⎡​fx​00​0fy​0​cx​cy​1​⎦⎤​

外部参数对应旋转和平移向量,会将3D坐标点(世界坐标系)转换为直角坐标系。

对于立体应用,首先需要校正这些失真,为了找到这些参数,我们必须提供一些定义好的模式,例如棋盘格图像。我们找到一些我们已经直到相对位置的特定点,例如,国际象棋棋盘上的正方形角,我们直到这些点在现实空间中的坐标,也直到图像中的坐标,所以我们可以解出失真参数,为了获得更好的结果,我们至少需要10个测试模式。

如上所述,我们至少需要10个测试模式来进行相机标定。我们将利用OpenCV自带的 棋盘格图像(见samples/data/left01.jpg - left14.jpg)。相机标定所需的重要输入数据是图像中三维真实世界点的集合以及这些点对应的二维图像坐标。我们可以很容易地从图像中找到对应的坐标。(这些图像点是国际象棋中两个黑色方块相互接触的位置)

那么来自真实世界空间的3D点呢?这些图像是由静态相机拍摄的,棋盘被放置在不同的位置和方向。我们需要知道(X,Y,Z)的值。但为了简单起见,我们可以说象棋棋盘在XY平面上保持静止,(所以Z总是=0),相机也相应地移动。这种考虑有助于我们只找到X和Y的值。现在对于X,Y的值,我们可以简单地将这些点传递为(0,0),(1,0),(2,0),…表示点的位置。在这种情况下,我们得到的结果将以棋盘正方形的大小为尺度。但是如果我们知道正方形的大小(比如30毫米),我们可以传递值为(0,0),(30,0),(60,0),… .因此,我们以毫米为单位得到结果(在这种情况下,我们不知道正方形大小,因为我们没有拍摄这些图像,所以我们根据正方形大小传递)。

3D点称为目标点,2D图像点称为图像点;

因此,我们可以使用函数cv2.findChessboardCorners()来查找棋盘中的模式。我们还需要传递什么样的模式,我们正在寻找,像8x8网格,5x5网格等。在本例中,我们使用7x6网格。(通常一个国际象棋棋盘有8x8的正方形和7x7的内角)。它返回角点和retval,如果获得pattern,则retval将为True。这些角将按顺序摆放(从左到右,从上到下)

【代码】

import numpy as np
import cv2
import globcriteria = (cv2.TERM_CRITERIA_EPS+cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)objp = np.zeros((6*7,3), np.float32)
objp[:,:2] = np.mgrid[0:7,0:6].T.reshape(-1, 2)objpoints = []
imgpoints = []images_name_list = glob.glob("assets/left/left*.jpg")for im_name in images_name_list:# print(im_name)img = cv2.imread(im_name) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)ret, corners = cv2.findChessboardCorners(gray, (7,6), None)if ret == True:objpoints.append(objp)corners2 = cv2.cornerSubPix(gray, corners, (11,11), (-1, -1), criteria)imgpoints.append(corners)cv2.drawChessboardCorners(img, (7,6), corners2, ret)cv2.imshow("image", img)cv2.waitKey(100)############ 相机标定
# 3D点和图像点
# cv2.calibrateCamera 相机标定
# 返回 camera matrix, distortion coefficients, rotation and translation vectors etc.
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)print("camera matrix:", mtx)
print("distortion", dist)############## 保存参数
np.savez("left.npz", mtx=mtx, dist=dist,rvecs=rvecs,tvecs=tvecs )############# 去失真
## OpenCV 有两种方法,
## 我们可以使用cv2.getOptimalNewCameraMatrix()基于自由缩放参数来细化相机矩阵。
## 如果缩放参数alpha=0,它将返回未扭曲的图像,其中包含最少的不需要像素。因此,它甚至可以删除图像角落的一些像素。
## 如果alpha=1,所有像素都保留一些额外的黑色图像。此函数还返回一个图像ROI,可用于裁剪结果。
imgtest = cv2.imread("assets/left/left12.jpg")
h, w = imgtest.shape[0:2]
newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mtx, dist, (w, h), 1, (w, h))cv2.imshow("left12", imgtest)#### 方法一: cv2.undistort(),方法一的效率更高一些
# undistort
dst = cv2.undistort(imgtest, mtx, dist, None, newcameramtx)# crop image
x, y, w, h = roi
dst = dst[y:y+h, x:x+w]cv2.imshow("left12-undistort", dst)
#### 方法二: using remapping
# undistort
mapx, mapy = cv2.initUndistortRectifyMap(mtx, dist, None, newcameramtx, (w,h), 5)
dst2 = cv2.remap(imgtest, mapx, mapy, cv2.INTER_LINEAR)# crop the image
x, y, w, h = roi
dst2 = dst[y:y+h, x:x+w]
cv2.imshow("left12-remapping", dst)cv2.waitKey(0)
cv2.destroyAllWindows()# 反向投影计算误差
# print(objpoints)
mean_error = 0
for i in range(len(objpoints)):imgpoints2, _ = cv2.projectPoints(objpoints[i], rvecs[i], tvecs[i], mtx, dist)error = cv2.norm(imgpoints[i], imgpoints2, cv2.NORM_L2)/len(imgpoints2)mean_error += error
print( "total error: {}".format(mean_error/len(objpoints)) )
  • output
camera matrix: [[534.07088364   0.         341.53407554][  0.         534.11914595 232.94565259][  0.           0.           1.        ]]
distortion [[-2.92971637e-01  1.07706962e-01  1.31038376e-03 -3.11018780e-054.34798110e-02]]

【接口】

  • findChessboardCorners
cv2.findChessboardCorners(   image, patternSize[, corners[, flags]]  ) -> retval, corners

找到棋盘格里内部角点

  • image: 源棋盘格图像,必须是8位灰度或彩色图像
  • patternSize: 棋盘特征的尺寸,行和列里的角点数
  • corners: 返回找到的角点
  • flags: 一个操作标志,可以为0或者其他标志组合:
    • cv2.CALIB_CB_ADAPTIVE_THRESH: 使用自适应阈值将图像转换为黑白,而不是固定的阈值水平(从平均图像亮度计算)。
    • cv2.CALIB_CB_NORMALIZE_IMAGE: 在应用固定或自适应阈值之前,用直方图均衡化对图像进行归一化
    • cv2.CALIB_CB_FILTER_QUADS: 使用附加的标准(如轮廓面积,周长,类似正方形的形状)来过滤掉在轮廓检索阶段提取的虚假四边形。
    • cv2.CALIB_CB_FAST_CHECK: 快速检查图像以寻找棋盘角,如果没有找到,则通过快捷方式调用。当没有观察到棋盘时,这可以大大加快退化条件下的调用速度。

该函数尝试确定输入图像是否是棋盘图案的视图,并定位棋盘内部的角点。如果找到了所有的角点,并且它们按一定的顺序(每行从左到右)放置,则该函数返回一个非零值。否则,如果函数无法找到所有的角点或重新排列它们,则返回0。例如,一个普通的棋盘有8 × 8个正方形和7 × 7个内角,即黑色正方形相互接触的点。检测到的坐标是近似的,为了更准确地确定它们的位置,函数调用了cornerSubPix。如果返回的坐标不够精确,你也可以使用带有不同参数的cornerSubPix函数。

该功能需要棋盘周围有一些空白空间(就像一个方的厚的的边框,越宽越好),以使检测在各种环境中更加健壮。否则,如果没有边框,背景较暗,外围黑色方块就无法正确分割,方块分组排序算法就会失败。

使用 gen_pattern.py (Create calibration pattern) 创建棋盘格。

  • drawChessboardCorners
cv2.drawChessboardCorners(   image, patternSize, corners, patternWasFound    ) -> image

绘制棋盘角点

  • image: 源棋盘格图像,必须是8位灰度或彩色图像
  • patternSize: 棋盘特征的尺寸,行和列里的角点数
  • corners: 返回找到的角点
  • patternWasFound: 显示完全的棋盘是否找到,

该函数显示每个单独的角点,如果棋盘没有找到,显示检测到的检测为红色的圆圈,如果找到了棋盘,则显示彩色的角点和其连线;

  • calibrateCamera
cv2.calibrateCamera( objectPoints, imagePoints, imageSize, cameraMatrix, distCoeffs[, rvecs[, tvecs[, flags[, criteria]]]]   ) -> retval, cameraMatrix, distCoeffs, rvecs, tvecscv.calibrateCameraExtended(   objectPoints, imagePoints, imageSize, cameraMatrix, distCoeffs[, rvecs[, tvecs[, stdDeviationsIntrinsics[, stdDeviationsExtrinsics[, perViewErrors[, flags[, criteria]]]]]]]    ) -> retval, cameraMatrix, distCoeffs, rvecs, tvecs, stdDeviationsIntrinsics, stdDeviationsExtrinsics, perViewErrors

从标定板不同视图中找到相机内参和外参

  • objectPoints: 在新的接口中,它是校准模式坐标空间中校准模式点向量的向量(例如 std::vector<std::vector<cv::Vec3f> >)。外层向量包含与模式视图数量一样多的元素。如果在每个视图中显示相同的校准模式,并且它是完全可见的,那么所有的向量将是相同的。尽管,在不同的视图中使用部分遮挡的模式甚至不同的模式是可能的。然后向量就不一样了。虽然这些点是3D的,但如果使用的校准模式是平面,那么它们都位于校准模式的XY坐标平面上(因此z坐标为0)。在旧接口中,不同视图下的所有对象点向量都被连接在一起。
  • imagePoints: 在新的接口中,它是校准模式点投影向量的向量(例如 std::vector<std::vector<cv::Vec2f>>)imagePoints.size()objectPoints.size(),以及每个 iimagePoints[i].size()objectPoints[i].size()必须分别相等。在旧接口中,不同视图下的所有对象点向量都被连接在一起。
  • imageSize: 仅用于初始化相机内禀矩阵的图像大小。
  • cameraMatrix:
    A=[fx0cx0fycy001]A=\begin{bmatrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{bmatrix} A=⎣⎡​fx​00​0fy​0​cx​cy​1​⎦⎤​

如果指定了 CALIB_USE_INTRINSIC_GUESS和/或 CALIB_FIX_ASPECT_RATIO, CALIB_FIX_PRINCIPAL_POINTCALIB_FIX_FOCAL_LENGTH ,则在调用函数之前必须初始化 fx, fy, cx, cy的部分或全部。

  • distCoeffs: 输入或输出的失真系数 (k1,k2,p1,p2[,k3[,k4,k5,k6[,s1,s2,s3,s4[,τx,τy]]]])(k_1,k_2,p_1,p_2[,k_3[,k_4,k_5,k_6[,s_1,s_2,s_3,s_4[,τ_x,τ_y]]]])(k1​,k2​,p1​,p2​[,k3​[,k4​,k5​,k6​[,s1​,s2​,s3​,s4​[,τx​,τy​]]]]) ,个数为 4, 5, 8, 12 或14.
  • rvecs: 每个模式视图估计的旋转向量的输出向量(Rodrigues)(例如 std::vector<cv::Mat>>)。也就是说,每个第 i个旋转向量与对应的第 i个平移向量(参见下一个输出参数说明)将校准模式从物体坐标空间(其中指定了物体点)带到相机坐标空间。用更专业的术语来说,第 i个旋转和平移向量的元组执行了从对象坐标空间到相机坐标空间的基的变化。由于它的对偶性,这个元组相当于校准模式相对于相机坐标空间的位置。
  • tvecs: 每个模式视图估计的平移向量的输出向量,见上面的参数说明。
  • stdDeviationsIntrinsics: 对内在参数估计的标准偏差的输出向量。值的偏差顺序:(fx,fy,cx,cy,k1,k2,p1,p2,k3,k4,k5,k6,s1,s2,s3,s4,τx,τy)(f_x,f_y,c_x,c_y,k_1,k_2,p_1,p_2,k_3,k_4,k_5,k_6,s_1,s_2,s_3,s_4,τ_x,τ_y)(fx​,fy​,cx​,cy​,k1​,k2​,p1​,p2​,k3​,k4​,k5​,k6​,s1​,s2​,s3​,s4​,τx​,τy​)如果有一个参数没有估计到,其偏差等于零。
  • stdDeviationsExtrinsics: 外部参数估计标准差的输出向量。偏差值的顺序:(R0,T0,…,RM−1,TM−1)(R_0,T_0,…,R_{M−1},T_{M−1})(R0​,T0​,…,RM−1​,TM−1​),其中MMM为模式视图的数量。RiR_iRi​和TiT_iTi​是连接在一起的1×31×31×3个向量。
  • perViewErrors: 每个模式视图估计RMS重投影误差的输出向量。
  • flags: 不同的标志,可能是0或以下值的组合:
    • cv2.CALIB_USE_INTRINSIC_GUESS: cameraMatrix包含有效的初始值fx,fy,cx,cyfx, fy, cx, cyfx,fy,cx,cy,进一步优化。否则,(cx,cy)(cx, cy)(cx,cy)最初被设置为图像中心(使用imageSize),并且以最小二乘方式计算焦距。注意,如果内在参数是已知的,就没有必要只使用这个函数来估计外在参数。使用solvePnP代替。
    • cv2.CALIB_FIX_PRINCIPAL_POINT: 在全局优化过程中,主点不变。当也设置了 CALIB_USE_INTRINSIC_GUESS时,它位于中心或指定的另一个位置。
    • cv2.CALIB_FIX_ASPECT_RATIO: 函数只考虑fy作为自由参数。比率fx/fy保持与输入cameraMatrix中的相同。当 CALIB_USE_INTRINSIC_GUESS未设置时,fx和fy的实际输入值将被忽略,只计算它们的比值并进一步使用。
    • cv2.CALIB_ZERO_TANGENT_DIST: 切向失真系数(p1,p2)设置为零并保持为零。
    • cv2.CALIB_FIX_FOCAL_LENGTH: 如果设置了 CALIB_USE_INTRINSIC_GUESS,那么在全局优化过程中焦距不会改变。
    • cv2.CALIB_FIX_K1,…, CALIB_FIX_K6: 优化过程中不改变相应的径向畸变系数。如果设置了 CALIB_USE_INTRINSIC_GUESS,则使用提供的distCoeffs矩阵中的系数。否则,设置为0。
    • cv2.CALIB_RATIONAL_MODEL: 启用系数k4、k5和k6。为了提供向后兼容性,应该显式指定这个额外的标志,以使校准函数使用合理模型并返回8个或更多系数。
    • cv2.CALIB_THIN_PRISM_MODEL: 启用系数s1、s2、s3和s4。为了提供向后兼容性,应该显式指定这个额外的标志,以使校准函数使用薄棱镜模型并返回12个或更多系数。
    • cv2.CALIB_FIX_S1_S2_S3_S4: 优化过程中不改变薄棱镜畸变系数。如果设置了 CALIB_USE_INTRINSIC_GUESS,则使用提供的distCoeffs矩阵中的系数。否则,设置为0。
    • cv2.CALIB_TILTED_MODEL: 启用系数tauX和tauY。为了提供向后兼容性,应该显式指定这个额外的标志,以使校准函数使用倾斜的传感器模型并返回14个系数。
    • cv2.CALIB_FIX_TAUX_TAUY: 优化过程中不改变倾斜传感器模型的系数。如果设置了 CALIB_USE_INTRINSIC_GUESS,则使用提供的distCoeffs矩阵中的系数。否则,设置为0。
  • criteria: 迭代优化算法的终止参数
  • getOptimalNewCameraMatrix
cv2.getOptimalNewCameraMatrix(   cameraMatrix, distCoeffs, imageSize, alpha[, newImgSize[, centerPrincipalPoint]]    ) -> retval, validPixROI

返回基于自由缩放参数的新相机固有矩阵。

  • cameraMatrix: 输入相机内参
  • distCoeffs: 失真系数 (k1,k2,p1,p2[,k3[,k4,k5,k6[,s1,s2,s3,s4[,τx,τy]]]])(k_1,k_2,p_1,p_2[,k_3[,k_4,k_5,k_6[,s_1,s_2,s_3,s_4[,τ_x,τ_y]]]])(k1​,k2​,p1​,p2​[,k3​[,k4​,k5​,k6​[,s1​,s2​,s3​,s4​[,τx​,τy​]]]]) ,个数为 4, 5, 8, 12 或14. 如果为空,则假设没有失真;
  • imageSize: 原始图像大小
  • alpha: 自由缩放参数介于0(当未失真图像中的所有像素都有效时)和1(当源图像中的所有像素都保留在未失真图像中时)之间。详情见stereoRectify。
  • newImgSize: 新的映射图像大小,默认时原图大小
  • validPixROI: 有效的ROI区域
  • centerPrincipalPoint: 可选标志,用于指示在新的相机固有矩阵中主点是否应位于图像中心。默认情况下,主点的选择是为了使源图像的一个子集(由alpha决定)最适合修正后的图像。

返回:
相机的新内参矩阵;

该函数根据自由缩放参数计算并返回最优的新相机内参矩阵。通过改变这个参数,您可以只检索合理的像素alpha=0,如果角落中有有价值的信息alpha=1,则保留所有原始图像像素,或者获得介于两者之间的东西。当alpha>0时,未失真的结果很可能有一些黑色像素对应于捕获的失真图像之外的“虚拟”像素。原始相机固有矩阵、失真系数、计算出的新相机固有矩阵和newImageSize应该传递给initUndistortRectifyMap来生成用于重新映射的remap。

  • undistort
cv2.undistort(   src, cameraMatrix, distCoeffs[, dst[, newCameraMatrix]] ) -> dst

转换图像,补偿镜头失真,修复径向和切向畸变,该函数只是initUndistortRectifyMap和remap的组合。目标图像中那些源图像中没有对应像素的像素被填充为0;校正后的图像中可以看到源图像的特定子集,可以通过newCameraMatrix进行调节。您可以使用getOptimalNewCameraMatrix来计算适当的newCameraMatrix,这取决于您的需求。使用calibrateCamera可以确定摄像机矩阵和畸变参数。如果图像的分辨率与校准阶段使用的分辨率不同,则fx,fy,cx和cy需要相应缩放,而失真系数保持不变。

  • src: 输入失真图像
  • dst: 输出矫正图像
  • cameraMatrix: 相机矩阵
  • newCameraMatrix: 新的相机矩阵
  • distCoeffs: 失真系数 (k1,k2,p1,p2[,k3[,k4,k5,k6[,s1,s2,s3,s4[,τx,τy]]]])(k_1,k_2,p_1,p_2[,k_3[,k_4,k_5,k_6[,s_1,s_2,s_3,s_4[,τ_x,τ_y]]]])(k1​,k2​,p1​,p2​[,k3​[,k4​,k5​,k6​[,s1​,s2​,s3​,s4​[,τx​,τy​]]]]) ,个数为 4, 5, 8, 12 或14. 如果为空,则假设没有失真;
  • initUndistortRectifyMap
cv.initUndistortRectifyMap(  cameraMatrix, distCoeffs, R, newCameraMatrix, size, m1type[, map1[, map2]]  ) -> map1, map2

计算不失真和还原图

  • cameraMatrix: 输入的相机矩阵
  • distCoeffs: 失真系数 (k1,k2,p1,p2[,k3[,k4,k5,k6[,s1,s2,s3,s4[,τx,τy]]]])(k_1,k_2,p_1,p_2[,k_3[,k_4,k_5,k_6[,s_1,s_2,s_3,s_4[,τ_x,τ_y]]]])(k1​,k2​,p1​,p2​[,k3​[,k4​,k5​,k6​[,s1​,s2​,s3​,s4​[,τx​,τy​]]]]) ,个数为 4, 5, 8, 12 或14. 如果为空,则假设没有失真;
  • R: 目标空间(3×33×33×3矩阵)中可选的还原变换。R1R2,通过 stereoRectify计算可以传递到这里。如果矩阵为空,则假设是恒等变换。
  • newCameraMatrix: 新的相机矩阵
  • size: 不失真图像的尺寸
  • m1type: 第一个输出图像的类型 CV_32FC1, CV_32FC2 or CV_16SC2
  • map1: 第一个输出映射 (x坐标映射)
  • map2: 第二个输出映射(y坐标映射)
  • remap
cv2.remap(   src, map1, map2, interpolation[, dst[, borderMode[, borderValue]]]  ) -> dst

不能 in-place 操作。

对图像应用通用几何变换,应用下述公式
dst(x,y)=src(mapx(x,y),mapy(x,y))dst(x,y)=src(map_x(x,y), map_y(x,y))dst(x,y)=src(mapx​(x,y),mapy​(x,y))

  • src: 输入图像
  • dst: 与 map1map_1map1​大小相同,与src类型相同
  • map1: 可以是 (x,y)(x,y)(x,y)的映射,也可以是xxx的映射,CV_16SC2 , CV_32FC1, or CV_32FC2
  • map2: 是yyy的映射图,如果map1是 (x,y)(x,y)(x,y),可以为空
  • interpolation: 插值类型,参考 InterpolationFlags 方法 INTER_AREA 和 INTER_LINEAR_EXACT 不支持。
  • borderMode: 当borderMode=BORDER_TRANSPARENT时,这意味着目标图像中与源图像中的“异常值”对应的像素不被函数修改。
  • borderValue: 扩边值,默认为0;

【参考】

  1. Camera Calibration
  2. Distortion (optics)
  3. OpenCV: Camera Calibration and 3D Reconstruction

【OpenCV-Python】教程:6-1 相机标定相关推荐

  1. OpenCV Python教程(2、图像元素的访问、通道分离与合并)

    OpenCV Python教程之图像元素的访问.通道分离与合并 转载请详细注明原作者及出处,谢谢! 访问像素 像素的访问和访问numpy中ndarray的方法完全一样,灰度图为: [python] v ...

  2. OpenCV Python教程(3)(4)(5): 直方图的计算与显示 形态学处理 初级滤波内

    OpenCV Python教程(3.直方图的计算与显示) 本篇文章介绍如何用OpenCV Python来计算直方图,并简略介绍用NumPy和Matplotlib计算和绘制直方图 直方图的背景知识.用途 ...

  3. Python实现的双目相机标定系统

    Python实现的双目相机标定系统 主要是求基础矩阵来确定两个相机坐标系之间的旋转和平移,继而实现双目相机拍摄图片之间的对齐(校正). copyright@Eason 文末有代码链接. Require ...

  4. 使用opencv实现单目标定相机标定(摘抄)

    使用opencv实现单目标定 相机标定的目的:获取摄像机的内参和外参矩阵(同时也会得到每一幅标定图像的选择和平移矩阵),内参和外参系数可以对之后相机拍摄的图像就进行矫正,得到畸变相对很小的图像. 相机 ...

  5. OpenCV实现张正友相机标定源代码

    本源代码基于VC++和opencv Opencv2.4.13.6版本开发,实现张正友相机标定源代码,资源包括完整源代码和12张棋盘图片,完美运行. Opencv2.4.13.6安装包下载地址:http ...

  6. opencv C++ 张正友相机标定

    //张正友相机标定 //https://blog.csdn.net/u010925447/article/details/77997735 #include <opencv2/core/core ...

  7. opencv python教程简书_OpenCV-Python系列二:常用的图像属性

    对于图像,我们经常需要知道关于图像的特殊属性,比如宽度,高度,面积,像素点数目等等,那么在opencv-python中,这些信息如何获取呢? 本文结构: 1.基本图像属性 2. 对于opencv中的特 ...

  8. opencv python教程-OpenCV4 Python 最新中文版官方教程来了(附下载)

    教程简介 OpenCV 是计算机视觉中经典的专用库,然而其中文版官方教程久久不来.近日,一款最新 OpenCV4.1 版本的完整中文版官方教程出炉,读者朋友可以更好的学习了解 OpenCV 相关细节. ...

  9. 使用opencv做双目测距(相机标定+立体匹配+测距)

    转载自:     http://www.cnblogs.com/daihengchen/p/5492729.html 最近在做双目测距,觉得有必要记录点东西,所以我的第一篇博客就这么诞生啦~ 双目测距 ...

最新文章

  1. 绝大多数人没玩过也没见过的现象:20个MYSQL进程共用1个3306端口
  2. ccxprocess启动项可以禁用么_macOS 删除烦人的CCXProcess.app
  3. 附带数据库的应用程序
  4. 46.Express框架 GET 方法和POST 方法
  5. golang中的切片
  6. 149. Leetcode 1005. K 次取反后最大化的数组和 (贪心算法-基础题目)
  7. [CS101] 转载:浅议Fibonacci(斐波纳契)数列求解
  8. 2017.12.1T19_B2_2zuoye
  9. 如何面试.NET/ASP.NET工程师?
  10. 400. 第 N 位数字
  11. java 面向对象继承的思想_Java面向对象思想!
  12. C语言-基础例题55道
  13. 五色电阻在线计算机,色环电阻(5色环在线电阻计算器)
  14. O2O模式的赢利点有哪些?
  15. Android Studio代码边界线的设置
  16. jbox ajax,JBox演示30种不同的调用方法
  17. 深度学习图像分类(六):Stochastic_Depth_Net
  18. 射击类项目(数据的持久化保存)整理四
  19. 涉密计算机不得接入互联网等公共信息网络,在涉密场所使用的与国际互联网或者其他公共网络连接的计算机不得安装视频、音频等输入装置 - 作业在线问答...
  20. 投资学 U15 利率期限结构 习题解读

热门文章

  1. 关于TP5静态文件加载不出来
  2. xp系统扫描仪服务器,通过系统自带的扫描仪向导获取图片(适用于WinXP)
  3. leetcode日记
  4. HDU 1713 相遇周期(求两个分数的最小公倍数)
  5. English Learning - Day16 作业打卡 2022.12.22 周四
  6. java关于考核 源码,基于jsp的职工绩效考核管理-JavaEE实现职工绩效考核管理 - java项目源码...
  7. Linux sleep和 usleep睡眠函数的使用
  8. html查看详情,查看详情页.html
  9. 创业公司如何留住人才
  10. 遮挡检测--基于角度的遮挡检测方法