Оценка позы с помощью SolvePNP - PullRequest
0 голосов
/ 11 февраля 2020

Я пытаюсь найти позу нескольких покадровых камер, которые выходят на ледник на Аляске. Пока что все предполагаемые позы были крайне неточными. Единицами, которые я использую для координат реального мира, являются UTM (Восток / Север) и высота. Я считаю, что моя проблема заключается в ошибке единиц или несоответствии мировых координат координатам изображения.

Вот что у меня есть для фокусного расстояния и наземного контроля:

Фокус: 5740,0 пикселей

Мир: [3.93610609e + 05 6.69557833e + 06 7.82287000e + 02] Изображение: [479. 2448.]

Мир: [3.93506713e + 05 6.69585564e + 06 9.61337000e + 02] Изображение: [164. 1398.]

Мир: [3.94569509e + 05 6.69555068e + 06 6.21075000e + 02] Изображение: [2812. 3853.]

Мир: [3.97774e + 05 6.69986e + 06 1.64200e + 03] Изображение: [6310. 1398.]

self.tve c = (393506.713,6695855.641,961.337) self.rve c = (np.radians (0), np.radians (0), np.radians (15) ))

def estimatePose(self):
    print("Estimating Pose for ", str(self.instance),"\n")
    _,self.rvec,self.tvec,_ = cv2.solvePnPRansac(self.worldGCP,self.imgGCP,self.cameraMatrix,iterationsCount=10000,distCoeffs=None,rvec=self.rvec,tvec=self.tvec,useExtrinsicGuess=1)
    self.R = np.zeros((3,3))
    cv2.Rodrigues(self.rvec,self.R)
    angle = np.degrees(self.rotationMatrixToEulerAngles(self.R))
    self.R = np.append(self.R,self.tvec,1)
    self.world2img = self.cameraMatrix@self.R

def rotationMatrixToEulerAngles(self, R) :

    sy = math.sqrt(R[0,0] * R[0,0] +  R[1,0] * R[1,0])
    singular = sy < 1e-6
    if  not singular :
        x = math.atan2(R[2,1] , R[2,2])
        y = math.atan2(-R[2,0], sy)
        z = math.atan2(R[1,0], R[0,0])
    else :
        x = math.atan2(-R[1,2], R[1,1])
        y = math.atan2(-R[2,0], sy)
        z = 0
    return np.array([x, y, z])



def extract_metadata(self):
    self.metaData = {}
    exif_info = self.image._getexif()
    if exif_info:
        print("Found Meta Data!","\n")
        for (tag, value) in exif_info.items():
            tagname = TAGS.get(tag,tag)
            self.metaData[tagname] = value
        self.focal_length = int(self.metaData['FocalLength'][0]/self.metaData['FocalLength'][1])*self.imagew/35.9
        print("Focal :", np.round(self.focal_length), " pixels")
        self.cameraMatrix = np.array([[self.focal_length,0,self.imagew/2],[0,self.focal_length,self.imageh/2],[0,0,1]])

Вот мои результаты: поза (поворот на север в восточном направлении):

(4221680.42,2006518.54, -4807966, 83,96, -47,243,34,061)

1 Ответ

0 голосов
/ 11 февраля 2020

Чтобы использовать solvePnPRansa c, необходимо предварительно выполнить калибровку камеры. Калибровка камеры даст вам матрицу камеры и коэффициенты искажения камеры. Я вижу, что вы просто передаете как нулевой массив как коэффициенты искажения. Без калибровки камеры вы не получите никакой точности от оценки позы. Go к документации OpenCV для калибровки камеры .

Как только вы откалибруете свою камеру, вы сможете использовать матрицу камеры и коэффициенты искажения для convertPnPRansa c.

Вы упомянули, что у вас есть фокусное расстояние, но насколько оно точно ? откуда ты это взял? Кроме того, вы, кажется, предполагаете, что оптический центр находится в центре изображения, но это не всегда так.

...