利用Metashape Python API 脚本将像素坐标反投影至点云坐标 全部代码详细教程

620 阅读1分钟

0前言:

因项目需要,需要将在相片上的窗户角点反投影至在Metashape所重建的点云上。

参考Transfering 2D-image markers (x/y-pixel) to 3D-real-world-coordinates

1代码:

在Metashape Pro中使用Python脚本 需要先导入你的工程文件

#input file format:
#camera name, x-Position in Pixel, Y-position in Pixel
#
#output file format:
#marker label, x-world, y-world, z-world

import Metashape, os

def read_2D_export_3D(chunk, path):
	if not path:
		print("Invalid path, script aborted")
		return 0
	if not os.path.isfile(path):
		print("Invalid path, script aborted")
		return 0
	if not chunk:
		print("Empty document, script aborted")
		return 0
	cameras = [camera for camera in chunk.cameras if camera.transform and camera.type == Metashape.Camera.Type.Regular] #list of aligned cameras
	if not cameras:
		print("Empty chunk, script aborted")
		return 0
	if not chunk.dense_cloud:
		print("Dense cloud is missing, script aborted")
		return 0
		
	surface = chunk.dense_cloud
	crs = chunk.crs
	T = chunk.transform.matrix
	input = open(path, "rt")
	if os.path.splitext(path)[1]:
		out_path = os.path.splitext(path)[0] + "_out.txt"
	else:
		out_path = path + "_out.txt"
	output = open(out_path, "wt")
	
	lines = input.readlines()
	for line in lines:
		if len(line) < 4:
			continue
		label, x_coord, y_coord = line.strip().split(",",3)
		x_coord = float(x_coord)
		y_coord = float(y_coord)
		
		for camera in cameras:
			if camera.label == label:
				marker = chunk.addMarker()
				ray_origin = camera.unproject(Metashape.Vector([x_coord, y_coord, 0]))
				ray_target = camera.unproject(Metashape.Vector([x_coord, y_coord, 1]))
				coord = crs.project(T.mulp(surface.pickPoint(ray_origin, ray_target)))
				marker.label = label
				marker.projections[camera] =  Metashape.Marker.Projection(Metashape.Vector([x_coord,y_coord]), True)
				marker.reference.location = coord
				marker.reference.enabled = True
				output.write("{:s},{:.6f},{:.6f},{:.6f}\n".format(marker.label, coord.x, coord.y, coord.z))
				break
		output.flush()
	output.close()
	input.close()


	print("Script finished")
	return 1

chunk = Metashape.app.document.chunk
path = Metashape.app.getOpenFileName("Select the file with 2D marker coordinates:", filter="(*.txt) Text files;; (*.*) All files")

read_2D_export_3D(chunk, path)

其中,输入的文件格式应该如下:分别为相片名,像素x坐标,像素y坐标

DSC01578.JPG,100.12,200.223
DSC02579.JPG,234.13,300.245
DSC02580.JPG,300.14,456.289
DSC03581.JPG,500.15,600.267

2代码解释:

1)代码中的chunk是指工程文件中的chunk,chunk.cameras是指chunk下的Cameras,代码中的camera.label是指相片的名称。

2)代码中的chunk.dense_cloud,是指在工程文件下生成的密集匹配点云

3反投影结果如下: