视场(FOV)补偿与分辨率(Resolution)补偿
文章目录
0. 前言
如何将两个参数不一致的相机拍摄的图像变换成一个立体对?本文认为需要从两个方面进行:1.补偿;2.立体校正。本文主要讨论补偿部分的一些方法,相机的参数不一致常常表现在如焦距 f f f、分辨率(resolution)以及视场(FOV)大小不同。从视场补偿和分辨率补偿进行讨论,利用ROI截取和图像上采样方法进行补偿。
1. 技术路线
2. FOV补偿
2.1 理论介绍
2.1.1 相机内参回顾
- 假设两个相机内参数分别为 K 1 K_{1} K1和 K 2 K_{2} K2,有 K 1 = [ f x 1 γ 1 u 1 0 f y 1 v 1 0 0 1 ] K_{1}=\begin {bmatrix} f_{x1}&\gamma_{1}&u_{1} \\0&f_{y1}&v_{1}\\0&0&1 \end{bmatrix} K1=⎣⎡fx100γ1fy10u1v11⎦⎤、 K 2 = [ f x 2 γ 2 u 2 0 f y 2 v 2 0 0 1 ] K_{2}=\begin {bmatrix} f_{x2}&\gamma_{2}&u_{2} \\0&f_{y2}&v_{2}\\0&0&1 \end{bmatrix} K2=⎣⎡fx200γ2fy20u2v21⎦⎤。
有关相机内参数的概念请参考相机模型;
一般的,有轴倾斜参数 γ = 0 \gamma=0 γ=0, f x f_{x} fx、 f y f_{y} fy是以像素为单位的焦距, ( u , v ) (u,v) (u,v)为图像主点。
- 假设量相机的实际焦距(以mm为单位)分别为
f
1
f_{1}
f1和
f
2
f_{2}
f2,
α
\alpha
α为
x
x
x轴方向上系数,(单位为pixel/mm),
β
\beta
β为
y
y
y轴方向上系数,(单位为pixel/mm)
- { f x 1 = f 1 α 1 f y 1 = f 1 β 1 \left\{\begin{array}{ll} f_{x1}=f_{1}\alpha_{1} \\ f_{y1}=f_{1}\beta_{1}\end{array} \right. {fx1=f1α1fy1=f1β1、 { f x 2 = f 2 α 2 f y 2 = f 2 β 2 \left\{\begin{array}{ll} f_{x2}=f_{2}\alpha_{2} \\ f_{y2}=f_{2}\beta_{2}\end{array} \right. {fx2=f2α2fy2=f2β2
2.1.2 FOV
-
视场(FOV)由相机的焦距和传感器的尺寸决定,在其他条件不变的情况下,焦距越大视场越小;在其他条件不变的情况下,传感器尺寸越大视场越大;
-
,上图给出了垂直方向的视场角计算示意图,传感器的物理尺寸为 w ∗ h w*h w∗h(单位:mm),垂直方向视场角 A h = 2 a r c t a n ( h 2 f ) A_{h}=2arctan(\frac{h}{2f}) Ah=2arctan(2fh),同理水平方向视场角 A w = 2 a r c t a n ( w 2 f ) A_{w}=2arctan(\frac{w}{2f}) Aw=2arctan(2fw)。
- 即 { A h = 2 a r c t a n ( h 2 f ) A w = 2 a r c t a n ( w 2 f ) ( 单 位 : m m ) \left\{\begin{array}{ll} A_{h}=2arctan(\frac{h}{2f}) \\ A_{w}=2arctan(\frac{w}{2f})\end{array} \right.(单位:mm) {Ah=2arctan(2fh)Aw=2arctan(2fw)(单位:mm)
-
设图像大小为 W ∗ H W*H W∗H(单位:pixel),将上式转化换为以像素为单位计算: { A h = 2 a r c t a n ( h ∗ α 2 f ∗ α ) = 2 a r c t a n ( H 2 f x ) A w = 2 a r c t a n ( w ∗ β 2 f ∗ β ) = 2 a r c t a n ( W 2 f y ) ( 单 位 : p i x e l ) \left\{\begin{array}{ll} A_{h}=2arctan(\frac{h*\alpha}{2f*\alpha})=2arctan(\frac{H}{2f_{x}}) \\ A_{w}=2arctan(\frac{w*\beta}{2f*\beta})=2arctan(\frac{W}{2f_{y}})\end{array} \right.(单位:pixel) {Ah=2arctan(2f∗αh∗α)=2arctan(2fxH)Aw=2arctan(2f∗βw∗β)=2arctan(2fyW)(单位:pixel)
2.1.3 FOV补偿
- FOV可以通过减小有效传感器尺寸进行调整,也就是说可以减小视场较大图像的有效区域以对齐视场较小的图像,如下图所示:
- 补偿后的FOV计算公式为: { A h ′ = 2 a r c t a n ( H ′ 2 f x ) A w ′ = 2 a r c t a n ( W ′ 2 f y ) ( 单 位 : p i x e l ) \left\{\begin{array}{ll} A_{h}^{'}=2arctan(\frac{H^{'}}{2f_{x}}) \\ A_{w}^{'}=2arctan(\frac{W^{'}}{2f_{y}})\end{array} \right.(单位:pixel) ⎩⎨⎧Ah′=2arctan(2fxH′)Aw′=2arctan(2fyW′)(单位:pixel)
由上面的分析我们可以看出来,FOV补偿的重点在于找到剪裁区域的大小,也就是 W ′ W^{'} W′和 H ′ H^{'} H′
- 一般的,在给定 A h ′ A_{h}^{'} Ah′和 A w ′ A_{w}^{'} Aw′的条件下有 { H ′ = 2 f x t a n ( A h ′ 2 ) W ′ = 2 f y t a n ( A w ′ 2 ) \left\{\begin{array}{ll} H^{'}=2f_{x}tan(\frac{A_{h}^{'}}{2}) \\ W^{'}=2f_{y}tan(\frac{A_{w}^{'}}{2})\end{array} \right. {H′=2fxtan(2Ah′)W′=2fytan(2Aw′)
- 还有一种方式就是直接给出另一个相机的视场计算公式:
- 设目标相机的图像大小为 W t ∗ H t W_{t}*H_{t} Wt∗Ht
- 像素焦距为 f x t f_{xt} fxt和 f y t f_{yt} fyt
- 视场角为 A h t A_{ht} Aht和 A w t A_{wt} Awt
- 计算公式为 { A h t = 2 a r c t a n ( H t 2 f x t ) A w t = 2 a r c t a n ( W t 2 f y t ) ( 单 位 : p i x e l ) \left\{\begin{array}{ll} A_{ht}=2arctan(\frac{H_{t}}{2f_{xt}}) \\ A_{wt}=2arctan(\frac{W_{t}}{2f_{yt}})\end{array} \right.(单位:pixel) {Aht=2arctan(2fxtHt)Awt=2arctan(2fytWt)(单位:pixel)
- 要使 { A h t = A h ′ A w t = A w ′ \left\{\begin{array}{ll} A_{ht}=A_{h}^{'}\\ A_{wt}=A_{w}^{'}\end{array} \right. {Aht=Ah′Awt=Aw′可以得到 { A h ′ = 2 a r c t a n ( H ′ 2 f x ) = 2 a r c t a n ( H t 2 f x t ) = A h t A w ′ = 2 a r c t a n ( W ′ 2 f y ) = 2 a r c t a n ( W t 2 f y t ) = A w t \left\{\begin{array}{ll} A_{h}^{'}=2arctan(\frac{H^{'}}{2f_{x}})=2arctan(\frac{H_{t}}{2f_{xt}})= A_{ht}\\ A_{w}^{'}=2arctan(\frac{W^{'}}{2f_{y}})=2arctan(\frac{W_{t}}{2f_{yt}})=A_{wt}\end{array} \right. ⎩⎨⎧Ah′=2arctan(2fxH′)=2arctan(2fxtHt)=AhtAw′=2arctan(2fyW′)=2arctan(2fytWt)=Awt
- 进而得到 { 2 a r c t a n ( H ′ 2 f x ) = 2 a r c t a n ( H t 2 f x t ) 2 a r c t a n ( W ′ 2 f y ) = 2 a r c t a n ( W t 2 f y t ) ⇒ { H ′ 2 f x = H t 2 f x t W ′ 2 f y = W t 2 f y t ⇒ { H ′ = f x f x t H t W ′ = f y f y t W t \left\{\begin{array}{ll} 2arctan(\frac{H^{'}}{2f_{x}})=2arctan(\frac{H_{t}}{2f_{xt}})\\2arctan(\frac{W^{'}}{2f_{y}})=2arctan(\frac{W_{t}}{2f_{yt}})\end{array} \right.\Rightarrow \left\{\begin{array}{ll} \frac{H^{'}}{2f_{x}}=\frac{H_{t}}{2f_{xt}}\\\frac{W^{'}}{2f_{y}}=\frac{W_{t}}{2f_{yt}}\end{array} \right.\Rightarrow \left\{\begin{array}{ll} H^{'}=\frac{f_{x}}{f_{xt}}H_{t} \\ W^{'}=\frac{f_{y}}{f_{yt}}W_{t}\end{array} \right. ⎩⎨⎧2arctan(2fxH′)=2arctan(2fxtHt)2arctan(2fyW′)=2arctan(2fytWt)⇒⎩⎨⎧2fxH′=2fxtHt2fyW′=2fytWt⇒{H′=fxtfxHtW′=fytfyWt
- 设 { λ 1 = f x f x t λ 2 = f y f y t ⇒ { H ′ = λ 1 H t W ′ = λ 2 W t \left\{\begin{array}{ll} \lambda_{1}=\frac{f_{x}}{f_{xt}} \\ \lambda_{2}=\frac{f_{y}}{f_{yt}}\end{array} \right.\Rightarrow \left\{\begin{array}{ll} H^{'}=\lambda_{1}H_{t} \\ W^{'}=\lambda_{2}W_{t}\end{array} \right. {λ1=fxtfxλ2=fytfy⇒{H′=λ1HtW′=λ2Wt
有两种特殊情况:
- 正方形像素: λ 1 = λ 2 \lambda_{1}=\lambda_{2} λ1=λ2;
- 两相机焦距相等(即 f = f t f=f_{t} f=ft): { λ 1 = f x f x t = f ∗ α f t ∗ α t = α α t λ 2 = f y f y t = f ∗ β f t ∗ β t = β β t \left\{\begin{array}{ll} \lambda_{1}=\frac{f_{x}}{f_{xt}}=\frac{f*\alpha}{f_{t}*\alpha_{t}}=\frac{\alpha}{\alpha_{t}} \\ \lambda_{2}=\frac{f_{y}}{f_{yt}}=\frac{f*\beta}{f_{t}*\beta_{t}}=\frac{\beta}{\beta_{t}}\end{array} \right. {λ1=fxtfx=ft∗αtf∗α=αtαλ2=fytfy=ft∗βtf∗β=βtβ
2.2 代码及实验结果
2.2.1 相机参数
-
实验所用到的相机:IR相机和RGB相机。
- 设IR相机内参为 K 1 = [ 640.148 0 637.217 0 640.148 367.655 0 0 1 ] K_{1}=\begin {bmatrix} 640.148&0&637.217 \\0&640.148&367.655\\0&0&1 \end{bmatrix} K1=⎣⎡640.148000640.1480637.217367.6551⎦⎤,RGB相机内参为 K 2 = [ 921.586 0 647.508 0 921.765 356.499 0 0 1 ] K_{2}=\begin {bmatrix} 921.586&0&647.508 \\0&921.765&356.499\\0&0&1 \end{bmatrix} K2=⎣⎡921.586000921.7650647.508356.4991⎦⎤
- 原始分辨率都为1280×720
- IR相机的视场更大,因此需要进行FOV补偿
-
计算补偿后的图像宽和高
- 利用 { H ′ = f x f x t H t W ′ = f y f y t W t \left\{\begin{array}{ll} H^{'}=\frac{f_{x}}{f_{xt}}H_{t} \\ W^{'}=\frac{f_{y}}{f_{yt}}W_{t}\end{array} \right. {H′=fxtfxHtW′=fytfyWt
- 其中 H t = 720 H_{t}=720 Ht=720, W t = 1280 W_{t}=1280 Wt=1280,结合相机内参得到
- { H ′ = f x f x t H t = 640.148 921.586 ∗ 720 = 500 W ′ = f y f y t W t = 640.148 921.765 ∗ 1280 = 890 \left\{\begin{array}{ll} H^{'}=\frac{f_{x}}{f_{xt}}H_{t}=\frac{640.148}{921.586}*720=500 \\ W^{'}=\frac{f_{y}}{f_{yt}}W_{t}=\frac{640.148}{921.765}*1280=890\end{array} \right. {H′=fxtfxHt=921.586640.148∗720=500W′=fytfyWt=921.765640.148∗1280=890
2.2.2 代码
# -*- coding:utf-8 -*-
"""
@FileName :ROI.py
@Time :2022/4/28 9:13
@Author :Jiayu
"""
import cv2
if __name__ == "__main__":
src = cv2.imread("../IR/IR1_0.png", 1)
# 复制原图
proimage0 = src.copy()
x = 195
y = 110
w = 890
h = 500
# 在图像绘制ROI区域
cv2.rectangle(img=src, pt1=(x, y), pt2=(x + w, y + h), color=(0, 0, 255), thickness=2)
cv2.imshow("roi", src)
# 进行裁剪
ImageROI = proimage0[y:y + h, x:x + w]
cv2.imshow("ImageROI", ImageROI)
cv2.imwrite("../IR//IR1ROI.png", ImageROI)
cv2.waitKey(0)
cv2.destroyAllWindows()
2.2.3 实验结果
-
- 可以发现IR图像的视场明显大于RGB图像
-
- 可以发现经过补偿后的两幅图像视场是一致的。
3. Resolution补偿
一个标准的立体对要实现分辨率一致,那么就要进行分辨率补偿以达到分辨率一致的效果,采用的方法是图像上下采样,这里以图像上采样为例,将上述FOV补偿后的图像进行Resolution补偿。
- 分辨率补偿采用的是图像上采样方法,将裁剪后的图像进行上采样到1280*720
- 采用双三次插值或者Lanczos插值
代码:
# -*- coding:utf-8 -*-
"""
@FileName :reSize.py
@Time :2022/4/28 10:08
@Author :Jiayu
"""
import numpy as np
import cv2
if __name__ == "__main__":
'''
resize(src, dsize, dst=None, fx=None, fy=None, interpolation=None)
第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可。
第二个参数,OutputArray类型的dst,输出图像,当其非零时,有着dsize(第三个参数)的尺寸,或者由src.size()计算出来。
第三个参数,Size类型的dsize,输出图像的大小;如果它等于零,由下式进行计算:
dsize=Size(round(fx*src.cols),round(fy*src.rows))
其中,dsize,fx,fy都不能为0。
第四个参数,double类型的fx,沿水平轴的缩放系数,有默认值0,且当其等于0时,由下式进行计算:
(double)dsize.width/src.cols
第五个参数,double类型的fy,沿垂直轴的缩放系数,有默认值0,且当其等于0时,由下式进行计算:
(double)dsize.height/src.rows)
第六个参数,int类型的interpolation,用于指定插值方式,默认为INTER_LINEAR(线性插值)。
可选的插值方式如下:
INTER_NEAREST - 最近邻插值
INTER_LINEAR - 线性插值(默认值)
INTER_AREA - 区域插值(利用像素区域关系的重采样插值)
INTER_CUBIC –三次样条插值(超过4×4像素邻域内的双三次插值)
INTER_LANCZOS4 -Lanczos插值(超过8×8像素邻域的Lanczos插值)
若要缩小图像,一般情况下最好用CV_INTER_AREA来插值,
而若要放大图像,一般情况下最好用CV_INTER_CUBIC(效率不高,慢,不推荐使用)或CV_INTER_LINEAR(效率较高,速度较快,推荐使用)。
'''
img = cv2.imread("../IR/IR1ROI.png", -1)
'''-1:原图 0:灰度图 1:彩色图'''
height, width = img.shape[:2]
# 缩小图像
# size = (int(width * 0.5), int(height * 0.5))
# shrink = cv2.resize(img, size, interpolation=cv2.INTER_AREA)
# 放大图像
fx = 1280/890
fy = 720/500
# enlarge = cv2.resize(img, (0, 0), fx=fx, fy=fy, interpolation=cv2.INTER_CUBIC)
enlarge = cv2.resize(img, (0, 0), fx=fx, fy=fy, interpolation=cv2.INTER_LANCZOS4)
print(enlarge.shape[:2])
# 显示
cv2.imshow("src", img)
#cv2.imshow("shrink", shrink)
cv2.imshow("enlarge", enlarge)
cv2.imwrite("../IR/IR1Upsampling.png", enlarge)
original=cv2.imread("../IR/IR1ROI.png", -1)
# cv2.imshow("difference", cv2.applyColorMap(cv2.subtract(enlarge, original), cv2.COLORMAP_JET))
cv2.waitKey(0)
cv2.destroyAllWindows()
4. 参考文献
Shin H, Sohn K. Asymmetric stereo imaging system for portable electronic devices[J]. Optical Engineering, 2012, 51(4): 043201. DOI:10.1117/1.OE.51.4.043201.