Forum

Author Topic: pairs in Metashape.Tasks.MatchPhotos doesn't work  (Read 4043 times)

JyunPingJhan

  • Newbie
  • *
  • Posts: 13
    • View Profile
pairs in Metashape.Tasks.MatchPhotos doesn't work
« on: December 04, 2024, 06:44:16 PM »
Hi
I am trying to use custom pairs for imagr matching, and use the latest 2.1.3 version.
It works if simply run script with the following code,

 
Code: [Select]


doc = Metashape.app.document
chunk = doc.chunk
cameras = [camera for camera in chunk.cameras if camera.reference.location is not None]
pairs = []
for i, cam1 in enumerate(cameras):
        for j, cam2 in enumerate(cameras):
            if i >= j:
                continue
           
                pairs.append((cam1, cam2))


chunk.matchPhotos(pairs=pairs, keypoint_limit=3000, tiepoint_limit=3000, generic_preselection=False, reference_preselection=False)




However, when I try to utilize network processing, it only works if pairs is not assigned.
Paris are as same as locol processing.
I do monitor the processing output, and found that only keypoints of first photo are detected.

can you help to debug it ? 

2024-12-04 23:34:04 Using device: NVIDIA GeForce RTX 4070 Ti SUPER, 66 compute units, free memory: 15079/16375 MB, compute capability 8.9
2024-12-04 23:34:04   driver/runtime CUDA: 12050/10010
2024-12-04 23:34:04   max work group size 1024
2024-12-04 23:34:04   max work item sizes [1024, 1024, 64]
2024-12-04 23:34:04 [GPU] photo 0: 3000 points
2024-12-04 23:34:04 points detected in 0.532 sec
2024-12-04 23:34:04 processing finished in 0.682 sec


Code: [Select]
pairs = custom_pairs(chunk) 
         
match_photos_task = Metashape.Tasks.MatchPhotos()
match_photos_task.keypoint_limit = 3000
match_photos_task.tiepoint_limit = 3000
match_photos_task.downscale = 1
match_photos_task.generic_preselection = False
match_photos_task.reference_preselection = False
match_photos_task.pairs = pairs
match_photos_task.filter_mask = True
match_photos_task.mask_tiepoints = False
match_photos_task.filter_stationary_points = False
match_photos_task.guided_matching = False
match_photos_task.reset_matches = True

         
network_task = match_photos_task.toNetworkTask(chunk)
           
tasks.append(network_task)

project_path = doc.path 
batch_id = network_client.createBatch(project_path, tasks)
   

network_client.setBatchPaused(batch_id, False)


Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 15420
    • View Profile
Re: pairs in Metashape.Tasks.MatchPhotos doesn't work
« Reply #1 on: December 05, 2024, 02:22:44 PM »
Hello JyunPingJhan,

Does it help, if you modify the pair assignment line to the following?
Code: [Select]
  pairs.append((cam1.key, cam2.key))
Best regards,
Alexey Pasumansky,
Agisoft LLC

JyunPingJhan

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: pairs in Metashape.Tasks.MatchPhotos doesn't work
« Reply #2 on: December 05, 2024, 04:22:05 PM »
Hi Alexey

Thanks your replies.

Actually, I have tried pairs.append((cam1.key, cam2.key)) , it don't work on network processing, either 

Meanwhile, if I run with local processing with     pairs.append((i, j))   ,it only detects features on part of images, and varied if I recreate the chunk.

Only pairs.append((cam1.key, cam2.key)) works on chunk.matchPhotos(....)

I have thousands of images and need custom paris to make sure the connection are corrected, but I still can't make it run with network processing.

Hope there are solutions.

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 15420
    • View Profile
Re: pairs in Metashape.Tasks.MatchPhotos doesn't work
« Reply #3 on: December 05, 2024, 05:46:16 PM »
Hello JyunPingJhan,

Can you please share the updated code that works as expected in local mode? And please confirm whether you are using the same script for Run Script task started in network mode?
Best regards,
Alexey Pasumansky,
Agisoft LLC

JyunPingJhan

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: pairs in Metashape.Tasks.MatchPhotos doesn't work
« Reply #4 on: December 05, 2024, 05:56:46 PM »
Hi Alexey


Here is code for local processing, it works fine.
Code: [Select]
import Metashape
import math

# 計算兩點之間的平面距離
def calculate_distance(point1, point2):
    """計算兩個點之間的平面距離 (忽略 Z 軸)。"""
    return (point1.x - point2.x) ** 2 + (point1.y - point2.y) ** 2

# 根據平面坐標 (E, N) 自訂建立 pairs
def custom_pairs(chunk):
    """根據相機標籤與距離條件建立自訂 pairs 列表。"""
    cameras = [camera for camera in chunk.cameras if camera.reference.location is not None]  # 確保參考位置存在
    pairs = []

    for i, cam1 in enumerate(cameras):
        loc1 = cam1.reference.location
        for j, cam2 in enumerate(cameras):
            if i >= j:  # 避免重複計算和自配對
                continue
           
            # 獲取相機參考位置
           
            loc2 = cam2.reference.location
            distance = calculate_distance(loc1, loc2)           
           
            # 配對規則
            if cam1.label.endswith("PL") and distance <= 25:
                pairs.append((cam1.key, cam2.key))
            elif cam1.label.endswith("PR") and distance <= 25:
                pairs.append((cam1.key, cam2.key))
            elif cam1.label.endswith("SL"):
                if cam2.label.endswith("PL") and distance <= 25:
                    pairs.append((cam1.key, cam2.key))
                elif cam2.label.endswith("PR") and distance <= 25:
                    pairs.append((cam1.key, cam2.key))
                elif cam2.label.endswith("SL") and distance <= 225:
                    pairs.append((cam1.key, cam2.key))
                elif cam2.label.endswith("SR") and distance <= 225:
                    pairs.append((cam1.key, cam2.key))
            elif cam1.label.endswith("SR"):
                if cam2.label.endswith("PL") and distance <= 25:
                    pairs.append((cam1.key, cam2.key))
                elif cam2.label.endswith("PR") and distance <= 25:
                    pairs.append((cam1.key, cam2.key))
                elif cam2.label.endswith("SL") and distance <= 225:
                    pairs.append((cam1.key, cam2.key))
                elif cam2.label.endswith("SR") and distance <= 225:
                    pairs.append((cam1.key, cam2.key))
                                 
    return pairs

# 主程式
doc = Metashape.app.document
chunk = doc.chunk


# 呼叫自訂配對函數
pairs = custom_pairs(chunk)
print(len(pairs))
print(pairs[0])

chunk.matchPhotos(pairs=pairs, keypoint_limit=5000, tiepoint_limit=5000, generic_preselection=False, reference_preselection=False)

# 執行相機對齊
chunk.alignCameras()



And the following is code for network processing.

Code: [Select]

import Metashape
import tkinter as tk
from tkinter import messagebox
import subprocess
import math

# 計算兩點之間的平面距離
def calculate_distance(point1, point2):
    """計算兩個點之間的平面距離 (忽略 Z 軸)。"""
    return (point1.x - point2.x) ** 2 + (point1.y - point2.y) ** 2

# 根據平面坐標 (E, N) 自訂建立 pairs
def custom_pairs(chunk):
    """根據相機標籤與距離條件建立自訂 pairs 列表。"""
    cameras = [camera for camera in chunk.cameras if camera.reference.location is not None]  # 確保參考位置存在
    pairs = []

    for i, cam1 in enumerate(cameras):
        loc1 = cam1.reference.location
        for j, cam2 in enumerate(cameras):
            if i >= j:  # 避免重複計算和自配對
                continue
           
            # 獲取相機參考位置
            loc2 = cam2.reference.location
            distance = calculate_distance(loc1, loc2)           
           
            # 配對規則
            if "PL" in cam1.label and distance <= 25:
                pairs.append((cam1.key, cam2.key))
            elif "PR" in cam1.label and distance <= 25:
                pairs.append((cam1.key, cam2.key))
            elif "SL" in cam1.label:
                if "PL" in cam2.label and distance <= 25:
                    pairs.append((cam1.key, cam2.key))
                elif "PR" in cam2.label and distance <= 25:
                    pairs.append((cam1.key, cam2.key))
                elif "SL" in cam2.label and distance <= 225:
                    pairs.append((cam1.key, cam2.key))
                elif "SR" in cam2.label and distance <= 225:
                    pairs.append((cam1.key, cam2.key))
            elif "SR" in cam1.label:
                if "PL" in cam2.label and distance <= 25:
                    pairs.append((cam1.key, cam2.key))
                elif "PR" in cam2.label and distance <= 25:
                    pairs.append((cam1.key, cam2.key))
                elif "SL" in cam2.label and distance <= 225:
                    pairs.append((cam1.key, cam2.key))
                elif "SR" in cam2.label and distance <= 225:
                    pairs.append((cam1.key, cam2.key))
                                 
    return pairs


def align_batch():
   
    root = tk.Tk()
    root.withdraw()
    response = messagebox.askquestion("確認", "確認執行Batch Align")
    if response == 'no':
        return

    doc = Metashape.app.document
    doc.save()
    if not doc.chunks:
        Metashape.app.messageBox("No chunks in the project!")
        return

    # 創建 NetworkClient 來與伺服器通信
    network_client = Metashape.NetworkClient()
    server_ip = "140.118.119.121"  # 用實際伺服器的 IP 替換
    network_client.connect(server_ip)

    # 任務列表
    tasks = []
    enabled_chunks = []

    # 遍歷所有啟用的 chunk,為每個 chunk 創建 MatchPhotos 任務
    for chunk in doc.chunks:
        if chunk.enabled:
            enabled_chunks.append(chunk)
           
            pairs = custom_pairs(chunk)  # 呼叫自訂配對函數
            #print(pairs[5])
           
            # 創建 MatchPhotos 任務
            match_photos_task = Metashape.Tasks.MatchPhotos()
            match_photos_task.pairs = pairs
            match_photos_task.keypoint_limit = 5000
            match_photos_task.tiepoint_limit = 5000
            match_photos_task.downscale = 1
            match_photos_task.generic_preselection = False
            match_photos_task.reference_preselection = False
            match_photos_task.filter_mask = True
            match_photos_task.mask_tiepoints = False
            match_photos_task.filter_stationary_points = False
            match_photos_task.guided_matching = False
            match_photos_task.reset_matches = True
           
            # 轉換為 NetworkTask 並加入任務列表
            network_task = match_photos_task.toNetworkTask(chunk)
            tasks.append(network_task)
           
   
   
    ## 創建 AlignCameras 任務,並將其加入任務列表
    align_cameras_task = Metashape.Tasks.AlignCameras()
    align_cameras_task.reset_alignment = True  # 可以設置其他 AlignCameras 參數
    align_cameras_task.adaptive_fitting = False

    network_task_align = align_cameras_task.toNetworkTask(enabled_chunks)
    tasks.append(network_task_align)
       
    ## 使用 createBatch 提交所有任務
    project_path = doc.path  # 取得當前專案的路徑
    batch_id = network_client.createBatch(project_path, tasks)  # 提交批次處理
   
    # 開始執行批次處理
    network_client.setBatchPaused(batch_id, False)
   
    Metashape.app.quit()
    metashape_executable = r"C:\Program Files\Agisoft\Metashape Pro\metashape.exe"  # 請根據實際路徑修改
    subprocess.Popen([metashape_executable, project_path])
   
Metashape.app.addMenuItem("PRIDE/B. Batch Align", align_batch)


« Last Edit: December 08, 2024, 07:31:12 AM by JyunPingJhan »

JyunPingJhan

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: pairs in Metashape.Tasks.MatchPhotos doesn't work
« Reply #5 on: December 15, 2024, 02:55:42 PM »
Hi Alexey

Have you checked the API? Are there kinds of bugs in pairs settings?

 I have tried several setting and still can't make it work through network processing.

 

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 15420
    • View Profile
Re: pairs in Metashape.Tasks.MatchPhotos doesn't work
« Reply #6 on: December 16, 2024, 05:01:27 PM »
Hello JyunPingJhan,

We were able to reproduce the problem and will try to fix it in one of the upcoming updates. Unfortunately, it appears that the fix is not trivial, thus it was not included to 2.1.4 update.
Best regards,
Alexey Pasumansky,
Agisoft LLC

JyunPingJhan

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: pairs in Metashape.Tasks.MatchPhotos doesn't work
« Reply #7 on: December 17, 2024, 05:32:03 AM »
Hi Alexey

Thanks for the help, looking forward to see the latest update.

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 15420
    • View Profile
Re: pairs in Metashape.Tasks.MatchPhotos doesn't work
« Reply #8 on: December 17, 2024, 03:58:49 PM »
Will be fixed in 2.1.5 and next 2.2.0 update.
Best regards,
Alexey Pasumansky,
Agisoft LLC