Перевести CircleFitByKasa в MATLAB на Python

#python #arrays #matlab #numpy

#python #массивы #matlab #numpy

Вопрос:

Уважаемые все: у меня нет опыта работы с MATLAB, но есть некоторый опыт работы с Python. Я пытаюсь перевести функцию MATLAB CircleFitByKasa на Python.

CircleFitByKasa Функция имеет следующий код:

 function Par = CircleFitByKasa(XY)
%--------------------------------------------------------------------------
%  
%     Simple algebraic circle fit (Kasa method)
%      I. Kasa, "A curve fitting procedure and its error analysis",
%      IEEE Trans. Inst. Meas., Vol. 25, pages 8-14, (1976)
%
%     Input:  XY(n,2) is the array of coordinates of n points x(i)=XY(i,1), y(i)=XY(i,2)
%
%     Output: Par = [a b R] is the fitting circle:
%                           center (a,b) and radius R
%
%--------------------------------------------------------------------------
P = [XY ones(size(XY,1),1)]  [XY(:,1).^2   XY(:,2).^2];
Par = [P(1)/2 , P(2)/2 , sqrt((P(1)^2 P(2)^2)/4 P(3))];
end   %  CircleFitByKasa
 

Я перевел два кода на Python для одной и той же функции MATLAB, и коды Python показаны ниже.

 import numpy as np
import os
import sys
import open3d as o3d
import math

pcd = o3d.io.read_point_cloud('C:\Users\wilso\python\datasets\PCD\rail_pcd_points.pcd')
XY=np.asarray(pcd.points)[:,:2]
def circiebykasa1(XY):
    P=np.linalg.solve(np.concatenate((XY, np.ones((len(XY),1))), axis=1), (XY[:,0]**2   XY[:,1]**2))
    Par=(P[0]/2 , P[1]/2 , np.sqrt((np.power(P[0],2) np.power(P[1],2))/4 P[2]))
    return Par

def circiebykasa2(XY):
    P=np.linalg.lstsq(np.concatenate((XY, np.ones((len(XY),1))), axis=1),(np.power(XY[:,0],2)   np.power(XY[:,1],2)))
    Par=(P[0]/2 , P[1]/2 , np.sqrt((np.power(P[0],2) np.power(P[1],2))/4 P[2]))
    return Par
    
 

Переведенный код Python может выполняться без какой-либо обратной трассировки, но результат кажется мне немного запутанным. Согласно комментарию в коде MATLAB, функция MATLAB должна возвращать центр (a,b) и радиус r подогнанной окружности; поэтому я предполагаю, что a , b , и r должны быть одиночными числами (поскольку входной массив (XY) находится в 2D). Однако обе мои переведенные функции Python показывают мне следующий результат.

 (array([ -49.44680817,  -65.29780001, -974.3765832 ]),
 array([1.47859859e 09]),
 array([1.47859859e 09, 1.47859859e 09, 1.47859859e 09]))
 

Согласно результату, мой параметр a и r являются 3D-координатами, которые не имеют особого смысла. Не мог бы кто-нибудь, пожалуйста, любезно взглянуть и сообщить мне, где я ошибся?

Ответ №1:

Функция numpy.linalg.lstsq() возвращает больше, чем просто решение методом наименьших квадратов.

Я думаю, что изменение этого:

 Par=(P[0]/2 , P[1]/2 , np.sqrt((np.power(P[0],2) np.power(P[1],2))/4 P[2]))
 

для этого:

 Par=(P[0][0]/2 , P[0][1]/2 , np.sqrt((np.power(P[0][0],2) np.power(P[0][1],2))/4 P[0][2]))
 

должно это исправить. Но я не могу проверить, так как у меня нет ваших данных.