1. 程式人生 > 其它 >python 使用散點擬合角度

python 使用散點擬合角度

技術標籤:python計算機視覺

與一般的擬合直線不同,擬合角度的目的是獲得直線與水平軸的夾角,即下圖中的a:
在這裡插入圖片描述
常用的最小二乘法無法用於上圖左邊的情況,更進一步的直線擬合方法同樣不適用:
https://blog.csdn.net/liyuanbhu/article/details/50866802
所以採用一種較簡單的混合法來計算:

import numpy as np
import math

def linear_regression(x, y): 
    """
    擬合直線
    x, y: list()
    return:  b, k  y = a0 + k*x
    """
N = len(x) sumx = sum(x) sumy = sum(y) sumx2 = sum(x**2) sumxy = sum(x*y) A = np.mat([[N, sumx], [sumx, sumx2]]) b = np.array([sumy, sumxy]) return np.linalg.solve(A, b) def angle_regression(x, y): """ 擬合角. x-y計算一次, y-x計算一次, 求哪個誤差小,如果x-y誤差小,直接返回angle, 如果y-x誤差小, 計算沿45°對稱的角 return: 弧度 """
# 垂直的情況 if x.min() == x.max(): return math.pi / 2. # x-y b1, k1 = linear_regression(x, y) # y-x b2, k2 = linear_regression(y, x) # 計算誤差 err1 = 0 err2 = 0 for i in np.arange(x.shape[0]): err1 += abs(k1*x[i] - y[i] + b1) / math.sqrt(k1**2 + 1) err2 +=
abs(k2*y[i] - x[i] + b2) / math.sqrt(k2**2 + 1) if err1 <= err2: return (math.atan(k1) + 2*math.pi) % (2*math.pi) else: # 計算沿45°對稱的角 return (math.pi/2. - math.atan(k2) + 2*math.pi) % (2*math.pi) if __name__ == "__main__": x = np.array([1, 1, 2, 1, 1]) y = np.array([1, 2, 3, 4, 5]) print(angle_regression(x, y))