0%

Python相机等效焦距转换

摘要

用于转换 相机胶片 大小变化时的 等效焦距.


Python实现代码

CV大法好, 拷走就能用(

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# coding=utf-8
"""
Created by MineClever to convert camera film size
"""

from math import atan, sqrt

class MathCamFovConvert (object):
AngleToRad = 0.017453292519943295
RadToAngle = 57.29577951308232

@classmethod
def calcFovFormHeightWidth(cls, w, h, focusDist, bRadian=False):
# type: (float, float, float, bool) -> tuple[float,float, float]
"""
input :w = FilmWidth(mm), h = FilmHeight(mm), focusDist(mm) = Focus Distance, bRadian -> if return radian value.
return : tuple(HFov, VFov, DFov)

"""
dx = focusDist
cx= w /2
cy = h /2
dy = sqrt(cx*cx + cy*cy)

DFovHalf = atan(dy/dx)
DFov = DFovHalf * 2
HFov = atan(cx/dx) * 2
VFov = atan(cy/dx) * 2

if not bRadian:
HFov *= cls.RadToAngle
VFov *= cls.RadToAngle
DFov *= cls.RadToAngle

return (HFov, VFov, DFov)

@classmethod
def calcFocusDistSameLook (cls, oriW, oriH, tarW, tarH, oriFocusDist, bLockHFov=True, bRadian= False):
# type:(float ,float, float, float, float, bool, bool)->tuple[float, float, float]
"""
calcFocusDistSameLook calculate a new HFov, VFov, Focus Distance


Arguments:
oriW -- origin width of film back size ;
oriH -- origin height of film back size ;
tarW -- target new width of film back size ;
tarH -- target new height of film back size;
oriFocusDist -- origin focal distance to film back ;

Keyword Arguments:
bLockHFov -- use origin HFov as reference (default: {True})
bRadian -- return value as radian one (default: {False})

Returns:
return new HFov, new VHFov , new focal distance to film back as a tuple
"""
oriDx = oriFocusDist
oriCx = oriW / 2
oriCy = oriH / 2
# oriDy = sqrt(oriCx * oriCx + oriCy * oriCy)

oriHFovHalf = atan(oriCx / oriDx) # 1/2 HFov
oriVFovHalf = atan(oriCy / oriDx) # 1/2 VFov

newCx = tarW / 2
newCy = tarH / 2


# NOTE: We should keep one fov sticked at least
if bLockHFov : # NOTE: change cy only
# NOTE: newCx / tan(HFov/2[angle]) -> new focus distance
newDx = newCx / (oriCx / oriDx)

# NOTE: Generate new VFov
newVFovHalf = atan(newCy / newDx) # type: float
newVFov = newVFovHalf * 2
newHFov = oriHFovHalf * 2
else: # NOTE: change cx only
# NOTE: newCy / tan(VFov/2[angle]) -> new focus distance
newDx = newCy / (oriCy / oriDx)

# NOTE: Generate new HFov
newHFovHalf = atan(newCx / newDx) # type: float
newHFov = newHFovHalf * 2
newVFov = oriVFovHalf * 2

# NOTE : convert to angle
if not bRadian:
newHFov *= cls.RadToAngle
newVFov *= cls.RadToAngle

return (newHFov, newVFov, newDx)

实现原理

Img_01

IMG_02

Convert

歡迎關注我的其它發布渠道