1. PTZ在惯性态时,不同视场角下的【发送】角速度和【理论响应】角速度
1.1 优化前
import numpy as np
import matplotlib. pyplot as plt
ATROffset_x = np. linspace( 0 , 60 , 120 )
y2 = ATROffset_x * 2 / 28
y4 = ATROffset_x * 4 / 28
y6 = ATROffset_x * 6 / 28
y8 = ATROffset_x * 8 / 28
y10 = ATROffset_x * 10 / 28
y12 = ATROffset_x * 12 / 28
y14 = ATROffset_x * 14 / 28
y16 = ATROffset_x * 16 / 28
y18 = ATROffset_x * 18 / 28
y20 = ATROffset_x * 20 / 28
y22 = ATROffset_x * 22 / 28
y24 = ATROffset_x * 24 / 28
y26 = ATROffset_x * 26 / 28
y28 = ATROffset_x * 28 / 28
plt. plot( ATROffset_x, y2, label= 'field angle: 2 degrees' )
plt. plot( ATROffset_x, y4, linestyle= 'dotted' , label= 'field angle: 4 degrees' )
plt. plot( ATROffset_x, y6, linestyle= '--' , label= 'field angle: 6 degrees' )
plt. plot( ATROffset_x, y8, linestyle= '-.' , label= 'field angle: 8 degrees' )
plt. plot( ATROffset_x, y10, label= 'field angle: 10 degrees' )
plt. plot( ATROffset_x, y12, linestyle= 'dotted' , label= 'field angle: 12 degrees' )
plt. plot( ATROffset_x, y14, linestyle= '--' , label= 'field angle: 14 degrees' )
plt. plot( ATROffset_x, y16, linestyle= '-.' , label= 'field angle: 16 degrees' )
plt. plot( ATROffset_x, y18, label= 'field angle: 18 degrees' )
plt. plot( ATROffset_x, y20, linestyle= 'dotted' , label= 'field angle: 20 degrees' )
plt. plot( ATROffset_x, y22, linestyle= '--' , label= 'field angle: 22 degrees' )
plt. plot( ATROffset_x, y24, linestyle= '-.' , label= 'field angle: 24 degrees' )
plt. plot( ATROffset_x, y26, linestyle= 'dotted' , label= 'field angle: 26 degrees' )
plt. plot( ATROffset_x, y28, label= 'field angle: 28 degrees' )
plt. xlabel( 'sending value[degree/second]' )
plt. ylabel( 'thertical response[degree/second]' )
plt. title( 'PTZ angular velocity: sending value & thertical response' )
handles, labels = plt. gca( ) . get_legend_handles_labels( )
plt. legend( handles[ : : - 1 ] , labels[ : : - 1 ] )
plt. grid( )
plt. show( )
1.2 优化后
import numpy as np
import matplotlib. pyplot as plt
ATROffset_x = np. linspace( 0 , 60 , 120 )
linestyles = [ '-' , 'dotted' , '--' , '-.' ,
'-' , 'dotted' , '--' , '-.' ,
'-' , 'dotted' , '--' , '-.' ,
'-' , 'dotted' ]
labels = [ f'field angle: { i} degrees' for i in range ( 2 , 30 , 2 ) ]
for i, linestyle in enumerate ( linestyles) :
y = ATROffset_x * ( i + 2 ) / 28
plt. plot( ATROffset_x, y, linestyle= linestyle, label= labels[ i] )
plt. xlabel( 'sending value[degree/second]' )
plt. ylabel( 'thertical response[degree/second]' )
plt. title( 'PTZ angular velocity: sending value & thertical response' )
handles, labels = plt. gca( ) . get_legend_handles_labels( )
plt. legend( handles[ : : - 1 ] , labels[ : : - 1 ] )
plt. grid( )
plt. show( )
2. 像素偏移与发送角速度
import numpy as np
import matplotlib. pyplot as plt
def piecewise_function ( x) :
if x > 80 : return x/ 9
elif x> 30 : return x/ 4
elif x> 10 : return x/ 1.8
elif x> 3 : return x/ 1.8
elif x> 1 : return x
else : return 0
x = np. linspace( 0 , 512 , 2000 )
y1 = [ piecewise_function( xi) for xi in x]
y2 = 2.5 * ( x** ( 0.5 ) )
points = [ ( 506.25 , piecewise_function( 506.25 ) ) ]
for point in points:
plt. plot( point[ 0 ] , point[ 1 ] , 'ro' )
plt. annotate( f'( { point[ 0 ] } , { point[ 1 ] : .2f } )' , ( point[ 0 ] , point[ 1 ] ) , textcoords= "offset points" , xytext= ( 0 , 10 ) , ha= 'center' )
plt. plot( x, y1, label= 'piecewise function' , linestyle= '-.' )
plt. plot( x, y2, label= '2.5*pow(x,0.5)' )
plt. xlabel( 'pixel offset[pixel]' )
plt. ylabel( 'sending value[degree/second]' )
plt. title( 'PTZ angular velocity: sending value & pixel offset' )
plt. grid( )
plt. legend( )
plt. show( )
3. 估算不同焦距下的目标大小
3.1 原理
【任务】:已知POD与目标之间的高度差3000m和水平距离2000m,需要解算7m*3m目标在POD观察画面中的大小 【途径】:利用视场角解算视野大小,绘制目标在POD观察画面中的大小
解算视场角大小:
fieldAngle_yaw = arctan(5.632/focalDistance)*180/Pi fieldAngle_pitch = arctan(4.224/focalDistance)*180/Pi 解算POD与目标的直线距离distance 解算视野覆盖的实际长和宽
fieldWidth = 2*tan(fieldAngle_yaw/2)/disctance fieldWidth = 2*tan(fieldAngle_pitch/2)/disctance 解算目标在视野中的比例后,可得3.2中的图像
import numpy as np
import matplotlib. pyplot as plt
from mpl_toolkits. mplot3d import Axes3D
def sphere ( u, v) :
theta = u * 2 * np. pi
phi = v * np. pi
x = np. sin( phi) * np. cos( theta)
y = np. sin( phi) * np. sin( theta)
z = np. cos( phi)
return x, y, z
def plot_rectangle_tangent_to_point ( point) :
point_normalized = point / np. linalg. norm( point)
perpendicular_vector_1 = np. cross( point_normalized, [ 1 , 0 , 0 ] )
if np. allclose( perpendicular_vector_1, [ 0 , 0 , 0 ] ) :
perpendicular_vector_1 = np. cross( point_normalized, [ 0 , 1 , 0 ] )
perpendicular_vector_1 /= np. linalg. norm( perpendicular_vector_1)
perpendicular_vector_2 = np. cross( point_normalized, perpendicular_vector_1)
perpendicular_vector_2 /= np. linalg. norm( perpendicular_vector_2)
rectangle_half_side = 0.5
rectangle_vertices = np. array( [
point_normalized + rectangle_half_side * perpendicular_vector_1 + rectangle_half_side * perpendicular_vector_2,
point_normalized - rectangle_half_side * perpendicular_vector_1 + rectangle_half_side * perpendicular_vector_2,
point_normalized - rectangle_half_side * perpendicular_vector_1 - rectangle_half_side * perpendicular_vector_2,
point_normalized + rectangle_half_side * perpendicular_vector_1 - rectangle_half_side * perpendicular_vector_2,
point_normalized + rectangle_half_side * perpendicular_vector_1 + rectangle_half_side * perpendicular_vector_2
] )
fig = plt. figure( figsize= ( 10 , 10 ) )
ax = fig. add_subplot( 111 , projection= '3d' )
ax. plot( rectangle_vertices[ : , 0 ] , rectangle_vertices[ : , 1 ] , rectangle_vertices[ : , 2 ] , color= 'r' )
ax. scatter( point[ 0 ] , point[ 1 ] , point[ 2 ] , color= 'b' , s= 50 )
point1 = point
point2 = np. array( [ 0 , 0 , 0 ] )
ax. scatter( point1[ 0 ] , point1[ 1 ] , point1[ 2 ] , color= 'r' , s= 100 )
ax. scatter( point2[ 0 ] , point2[ 1 ] , point2[ 2 ] , color= 'b' , s= 100 )
ax. plot( [ point1[ 0 ] , point2[ 0 ] ] , [ point1[ 1 ] , point2[ 1 ] ] , [ point1[ 2 ] , point2[ 2 ] ] , color= 'k' , linestyle= '--' )
fyo = ( point_normalized + rectangle_half_side * perpendicular_vector_1 + rectangle_half_side * perpendicular_vector_2 + point_normalized + rectangle_half_side * perpendicular_vector_1 - rectangle_half_side * perpendicular_vector_2) / 2
ax. scatter( fyo[ 0 ] , fyo[ 1 ] , fyo[ 2 ] , color= 'b' , s= 50 )
ax. plot( [ fyo[ 0 ] , point2[ 0 ] ] , [ fyo[ 1 ] , point2[ 1 ] ] , [ fyo[ 2 ] , point2[ 2 ] ] , color= 'k' , linestyle= '--' )
ax. plot( [ fyo[ 0 ] , point[ 0 ] ] , [ fyo[ 1 ] , point[ 1 ] ] , [ fyo[ 2 ] , point[ 2 ] ] , color= 'k' , linestyle= '--' )
u = np. linspace( 0 , 2 , 100 )
v = np. linspace( 0 , 2 , 100 )
u, v = np. meshgrid( u, v)
x, y, z = sphere( u, v)
ax. plot_surface( x, y, z, color= 'b' , alpha= 0.02 )
ax. plot( [ 0 , 1 ] , [ 0 , 0 ] , [ 0 , 0 ] , color= 'red' , linestyle= '-' , linewidth= 2 )
ax. plot( [ 0 , 0 ] , [ 0 , 1 ] , [ 0 , 0 ] , color= 'green' , linestyle= '-' , linewidth= 2 )
ax. plot( [ 0 , 0 ] , [ 0 , 0 ] , [ 0 , 1 ] , color= 'blue' , linestyle= '-' , linewidth= 2 )
ax. set_box_aspect( [ 1 , 1 , 1 ] )
ax. set_xlabel( 'X' )
ax. set_ylabel( 'Y' )
ax. set_zlabel( 'Z' )
ax. set_xticks( [ - 1 , - 0.5 , 0 , 0.5 , 1 ] )
ax. set_yticks( [ - 1 , - 0.5 , 0 , 0.5 , 1 ] )
ax. set_zticks( [ - 1 , - 0.5 , 0 , 0.5 , 1 ] )
plt. title( "Since: tan(fieldAngle/2) = (fieldWidth/2) / distance\n\nThen: fieldWidth = 2 * tan(fieldAngle/2) * distance" )
plt. show( )
point_on_sphere = np. array( [ - 0.55 , 0 , - 0.83 ] )
plot_rectangle_tangent_to_point( point_on_sphere)
3.2 绘图
POD与目标之间高度差3000m、水平距离2000m,目标尺寸7m*3m 不同焦距下,该目标在POD观察画面中的大小如图所示
import matplotlib. pyplot as plt
import matplotlib. patches as patches
import numpy as np
import math
relative_target_height = 3000
relative_target_horizontal = 2000
relative_distance = math. sqrt( relative_target_height* relative_target_height + relative_target_horizontal* relative_target_horizontal)
print ( "relative_distance: " , relative_distance)
fig, ax = plt. subplots( )
plt. title( "ROI SIZE of 7m*3m target: 3000m high & 2000m distance" )
def fd2pic ( fd) :
horizontal_draw = np. tan( math. atan( 5.632 / fd) / 2 ) * relative_distance * 2
vertical_draw = np. tan( math. atan( 4.224 / fd) / 2 ) * relative_distance * 2
rect = patches. Rectangle( ( 6 * 7 / horizontal_draw* 1024 , 14 * 3 / vertical_draw* 768 ) ,
7 / horizontal_draw* 1024 , 3 / vertical_draw* 768 , linewidth= 1 , edgecolor= 'r' , facecolor= 'none' )
ax. add_patch( rect)
ax. text( 7 * 7 / horizontal_draw* 1024 + 20 , 14 * 3 / vertical_draw* 768 , "fd: {:.2f}" . format ( fd) , fontsize= 12 , color= 'r' )
for i in range ( 9 ) :
fd2pic( max ( 40 * i, 10.59 ) )
plt. xlim( 0 , 1024 )
plt. ylim( 0 , 768 )
plt. xticks( [ 0 , 1024 ] )
plt. yticks( [ 0 , 768 ] )
plt. show( )