如何计算FOV?

发布于 2025-01-27 02:33:40 字数 6268 浏览 2 评论 0原文

因此,我有一个板倾斜系统,顶部有喷枪,压力很大,因此我可以将机器人放在至少1.5米的距离处。我目前已经将坐标标准化了xy,我可以在相机上可视化

现在我想将这些坐标转换为真实的帆布,并让泛块朝向它们并最终喷洒。这两个伺服器具有0至180度,但喷枪位于倾斜的顶部90。我正在跟随这个答案 https://stackoverflow.com/a/44269392/444269392/13475623

lx = (2 * canvasXpoint / canvasW - 1) * np.tan(fovX / 2)
ly = (-2 * canvasYpoint / canvasH + 1) * np.tan(fovY / 2) 
lz = 100

tx = np.cos(pan) * np.cos(tilt) * lx - np.cos(tilt) * np.sin(pan) * ly - np.sin(tilt) * lz
ty = np.sin(pan) * lx + np.cos(pan) * ly
tz = np.cos(pan) * np.sin(tilt) * lx - np.sin(pan) * np.sin(tilt) * ly + np.cos(tilt) * lz

tilt = abs(np.arctan2(tz, tx) )*180 /np.pi
pan  = abs(np.arcsin(ty / np.sqrt(tx*tx + ty*ty + tz*tz))) *180 /np.pi

他特别要求使用Fovx和fovy,但我不知道如何放置,而fovx和fovy与canvas Plus Z的中心相同?哪个给出机器人位置?

这是整个代码:

import numpy as np
import random
import cv2

rect = (0,0,0,0)
startPoint = False
endPoint = False

def on_mouse(event,x,y,flags,params):

    global rect,startPoint,endPoint

    # get mouse click
    if event == cv2.EVENT_LBUTTONDOWN:

        if startPoint == True and endPoint == True:
            startPoint = False
            endPoint = False
            rect = (0, 0, 0, 0)

        if startPoint == False:
            rect = (x, y, 0, 0)
            startPoint = True
        elif endPoint == False:
            rect = (rect[0], rect[1], x, y)
            endPoint = True

cap = cv2.VideoCapture(0)
waitTime = 50

#Reading the first frame
(grabbed, frame) = cap.read()

# create a numpy array with coordinates, dtype= np.uint32
points = np.array([
    [0.3791454386035252, 0.5089704263689607], [0.4983802415059109, 0.4865878212776629], [0.4191061040406586, 0.4890729258496474], [0.48898375092596835, 0.6904554156787046], [0.41117320428962, 0.6855686449973655], [0.48969027909831686, 0.8806483247709954], [0.4096722346480175, 0.8725103831012889], [0.45146556567120294, 0.216198952126905], [0.6304876750748412, 0.1994776546413951], [0.6406976694235704, 0.1861724655606558], [0.6199918357274865, 0.18561325370105788], [0.6525936779272056, 0.201758477474465], [0.6013198509477334, 0.20041966221830415], [0.6683290543094758, 0.29699362669473495], [0.5645238852104717, 0.3113999818240313], [0.6545654774178274, 0.49620430200480303], [0.5898070573107588, 0.49659117464889346], [0.6592482998457356, 0.6834740545963035], [0.5840631897032319, 0.6828527784533074], [0.6408640096147972, 0.8299668209407426], [0.5829181988101784, 0.8173392725052692], [0.6197806290284397, 0.30050890733295843], [0.8252923243905792, 0.23409826375167195], [0.835683753646597, 0.2185883280832016], [0.8131540844750428, 0.21904862499113367], [0.8506741192799976, 0.2279991219170517], [0.7959142481709739, 0.22725381616179272], [0.8733570624656342, 0.3256920048853457], [0.7652207837892534, 0.3239122878098148], [0.893097550288673, 0.44273291363944955], [0.7346131146711571, 0.4430594635999311], [0.902709244982588, 0.5343829401117663], [0.8520378940615836, 0.543215423861057], [0.7842126810888624, 0.5430821914771806], [0.8496391467917583, 0.7170072127563635], [0.7934480818135997, 0.7157067918591926], [0.8415470663986131, 0.8790693270711738], [0.7969306654944098, 0.8786970205344115], [0.8191112469834433, 0.32444646417244244], [0.4544294400182521, 0.10802826838116084], [0.4652589441860643, 0.09470838455219986], [0.44184697991125976, 0.09401847354478254], [0.4784184639521475, 0.1113126386155105], [0.42270482157448985, 0.10977393520172159], [0.5101597581790689, 0.21719483055184013], [0.39370939342390643, 0.21645334444157344], [0.3703281257159549, 0.34746637604116004]], np.float64)

while(cap.isOpened()):

    (grabbed, frame) = cap.read()

    cv2.namedWindow('frame')
    cv2.setMouseCallback('frame', on_mouse)    
    panarr=[]
    tiltarr=[]

    #drawing rectangle

    if startPoint == True:
        cv2.circle(frame, (rect[0], rect[1]), 2,(255, 0, 255), 2)
    if startPoint == True and endPoint == True:
        
        cv2.rectangle(frame, (rect[0], rect[1]), (rect[2], rect[3]), (255, 0, 255), 2)
        
        w = rect[2] - rect[0]
        h = rect[3] - rect[1]

        canvasW = 120
        canvasH = 90
        distanceZ = 100
        
        #position machine    
        screenXCenter = (rect[0] + rect[2]) / 2
        screenYCenter = (rect[1] + rect[3]) / 2

        pan = tilt = 90

        servoXcentrepoint = canvasW / 2 
        servoYcentrepoint = canvasH / 2 

        # fov
        fovX =  np.arctan((canvasW * canvasH )/distanceZ)
        
        for x, y in points:
           
            screenX = (x * w) + rect[0] #- differencesqrx
            screenY = (y * h) + rect[1] #- differencesqry

            cv2.circle(frame,(int(screenXCenter),int(screenYCenter)),2,(255, 255, 0),2)    
            cv2.circle(frame,(int(screenX),int(screenY)),2,(255, 45, 250),2)


            canvasXpoint = (x * canvasW)
            canvasYpoint = (y * canvasH)

            # dx =  canvasXpoint - servoXcentrepoint 

            # dy =  canvasYpoint - servoYcentrepoint

            # pan = abs(np.arctan((distanceZ/dx))) * 180/np.pi
            # tilt = abs(np.arctan(distanceZ/dy)) * 180/np.pi

            lx = (2 * canvasXpoint / canvasW - 1) * np.tan(servoXcentrepoint / 2)
            ly = (-2 * canvasYpoint / canvasH + 1) * np.tan(servoYcentrepoint / 2) 
            lz = 10

            tx = np.cos(pan) * np.cos(tilt) * lx - np.cos(tilt) * np.sin(pan) * ly - np.sin(tilt) * lz
            ty = np.sin(pan) * lx + np.cos(pan) * ly
            tz = np.cos(pan) * np.sin(tilt) * lx - np.sin(pan) * np.sin(tilt) * ly + np.cos(tilt) * lz

            tilt = abs(np.arctan2(tz, tx) )*180 /np.pi
            pan  = abs(np.arcsin(ty / np.sqrt(tx*tx + ty*ty + tz*tz))) *180 /np.pi

            

          
            
            tiltarr.append(int(tilt))
            panarr.append(int(pan))
            
   

            # a = [x,y]
    
    cv2.imshow('frame',frame)
    if cv2.waitKey(1)==ord('q'):
        break
print(tiltarr)
print(panarr)

cap.release()
cv2.destroyAllWindows()

最终目标是根据每个点确定锅的角度并倾斜

So I have a pan-tilt system with an airbrush on top, the pressure is quite strong so that I can place the robot at a distance of at least 1.5 meters. I currently have normalized coordinates XY that I can visualize on my camera like this
enter image description here

Now I want to translate those coordinates to a real canvas and allow the pan-tilt to point towards them and eventually spray. The two servos have 0 to 180 degrees but the airbrush is positioned on top of the tilt at 90. So if we consider that the pan and tilt it's at 90 the airbrush points perpendicularly to the real canvas. I am following along with this answer https://stackoverflow.com/a/44269392/13475623

lx = (2 * canvasXpoint / canvasW - 1) * np.tan(fovX / 2)
ly = (-2 * canvasYpoint / canvasH + 1) * np.tan(fovY / 2) 
lz = 100

tx = np.cos(pan) * np.cos(tilt) * lx - np.cos(tilt) * np.sin(pan) * ly - np.sin(tilt) * lz
ty = np.sin(pan) * lx + np.cos(pan) * ly
tz = np.cos(pan) * np.sin(tilt) * lx - np.sin(pan) * np.sin(tilt) * ly + np.cos(tilt) * lz

tilt = abs(np.arctan2(tz, tx) )*180 /np.pi
pan  = abs(np.arcsin(ty / np.sqrt(tx*tx + ty*ty + tz*tz))) *180 /np.pi

he specifically ask to use fovx and fovy, but i have no idea how to place the, is fovx and fovy the same as the centre of the canvas plus z? which gives the robot position?

this is the entire code:

import numpy as np
import random
import cv2

rect = (0,0,0,0)
startPoint = False
endPoint = False

def on_mouse(event,x,y,flags,params):

    global rect,startPoint,endPoint

    # get mouse click
    if event == cv2.EVENT_LBUTTONDOWN:

        if startPoint == True and endPoint == True:
            startPoint = False
            endPoint = False
            rect = (0, 0, 0, 0)

        if startPoint == False:
            rect = (x, y, 0, 0)
            startPoint = True
        elif endPoint == False:
            rect = (rect[0], rect[1], x, y)
            endPoint = True

cap = cv2.VideoCapture(0)
waitTime = 50

#Reading the first frame
(grabbed, frame) = cap.read()

# create a numpy array with coordinates, dtype= np.uint32
points = np.array([
    [0.3791454386035252, 0.5089704263689607], [0.4983802415059109, 0.4865878212776629], [0.4191061040406586, 0.4890729258496474], [0.48898375092596835, 0.6904554156787046], [0.41117320428962, 0.6855686449973655], [0.48969027909831686, 0.8806483247709954], [0.4096722346480175, 0.8725103831012889], [0.45146556567120294, 0.216198952126905], [0.6304876750748412, 0.1994776546413951], [0.6406976694235704, 0.1861724655606558], [0.6199918357274865, 0.18561325370105788], [0.6525936779272056, 0.201758477474465], [0.6013198509477334, 0.20041966221830415], [0.6683290543094758, 0.29699362669473495], [0.5645238852104717, 0.3113999818240313], [0.6545654774178274, 0.49620430200480303], [0.5898070573107588, 0.49659117464889346], [0.6592482998457356, 0.6834740545963035], [0.5840631897032319, 0.6828527784533074], [0.6408640096147972, 0.8299668209407426], [0.5829181988101784, 0.8173392725052692], [0.6197806290284397, 0.30050890733295843], [0.8252923243905792, 0.23409826375167195], [0.835683753646597, 0.2185883280832016], [0.8131540844750428, 0.21904862499113367], [0.8506741192799976, 0.2279991219170517], [0.7959142481709739, 0.22725381616179272], [0.8733570624656342, 0.3256920048853457], [0.7652207837892534, 0.3239122878098148], [0.893097550288673, 0.44273291363944955], [0.7346131146711571, 0.4430594635999311], [0.902709244982588, 0.5343829401117663], [0.8520378940615836, 0.543215423861057], [0.7842126810888624, 0.5430821914771806], [0.8496391467917583, 0.7170072127563635], [0.7934480818135997, 0.7157067918591926], [0.8415470663986131, 0.8790693270711738], [0.7969306654944098, 0.8786970205344115], [0.8191112469834433, 0.32444646417244244], [0.4544294400182521, 0.10802826838116084], [0.4652589441860643, 0.09470838455219986], [0.44184697991125976, 0.09401847354478254], [0.4784184639521475, 0.1113126386155105], [0.42270482157448985, 0.10977393520172159], [0.5101597581790689, 0.21719483055184013], [0.39370939342390643, 0.21645334444157344], [0.3703281257159549, 0.34746637604116004]], np.float64)

while(cap.isOpened()):

    (grabbed, frame) = cap.read()

    cv2.namedWindow('frame')
    cv2.setMouseCallback('frame', on_mouse)    
    panarr=[]
    tiltarr=[]

    #drawing rectangle

    if startPoint == True:
        cv2.circle(frame, (rect[0], rect[1]), 2,(255, 0, 255), 2)
    if startPoint == True and endPoint == True:
        
        cv2.rectangle(frame, (rect[0], rect[1]), (rect[2], rect[3]), (255, 0, 255), 2)
        
        w = rect[2] - rect[0]
        h = rect[3] - rect[1]

        canvasW = 120
        canvasH = 90
        distanceZ = 100
        
        #position machine    
        screenXCenter = (rect[0] + rect[2]) / 2
        screenYCenter = (rect[1] + rect[3]) / 2

        pan = tilt = 90

        servoXcentrepoint = canvasW / 2 
        servoYcentrepoint = canvasH / 2 

        # fov
        fovX =  np.arctan((canvasW * canvasH )/distanceZ)
        
        for x, y in points:
           
            screenX = (x * w) + rect[0] #- differencesqrx
            screenY = (y * h) + rect[1] #- differencesqry

            cv2.circle(frame,(int(screenXCenter),int(screenYCenter)),2,(255, 255, 0),2)    
            cv2.circle(frame,(int(screenX),int(screenY)),2,(255, 45, 250),2)


            canvasXpoint = (x * canvasW)
            canvasYpoint = (y * canvasH)

            # dx =  canvasXpoint - servoXcentrepoint 

            # dy =  canvasYpoint - servoYcentrepoint

            # pan = abs(np.arctan((distanceZ/dx))) * 180/np.pi
            # tilt = abs(np.arctan(distanceZ/dy)) * 180/np.pi

            lx = (2 * canvasXpoint / canvasW - 1) * np.tan(servoXcentrepoint / 2)
            ly = (-2 * canvasYpoint / canvasH + 1) * np.tan(servoYcentrepoint / 2) 
            lz = 10

            tx = np.cos(pan) * np.cos(tilt) * lx - np.cos(tilt) * np.sin(pan) * ly - np.sin(tilt) * lz
            ty = np.sin(pan) * lx + np.cos(pan) * ly
            tz = np.cos(pan) * np.sin(tilt) * lx - np.sin(pan) * np.sin(tilt) * ly + np.cos(tilt) * lz

            tilt = abs(np.arctan2(tz, tx) )*180 /np.pi
            pan  = abs(np.arcsin(ty / np.sqrt(tx*tx + ty*ty + tz*tz))) *180 /np.pi

            

          
            
            tiltarr.append(int(tilt))
            panarr.append(int(pan))
            
   

            # a = [x,y]
    
    cv2.imshow('frame',frame)
    if cv2.waitKey(1)==ord('q'):
        break
print(tiltarr)
print(panarr)

cap.release()
cv2.destroyAllWindows()

The ultimate goal is to determine the angle for the pan and tilt based on each point

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文