- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个经过校准的多摄像头系统。内部(焦距、畸变等)和外部(姿势)相机参数均已使用基于 HALCON 的程序进行了估算。现在,目标是编写一个 C++ 程序,读取相机参数,特别是 HALCON 估计的畸变系数(k1、k2、k3、p1、p2),并使用它们通过 OpenCV 对图像进行去畸变。不幸的是,到目前为止,我无法成功:HALCON 和 OpenCV 中使用的相同失真系数会生成截然不同的未失真图像!我想,问题在于 HALCON 和 OpenCV 解释失真系数的方式,甚至是它们执行去失真的方式。
这是我的 HALCON 代码,用于读取失真系数并使用它们来消除测试图像的失真:
* Read the internal camera calibratino parameters ('area_scan_polynomial' model)
read_cam_par('Calibration.dat', CamParam)
* Estimate camera parameters without distortion: set all distortion coefficients to [k1, k2, k3, p1, p2] = [0, 0, 0, 0, 0]
change_radial_distortion_cam_par ('fixed', CamParam, [0, 0, 0, 0, 0], CamParamOut)
* Estimate camera matrix of distortion-free parameters (used for OpenCV)
cam_par_to_cam_mat(CamParamOut, CamMatrix, ImageWidth, ImageHeight)
* Generate map to use for undistortion.
* Note the use of type 'coord_map_sub_pix' which is of type 'vector_field_absolute',
* i.e. the values are 2D absolute coordinates of the corresponding undistorted pixel location
gen_radial_distortion_map(Map, CamParam, CamParamOut, 'coord_map_sub_pix')
* Read a test image and undistort it using the estimate map
read_image (Image, 'test.jpg')
map_image(Image, Map, ImageRectified)
我正在尝试使用以下代码在 OpenCV 中做完全相同的事情:
Mat view , rview, mapx, mapy;
// Read the same test image as in HALCON
view = imread("test.jpg");
// Get the image size
const Size viewSize = view.size();
// Generate map to use for undistortion
initUndistortRectifyMap(cameraMatrix, distCoeffs, Mat(),
cameraMatrix, viewSize, CV_16SC2, mapx, mapy);
// Undistort the image using the estimated map
remap(view, rview, mapx, mapy, INTER_LINEAR);
OpenCV 中的变量“cameraMatrix”等同于 HALCON 中的变量“CamMatrix”。 OpenCV 中的失真系数“distCoeffs”取自 HALCON(k1、k2、k3、p1、p2),并按照文档以这种方式重新排列:
distCoeffs = (Mat_<double>(5, 1) << k1, k2, p2, p1, k3)
请注意,k3 作为第五个参数提供,并且 p2 和 p1 已交换。根据 HALCON 文档(https://www.mvtec.com/doc/halcon/12/en/calibrate_cameras.html,请参阅函数 calibrate_cameras),图像平面 (u, v) 中的未失真坐标是根据失真 (u', v') 计算得出的:
u = u' + u' (k1 r^2 + k2 r^4 + k3 r^6) + p1 (r^2 + 2 u'^2) + 2 p2 u' v'
v = v' + v' (k1 r^2 + k2 r^4 + k3 r^6) + p2 (r^2 + 2 v'^2) + 2 p1 u' v'
having r = sqrt(u'^2 + v'^2)
而在 OpenCV(https://docs.opencv.org/2.4/modules/imgproc/doc/geometric_transformations.html,参见函数 initUndistortRectifyMap)中,同样的未失真坐标被类似地估计,只有 p1 和 p2 被交换。
显然,OpenCV 和 HALCON 都以类似的方式将像素投影到图像平面中。也就是说,具有像素 (x, y) 的相应图像平面坐标计算为:
u' = x - cx / fx
v' = y - cy / fy
这些当然可以反投影,重新得到对应的像素坐标:
x = u' * fx + cx
y = v' * fy + cy
根据文档,似乎一切都应该按预期工作。但是,我不明白为什么基于 HALCON 和 OpenCV 的代码仍然输出截然不同的结果。我注意到,为了产生与 HALCON 中类似的无失真结果(但不完全相同),我必须按比例缩小(约 100 倍!)OpenCV 中的失真系数。事实上,我注意到 HALCON 估计了巨大的失真系数。例如,为了在未失真的图像中产生可见的变化,我必须在 HALCON 中设置 k1=1000,而在 OpenCV 中 k1=1 已经明显地改变了图像。对于某些失真系数,我什至不得不反转(带负号)值以获得朝类似方向发展的未失真结果...
我深入研究了 HALCON 无畸变代码,并尝试按照文档手动估计无畸变坐标 (u, v),这应该对应于“ map ”中的坐标。我这样做是为了确保“ map ”确实按照文档中指定的方式/我理解的方式进行了估算。然而,即使在这里,与“ map ”中估计的结果相比,我也得到了非常不同的结果......为了进行测试,我使用了以下代码:
* Get the camera parameters from the calibration
get_cam_par_data (CamParam, 'k1', k1)
get_cam_par_data (CamParam, 'k2', k2)
get_cam_par_data (CamParam, 'k3', k3)
get_cam_par_data (CamParam, 'p1', p1)
get_cam_par_data (CamParam, 'p2', p2)
get_cam_par_data (CamParam, 'cx', cx)
get_cam_par_data (CamParam, 'cy', cy)
get_cam_par_data (CamParam, 'image_width', width)
get_cam_par_data (CamParam, 'image_height', height)
* Estimate the camera matrix, to read the focal length in pixel
cam_par_to_cam_mat(CamParamOut, CamMatrix, width, height)
* Extract the focal lenths in pixel from the estimated camera matrix (see above)
fx_px := CamMatrix[0]
fy_px := CamMatrix[4]
* Pick a pixel coordinate (I tried different values) in the image domain
x := 350
y := 450
* Convert into image plane coordinates
u_1 := (x - cx) / fx_px
v_1 := (y - cy) / fy_px
* Estimate the undistorted location u_2 and v_2
r2 := u_1 * u_1 + v_1 * v_1
u_2 := u_1 * (1 + k1 * r2 + k2 * r2 * r2 + k3 * r2 * r2 * r2) + 2 * p1 * u_1 * v_1 + p2 * (r2 + 2 * u_1 * u_1)
v_2 := v_1 * (1 + k1 * r2 + k2 * r2 * r2 + k3 * r2 * r2 * r2) + 2 * p2 * u_1 * v_1 + p1 * (r2 + 2 * v_1 * v_1)
* Back to pixel coordinate
x_1 := u_2 * fx_px + cx
y_1 := v_2 * fy_px + cy
* Compare the values with the value in Map (estimated as before). G_found and G_est should match!
G_found := [y_1, x_1]
get_grayval(Map, y, x, G_est)
我试着一次只关注几个失真系数,即只有 k1 > 0,其他都设置为 0。但是在大多数情况下,(除了 x = cx,y = cy 时的少数异常(exception))未失真坐标超过图片大小甚至变成负数。
这不是HALCON估计无畸变贴图坐标的方式吗?我错过了什么吗?应该如何转换这些失真系数以使 OpenCV 生成完全相同的未失真结果图像?任何帮助将不胜感激!
由于某些软件限制,仅使用 OpenCV 进行校准和不失真是有争议的,但不幸的是,这对我来说不是一个可接受的解决方案。
最佳答案
我能够找到我自己问题的答案。简而言之,答案是肯定的。是的,可以从 HALCON 转换为 OpenCV 失真参数,反之亦然。原因是,HALCON 和 OpenCV 显然估计的是相同的底层模型。我做了几次成功的测试来证实这一点,我想分享我的见解。下面是我计算的将每个失真参数从 HALCON 转换为 OpenCV 的公式:
k1_opencv = k1_halcon * fmm * fmm;
k2_opencv = k2_halcon * fmm * fmm * fmm * fmm;
k3_opencv = k3_halcon * fmm * fmm * fmm * fmm * fmm * fmm;
p1_opencv = p2_halcon * fmm; // Notice: swap
p2_opencv = p1_halcon * fmm;
请注意,fmm 是以毫米为单位的焦距,例如在哈尔康。估计 map 中估计的相同值的正确 HALCON 代码是:
get_cam_par_data (CamParam, 'sx', Sx)
get_cam_par_data (CamParam, 'sy', Sy)
* Convert into image plane coordinates
u_1 := (x - cx) * sx
v_1 := (y - cy) * sy
* Estimate the undistorted location u_2 and v_2
r2 := u_1 * u_1 + v_1 * v_1
u_2 := u_1 * (1 + k1 * r2 + k2 * r2 * r2 + k3 * r2 * r2 * r2) + 2 * p2 * u_1 * v_1 + p1 * (r2 + 2 * u_1 * u_1)
v_2 := v_1 * (1 + k1 * r2 + k2 * r2 * r2 + k3 * r2 * r2 * r2) + 2 * p1 * u_1 * v_1 + p2 * (r2 + 2 * v_1 * v_1)
* Back to pixel coordinate
x_1 := u_2 / sx + cx
y_1 := v_2 / sy + cy
* Compare coordinates. NOTICE: we get the values from the distortion map
* going from UNdistorted to DIstorted coordinates!!!
G_found := [y_1, x_1]
gen_radial_distortion_map(MapUD, CamParamOut, CamParam, 'coord_map_sub_pix')
get_grayval(MapUD, y, x, G_est)
关于我在问题中发布的初始代码,坐标是使用以毫米 sx 和 sy 为单位的像素大小而不是焦距进行转换的。另一个区别是我们将估计的坐标与 MapUD 的值进行比较,其中 MapUD(UNdistorted coordinate) := DIstorted coordinate。估计的坐标和 map 中的坐标对应于图像边界处的舍入误差和条件。
OpenCV 改为执行以下操作(完全符合文档!):
float u = (x - cx) / fpx;
float v = (y - cy) / fpx;
float x_1 = u;
float y_1 = v;
float r2 = x_1 * x_1 + y_1 * y_1;
float x_2 = x_1 * (1 + k1 * r2 + k2 * r2 * r2 + k3 * r2 * r2 * r2) + 2 * p1 * x_1 * y_1 + p2 * (r2 + 2 * x_1 * x_1);
float y_2 = y_1 * (1 + k1 * r2 + k2 * r2 * r2 + k3 * r2 * r2 * r2) + p1 * (r2 + 2 * y_1 * y_1) + 2 * p2 * x_1 * y_1;
float map_x_est = x_2 * fpx + cx;
float map_y_est = y_2 * fpx + cy;
// Compare coordinates
initUndistortRectifyMap(cameraMatrix, distCoeffs, Mat(),
cameraMatrix, viewSize, CV_32FC1, mapx, mapy);
float map_x = mapx.at<float>(y, x);
float map_y = mapy.at<float>(y, x);
在上面的代码中,值map_x对应于map_x_est,map_y对应于map_y_est直到舍入误差。如果我们使用与 HALCON 中相同的 cameraMatrix,并使用上述公式转换失真系数 distCoeffs,我们可以清楚地看到 OpenCV 变量 map_x 和 map_y 对应于在 HALCON 的 MapUD 中找到的那些。我通过在 HALCON 和 OpenCV 中针对不同的失真参数逐一(在整个域中)输出映射值来测试这一点,获得相同的结果,直到小误差 < 0.01 像素。
附加信息:MVTec 向我发送了一些 HALCON 代码,用于将手动估计的坐标与 map 中的坐标进行比较。请注意,关于我的解决方案,它们是相反的,即从扭曲到未扭曲。在许多情况下,代码不对我有用。请随意尝试并告诉我:
dev_close_window ()
dev_update_off ()
Width:=1600
Height:=1200
dev_open_window_fit_size(0, 0, Width, Height, -1, -1, WindowHandle)
gen_cam_par_area_scan_polynomial (0.008, 0, 0, 0, 0, 10, 5.2e-006, 5.2e-006, Width/2, Height/2, Width, Height, CamParam)
change_radial_distortion_cam_par ('fixed', CamParam, [0, 0, 0, 0, 0], CamParamOut)
gen_radial_distortion_map(Map, CamParam, CamParamOut, 'coord_map_sub_pix')
get_cam_par_data (CamParam, 'k1', k1)
get_cam_par_data (CamParam, 'k2', k2)
get_cam_par_data (CamParam, 'k3', k3)
get_cam_par_data (CamParam, 'p1', p1)
get_cam_par_data (CamParam, 'p2', p2)
get_cam_par_data (CamParam, 'cx', cx)
get_cam_par_data (CamParam, 'cy', cy)
get_cam_par_data (CamParam, 'sx', Sx)
get_cam_par_data (CamParam, 'sy', Sy)
* Select a valid point
Row := 86
Col := 89
get_grayval(Map, Row, Col, G_map)
get_domain (Map, Domain)
test_region_point (Domain, Row, Col, IsInside)
if (IsInside)
* Check calculation
GRow:=G_map[0]
GCol:=G_map[1]
U_1 := (GCol - cx) * Sx
V_1 := (GRow - cy) * Sy
R_2 := U_1 * U_1 + V_1 * V_1
U_2 := U_1 * (1 + k1 * R_2 + k2 * R_2 * R_2 + k3 * R_2 * R_2 * R_2) + p1 * (R_2 + 2 * U_1 * U_1) + 2 * p2 * U_1 * V_1
V_2 := V_1 * (1 + k1 * R_2 + k2 * R_2 * R_2 + k3 * R_2 * R_2 * R_2) + p2 * (R_2 + 2 * V_1 * V_1) + 2 * p1 * U_1 * V_1
Col_calc := U_2 / Sx + cx
Row_calc := V_2 / Sy + cy
G_input:=[Row, Col]
G_calc:=[Row_calc, Col_calc]
G_diff:=G_calc-G_input
dev_inspect_ctrl ([G_input, G_calc, G_diff])
stop()
else
* Point is outside domain of distortion map
stop()
endif
dev_close_inspect_ctrl ([G_input, G_calc, G_diff])
dev_clear_window ()
dev_update_on ()
disp_message (WindowHandle, 'No more lines to execute...', 'window', 12, 12, 'black', 'true')
关于c++ - HALCON 到 OpenCV 失真系数转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58606394/
我已经训练了一个线性回归模型来以多输出方式进行预测。这是一个时间序列预测问题,根据一组输入来估计 future 12 个月的需求。在过去 - 如果我只预测一个输出值 - 我会简单地调用以下命令来访问模
我的应用程序对原始音频信号执行FFT(所有麦克风读数均为values中的16位整数值,即1024个单元)。它首先根据16位对读数进行归一化。然后提取频率为400Hz的幅度。 int sample_ra
我从包含相同语音内容的两个大约 30 秒的音频文件中提取了两个系列 MFCC 系数。音频文件从不同来源录制在同一位置。应该估计音频是否包含相同的对话或不同的对话。目前我已经测试了两个Mfcc系列的相关
我正在尝试使用两个自变量(批处理和方法)和一个因变量 (conc) 运行线性回归。当我运行回归时,我得到一个系数的 NA 值。当我更改模型中自变量的顺序时,NA 值显示为不同的变量。这是一个可重现的数
我想要的,大图:我想知道如何在 Java 中模仿 Mathematica 的 ExtendedGCD[...] 功能。有关该功能的信息可以在 here 中找到,但为了完整起见,我将对其进行简要描述。
我用 R 编写了这个套索代码,并且得到了一些 beta 值: #Lasso library(MASS) library(glmnet) Boston=na.omit(Boston) x=model.m
我有一个幅频响应点列表。振幅以分贝为单位给出。 任务是将此 AFR 列表导出为某些硬件 DSP 设备的一组系数。我知道此设备的文件格式。该设备的规范表明它需要 12288 个系数,并且 DSP 有 2
是否可以替换 lm 对象中的系数? 我认为以下会起作用 # sample data set.seed(2157010) x1 <- 1998:2011 x2 <- x1 + rnorm(length(
我正在尝试使用 lm.ridge 方法执行岭回归。我的问题是如何获得拟合模型的系数?我从调用中得到不同的结果: 模型$coef 系数(模型) 哪个是正确的?另外,为什么我从调用中得到不同的结果: co
以下代码片段死于 Eigen 断言: MatrixXd L; VectorXd x, b; ... ASSERT_MATRIX_EQ(L*x, b); 与, template void ASSERT
有没有办法从编码的图像和视频中轻松提取 DCT 系数(和量化参数)?任何解码器软件都必须使用它们来解码 block DCT 编码的图像和视频。所以我很确定解码器知道它们是什么。有没有办法将它们暴露给使
如何找到矢量 w 是多少,即垂直于分离平面? 最佳答案 我就是这样做的here .如果我没记错的话,这是基于 dual form 的SVM 优化的结果。 model = svmtrain(...);
我是 FFMPEG 的新手。我知道如何提取关键帧, 但现在我想提取那些 I 帧的 DC 系数。 您能否帮助编写 FFMPEG 命令的正确语法以获取 DC 系数? 问候 最佳答案 FFmpeg 命令不会
任何人都可以共享任何代码或可调用以从 HEVC 比特流中提取变换系数 (DCT/DST) 的函数吗? 我检查了 HM 16.0 的源代码。文件\source\Lib\TLibCommon\TComTr
我需要从 MPEG4 视频中提取有关运动矢量和 DC 系数的信息。我搜索了相关站点和主题,发现一个好的解决方案是使用 ffmpeg 编解码器的代码。尤其是 libavcodec/mpegvideo.c
我想删除sympy符号表达式中等于1的任何系数,例如:我希望 1.0x**2 成为 x**2 ,有办法做到吗?另外,如果可能的话,可以对整数进行舍入,例如将 2.0x**2 变为 2*x**2 最佳答
我想删除sympy符号表达式中等于1的任何系数,例如:我希望 1.0x**2 成为 x**2 ,有办法做到吗?另外,如果可能的话,可以对整数进行舍入,例如将 2.0x**2 变为 2*x**2 最佳答
我最近的任务是将 PMML 解析回 R 模型。 (我进行了广泛搜索,没有库可以为您进行这种转换。)我正在尝试将包含多项逻辑回归的 PMML 转换回 R 模型,但我不知道如何转换任何PMML 文档中保存
当使用 pandas statsmodels 的 .summary() 函数时,OLS 回归结果包括以下字段。 coef std err t P>|t| [
我正在 STM32F4 微 Controller 上使用 CMSIS 库开发 PID Controller 。我实在无法理解PID参数的归一化。现在我有了 PID Controller 的三个 Kp、
我是一名优秀的程序员,十分优秀!