主頁 >  其他 > python實作兩函式通過縮放,平移和旋轉進行完美擬合

python實作兩函式通過縮放,平移和旋轉進行完美擬合

2023-07-13 08:21:22 其他

Curve _fitting

前幾天在作業的時候接到了一個需求,希望將不同坐標系,不同角度的兩條不規則曲線,并且組成該曲線的點集數量不一致,需求是希望那個可以通過演算法的平移和旋轉搞到一個概念里最貼合,擬合態進行比較,

image-20230712151728578

這是初步將兩組資料畫到圖里的情況,和背景需求是一致的,其實從肉眼看過去左圖逆時針旋轉120度可以得到一個大致差不多的圖,

但這里存在了兩個問題:

  1. 就算搞到了同一個坐標系,一個基準點選取在哪里,影像繞著這個點旋轉才可以得到最擬合點樣子
  2. 找到基準點,判斷最擬合的標準是什么,怎么算距離

首先我們將兩圖換到一個相同坐標系下

def Convert_to_the_same_scale(xs1, ys1, xs2, ys2):
    xs1 = np.array(xs1)
    ys1 = np.array(ys1)

    xs2 = np.array(xs2)
    ys2 = np.array(ys2)

    # 減去平均值,使得資料中心化
    xs1 -= np.mean(xs1)  # 算一個平均值,最后回到0,0坐標系下
    ys1 -= np.mean(ys1)

    xs2 -= np.mean(xs2)
    ys2 -= np.mean(ys2)

    # 除以標準差,使得資料標準化
    xs1 /= np.std(xs1)
    ys1 /= np.std(ys1)

    xs2 /= np.std(xs2)
    ys2 /= np.std(ys2)


    return xs1.tolist(), ys1.tolist(), xs2.tolist(), ys2.tolist()

我們運用numpy中的函式進行了資料中心化和標準化的處理,np.std()函式是Numpy庫中的一個方法,它被用來計算陣列中元素的標準差,標準差是一種衡量資料分散程度的指標,值越大表明資料越分散,將資料點除以該數值可以統一到一個離散的程度,經過處理之后得到了以下圖樣:

image-20230712153034757

接下來就要引入一個比較熱的判斷距離的演算法DTW,DTW是指動態時間扭曲(Dynamic Time Warping)演算法,這是一種用于測量兩個可能不等長的序列之間相似度的演算法,該演算法可以找到序列之間的對齊方式,使得對齊后的總體誤差最小,

在信號處理、識別和資料挖掘領域,DTW廣泛應用于各種任務,如語音識別和手寫數字識別,它的主要優點是能夠處理時間序列的“彈性”對齊問題,即即使在時間尺度上存在變形,也能夠匹配和識別模式,

DTW 演算法的基本步驟如下:

  1. 初始化:創建一個二維矩陣,其中行數和列數分別等于兩個輸入序列的長度,將第一個元素設為 0,其余元素設為無窮大,
  2. 遞回填充:從左上角開始,計算當前位置的距離(通常是歐氏距離),并將其與左方、上方、左上方三個元素的最小值相加,結果存盤在當前位置,
  3. 尋找路徑:從右下角開始,向左上角回溯,尋找最小累計距離的路徑,這就是兩個序列之間的最佳對齊路徑,
  4. 輸出距離:回傳最后一個元素的值,即為兩個序列之間的 DTW 距離,

值得注意的是,盡管 DTW 可以很好地處理變化的速度和非線性變形,但是它對輸入序列的噪聲和例外值敏感,并且計算成本相當高,

我這兩個影像都是由幾千個點組成的,所以如果讓DTW演算法去自己360度無死角找best angle和最擬合的點的話,計算量就太大了,

所以經過一些計算,我可以先拿到兩組點的端點,將起點對齊之后,再去將一條線以另一條線為準進行旋轉,此時得到的角度可以被視作是一個范圍角度,

def get_degree(a,b,c,d):
    def get_vector_from_points(p1, p2):
        return np.array([p2[0] - p1[0], p2[1] - p1[1]])

    def dot_product(v1, v2):
        return np.dot(v1, v2)

    def cross_product(v1, v2):
        return v1[0]*v2[1] - v1[1]*v2[0]

    def length_of_vector(v):
        return np.linalg.norm(v)

    def translate_point(p, t):
        return [p[0]+t[0], p[1]+t[1]]

    def rotate_point(p, angle):
        px, py = p
        cos_theta = np.cos(angle)
        sin_theta = np.sin(angle)
        
        qx = cos_theta * px - sin_theta * py
        qy = sin_theta * px + cos_theta * py
        
        return [qx, qy]

    def align_lines(A, B, C, D):
        # Step 1: Translate
        T = get_vector_from_points(C, A)
        C_translated = translate_point(C, T)
        D_translated = translate_point(D, T)

        # Step 2: Rotate
        vAB = get_vector_from_points(A, B)
        vCD = get_vector_from_points(C_translated, D_translated)
        cos_theta = dot_product(vAB, vCD) / (length_of_vector(vAB)*length_of_vector(vCD))
        theta = np.arccos(cos_theta)
        direction = np.sign(cross_product(vAB, vCD)) 

        C_final = rotate_point(C_translated, direction*theta)
        D_final = rotate_point(D_translated, direction*theta)

        return np.degrees(direction*theta)
    degree = align_lines(a,b,c,d)
    return degree

rotate_bosch = [[BOSCH_xs[0],BOSCH_ys[0]],[BOSCH_xs[-1],BOSCH_ys[-1]]]
rotate_ego = [[EGO_xs[0],EGO_ys[0]],[EGO_xs[-1],EGO_ys[-1]]]
theta = (get_degree(rotate_ego[0],rotate_ego[1],rotate_bosch[0],rotate_bosch[1]))

tran_x = EGO_xs[0] - BOSCH_xs[0]
tran_y = EGO_ys[0] - BOSCH_ys[0]

這段代碼定義了一個名為 get_degree 的函式,其目的是計算兩條線之間的夾角,這里的引數 a,b,c,d 分別代表兩條線上的四個點,其中 ab 在一條線上,cd 在另一條線上,

下面是該函式的詳細步驟:

  1. 定義輔助函式:這些函式用于執行向量運算、平移和旋轉點等操作,
  2. 定義主要流程:在 align_lines 函式中,首先通過向量差得到平移量 T,將 cd 兩點進行平移,使得平移后的 c 點與 a 點重合;接著計算 ABCD 兩向量的夾角 theta,并確定旋轉方向 direction;最后根據 direction*theta 對平移后的 cd 進行旋轉,該函式回傳的是 theta 的度數形式,
  3. 呼叫主要流程:在 get_degree 函式中,呼叫 align_lines 函式并回傳得到的角度,

簡單來說,這段代碼就是把以 cd 為端點的線段通過平移和旋轉,讓它和以 ab 為端點的線段對齊,然后回傳這個旋轉的角度,獲取的角度就是一個比較貼合的角度,但是不是最精準的,

image-20230712154046616

此時旋轉的角度確實如我們所想,度數120度左右,效果大概是這樣,看起來還不錯,那這樣的基礎上我們再去撰寫DTW演算法就速度比較快了,Python并沒有自帶的DTW(Dynamic Time Warping)演算法,但是第三方的庫,例如fastdtwdtaidistance提供了這個演算法的實作,

使用fastdtw:

from scipy.spatial.distance import euclidean
from fastdtw import fastdtw

x = np.array([1, 2, 3, 4, 5], dtype=float)
y = np.array([2, 3, 4, 5, 6], dtype=float)

distance, path = fastdtw(x, y, dist=euclidean)

print("DTW distance: ", distance)
print("DTW path: ", path)

在上述代碼中,fastdtw函式接收兩個序列,xy,以及一個用于計算兩點之間距離的函式,這里采用歐氏距離進行計算,

使用dtaidistance:

from dtaidistance import dtw

x = np.array([1, 2, 3, 4, 5], dtype=float)
y = np.array([2, 3, 4, 5, 6], dtype=float)

distance = dtw.distance(x, y)

print("DTW distance: ", distance)

在這段代碼中,dtw.distance函式接收兩個序列,并回傳它們之間的DTW距離,

# 對第二條曲線進行旋轉,并計算與第一條曲線的DTW距離
def compute_dtw_distance(points1, points2, angle, center_point):
    rotated_points = rotate_points(points2, angle, center_point)
    distance, _ = fastdtw(points1, rotated_points, dist=euclidean)
    return distance

# 尋找最佳擬合角度
def find_best_fit(points1, points2, center_point=(0, 0), theta = 0):
    """Finds the rotation angle that gives the best fit between two sets of points."""
    angles=np.arange(theta-10, theta+10, 0.3)
    min_distance = float('inf')
    best_angle = None

    for angle in angles:
        distance = compute_dtw_distance(points1, points2, angle, center_point)

        if distance < min_distance:
            min_distance = distance
            best_angle = angle

    return best_angle, min_distance

代碼里面我們為了減輕計算量,角度區間為之前得到的theta以及 正負10度,每隔0.3度進行一次計算,然后我們再根據得到的best_angle旋轉1次獲得最后的結果,

image-20230712154950575

這樣一看,兩條線就非常的貼合了,角度也調整成了115.5度,但是老板突然跟我說有沒有可能這不是最貼合的情況(我#¥#@#@!#@$$#$@),要我把初始點不對齊也算一下,我想了一下,也做了幾組測驗,我選取了起點周圍情況0.4*0.4面積內的格點,一般情況也不會在這個范圍之外了,進行一個回圈的計算,保留做小的距離和最佳的角度

tran_x = EGO_xs[0] - BOSCH_xs[0]
tran_y = EGO_ys[0] - BOSCH_ys[0]
trans_x = np.linspace(tran_x-0.2, tran_x + 0.2, 5)
trans_y = np.linspace(tran_y-0.2, tran_y + 0.2, 5)

min_distance = float('inf')
best_angle = 0.0
best_bosch_x = []
best_bosch_y = []
start_time = time.time()
for i in trans_x:
    for j in trans_y:
        tmpx,tmpy = copy.deepcopy(BOSCH_xs), copy.deepcopy(BOSCH_ys)
        tmpx,tmpy = translate_points(tmpx,tmpy, i, j)

        ego = np.column_stack((EGO_xs, EGO_ys))
        bosch = np.column_stack((tmpx,tmpy))
        angle, distance = find_best_fit(ego,bosch,center_point=(tmpx[0],tmpy[0]),theta= theta)
        if distance < min_distance:
            min_distance = distance
            best_angle = angle
            best_bosch_x = tmpx
            best_bosch_y = tmpy
        print("此時Bosch的起點在{},{}, 平移的長度為{},{}".format(tmpx[0],tmpy[0],i,j))
        print(BOSCH_xs[0], BOSCH_ys[0])
        print("起點在{},{} 最佳角度為{}  誤差距離為{}".format(tmpx[0],tmpy[0],angle,distance))
BOSCH_xs, BOSCH_ys = rotate_points_after_DTW(best_bosch_x,best_bosch_y, best_angle)

image-20230712155402466

別說,你還真別說,上圖所示的才是最擬合狀態,角度也有微小的變化,這是根據DTW演算法得出的結果,但是我個人覺得起點對齊的時候更擬合一點,~~~

全部代碼可以聯系本菜雞!純原創!!!

本文來自博客園,作者:ivanlee717,轉載請注明原文鏈接:https://www.cnblogs.com/ivanlee717/p/17547754.html

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/557138.html

標籤:其他

上一篇:淺析華為云Astro的5大關鍵能力技術

下一篇:返回列表

標籤雲
其他(162478) Python(38274) JavaScript(25531) Java(18294) C(15241) 區塊鏈(8275) C#(7972) AI(7469) 爪哇(7425) MySQL(7296) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5876) 数组(5741) R(5409) Linux(5347) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4616) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2439) ASP.NET(2404) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) HtmlCss(1998) .NET技术(1987) 功能(1967) Web開發(1951) C++(1942) python-3.x(1918) 弹簧靴(1913) xml(1889) PostgreSQL(1883) .NETCore(1863) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • python實作兩函式通過縮放,平移和旋轉進行完美擬合

    # Curve _fitting 前幾天在作業的時候接到了一個需求,希望將不同坐標系,不同角度的兩條不規則曲線,并且組成該曲線的點集數量不一致,需求是希望那個可以通過演算法的平移和旋轉搞到一個概念里最貼合,擬合態進行比較。 ![image-20230712151728578](https://img2 ......

    uj5u.com 2023-07-13 08:21:22 more
  • 淺析華為云Astro的5大關鍵能力技術

    摘要:本文以技術方案視角,對華為云Astro低代碼平臺的一些核心功能進行簡要介紹。 背景介紹 低代碼開發基于可視化開發的概念,結合了云原生和多終端體驗技術,它可以在大多數業務場景中,幫助企業顯著的提升效率。同時為專業開發者提供了一種全新的高生產力開發方式,讓不懂代碼的人通過“拖拉拽”開發組件來完成應 ......

    uj5u.com 2023-07-13 08:21:11 more
  • 重塑未來的1課:組裝式交付新引擎——智能化低代碼平臺

    摘要:智能化低代碼必修課。 緊跟低代碼技術飛速發展——華為云Astro智能作業流驚艷HDC.Cloud 2023!企業對未來智能化組裝式交付的期待已不是空想。智能化低代碼即將重新定義傳統交付模式,密切連接AI科技與創造力。 在HDC.Cloud 2023華為云Astro分論壇,云計算大咖、行業翹楚科 ......

    uj5u.com 2023-07-13 08:20:43 more
  • 盤古大模型加持,華為云開天aPaaS加速使能千行百業應用創新

    摘要:開天aPaaS,讓優秀快速復制,支撐開發者及伙伴上好云、用好云。 本文分享自華為云社區《盤古大模型加持,華為云開天aPaaS加速使能千行百業應用創新》,作者:開天aPaaS小助手。 7月7-9日,華為開發者大會(Cloud)2023在東莞隆重召開。此次大會,華為云開天aPaaS帶來了主題演講、 ......

    uj5u.com 2023-07-13 08:19:49 more
  • Navicat Premium v16.0.6 綠色破解版

    這里版本:Navicat Premium v16.0.6.0 ,這個是綠色版,不需要安裝,啟動Navicat.exe即可用 破解工具:NavicatKeygenPatch(其它版本也能破解) 1、下載安裝檔案 鏈接:https://pan.baidu.com/s/1_9XLoqulp2EyI2H0G ......

    uj5u.com 2023-07-13 08:18:26 more
  • 華為云5大開源專案發布與更新,助力開發者實作應用創新

    摘要:華為開發者大會2023(Cloud)期間,由華為云開源主導的“5大開源專案發布與更新,多種底層能力助力開發者實作應用創新”分論壇圓滿落幕。 本文分享自華為云社區《HDC.Cloud 2023 |華為云5大開源專案發布與更新,助力開發者實作應用創新》,作者:華為云開源。 華為開發者大會2023( ......

    uj5u.com 2023-07-13 08:18:07 more
  • 北斗GPS校時器,NTP網路時鐘服務器,局域網時間統一

    北斗GPS校時器,NTP網路時鐘服務器,局域網時間統一 北斗GPS校時器,NTP網路時鐘服務器,局域網時間統一 京準電子科技官微——ahjzsz 1.1.1 該系統特點: ã系統構成簡單,實用、可靠,具有很高的性價比。 ã子鐘可以是LED數顯或模擬(指標)形式、或兩種形式的混合,數量不限,可大規模擴 ......

    uj5u.com 2023-07-13 08:17:56 more
  • GPS北斗網路時鐘同步器(衛星時鐘發生器)插卡式模組設計方案

    GPS北斗網路時鐘同步器(衛星時鐘發生器)插卡式模組設計方案 GPS北斗網路時鐘同步器(衛星時鐘發生器)插卡式模組設計方案 京準電子科技官微——ahjzsz 4.1 時間同步系統功能 時間同步系統的主要功能就是為變電站用時設備提供全站統一的時間基準。時間同步系統應以天基授時為主,地基授時為輔,逐步形 ......

    uj5u.com 2023-07-13 08:17:46 more
  • 電子表格vlookup函式使用

    vlookup是常用的輔助查找函式,但是這個函式的引數定義和解釋非常的難以理解,即使用向導也很難搞清楚哪個引數是啥意思。放到編程圈里面應該也算bad design的典型了。下面是函式的定義,每次看到這個定義都一臉懵逼: 下面對每個引數進行詳細的解釋: 查找值:一般是和查找結果在同一個sheet頁里面 ......

    uj5u.com 2023-07-13 08:17:36 more
  • LEA: Improving Sentence Similarity Robustness to Typos Using

    # LEA: Improving Sentence Similarity Robustness to Typos Using Lexical Attention Bias 論文閱讀 KDD 2023 [原文地址](https://arxiv.org/abs/2307.02912) ## Introd ......

    uj5u.com 2023-07-13 08:16:57 more