Forum

Author Topic: How can I compute the area that a camera is covering?  (Read 17617 times)

nickponline

  • Newbie
  • *
  • Posts: 38
    • View Profile
How can I compute the area that a camera is covering?
« on: July 29, 2014, 01:50:10 AM »
Hey Alexey!


For each camera, I am looking to compute the coordinates of quad of what that camera can see on the ground. Is this information (in latitude and longitude) and if not how do I compute it?


Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 13211
    • View Profile
Re: How can I compute the area that a camera is covering?
« Reply #1 on: July 29, 2014, 06:20:55 AM »
Hello nickponline,

You need to intersect the vectors going through camera center and each image corner with the reconstructed surface.
Best regards,
Alexey Pasumansky,
Agisoft LLC

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 13211
    • View Profile
Re: How can I compute the area that a camera is covering?
« Reply #2 on: July 29, 2014, 09:39:14 AM »
Actually we have a sample script that outputs the coordinates of the "footprint" borders of the image frame projected on the reconstructed surface.

If you have any questions regarding the script, please let me know, but I assume that you can easily adopt the code to your task.

Code: [Select]
#compatibility - PhotoScan Professional v 1.0.4

import time
import PhotoScan

def cross(a, b):
result = PhotoScan.Vector([a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y *b.x])
return result

print("Script started")

cam_index = PhotoScan.app.getInt("Input camera index (starting from zero): ")
save_path = PhotoScan.app.getSaveFileName("Specify output file:")

t0 = time.time()
file = open(save_path, "wt")

doc = PhotoScan.app.document
chunk = doc.activeChunk
model = chunk.model
faces = model.faces
vertices = model.vertices

camera = chunk.photos[cam_index]
print(camera) #camera label

step = 100 #bigger value - faster processing.
steps = list(zip(list(range(0, camera.width - 1, step)), [0]*((camera.width - 1)// step)))
steps.extend( list(zip([camera.width - 1]*((camera.height - 1) // step), list(range(0, camera.height - 1, step)))) )
steps.extend( list(zip(list(range((camera.width - 1), 0, -step)), [camera.height - 1]*((camera.width - 1)// step))))
steps.extend( list(zip([0]*((camera.height - 1) // step), list(range(camera.height - 1, 0, -step)))) )

for x,y in steps:

point = PhotoScan.Vector([x, y])
point = camera.calibration.unproject(point)
point = camera.transform.mulv(point)
vect = point
p = PhotoScan.Vector(camera.center)

for face in faces:

v = face.vertices

E1 = PhotoScan.Vector(vertices[v[1]].coord - vertices[v[0]].coord)
E2 = PhotoScan.Vector(vertices[v[2]].coord - vertices[v[0]].coord)
D = PhotoScan.Vector(vect)
T = PhotoScan.Vector(p - vertices[v[0]].coord)
P = cross(D, E2)
Q = cross(T, E1)

result = PhotoScan.Vector([Q * E2, P * T, Q * D]) / (P * E1)

if (0 < result[1]) and (0 < result[2]) and (result[1] + result[2] <= 1):
t = (1 - result[1] - result[2]) * vertices[v[0]].coord
u = result[1] * vertices[v[1]].coord
v_ = result[2] * vertices[v[2]].coord

res = chunk.transform.mulp(u + v_ + t)
res = chunk.crs.project(res)

file.write("{:>04d}".format(x + 1) + "\t" + "{:04d}".format(y + 1) + "\t" + "{:.4f}".format(res[0]) + "\t" + "{:.4f}".format(res[1]) + "\t" + "{:.4f}".format(res[2]) + "\n")
#face.selected = True
break #finish when the first intersection is found


file.close()
t1 = time.time()
t1 -= t0
t1 = float(t1)
print("Script finished in " + "{:.2f}".format(t1) + " seconds.")
Best regards,
Alexey Pasumansky,
Agisoft LLC

nickponline

  • Newbie
  • *
  • Posts: 38
    • View Profile
Re: How can I compute the area that a camera is covering?
« Reply #3 on: July 30, 2014, 12:26:02 AM »
Thanks are camera.width and camera.height the sensor width and height of the camera?

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 13211
    • View Profile
Re: How can I compute the area that a camera is covering?
« Reply #4 on: August 13, 2014, 03:59:30 PM »
Hello nickponline,

camera.width and camera.height are actually the resolution of image (in pixels).
Best regards,
Alexey Pasumansky,
Agisoft LLC

AerRob

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: How can I compute the area that a camera is covering?
« Reply #5 on: January 23, 2015, 07:08:23 PM »
Hello Alexey,

when I start the python program PhotoScan crashes, continue to perform the procedure but not outcome.
Where am I wrong? I insert the size of the camera in the listing (camera.width, camera.height)  and the name of the output file during its execution (..."Specify output file:"... , that is : test.txt). What else should I enter ? ???

Thank You

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 13211
    • View Profile
Re: How can I compute the area that a camera is covering?
« Reply #6 on: January 24, 2015, 12:12:52 AM »
Hello AerRob,

The script is for version 1.0.4, so it need to be modified for the version 1.1.0.

I'll check it a little bit later, but from what I see now:
doc.activeChunk -> doc.chunk
camera.width -> camera.sensor.width
camera.height -> camera.sensor.height
chunk.transform -> chunk.transform.matrix
Best regards,
Alexey Pasumansky,
Agisoft LLC

AerRob

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: How can I compute the area that a camera is covering?
« Reply #7 on: January 26, 2015, 05:28:21 PM »
Hello Alexey.
i have the same version of photoscan (1.0.4) but......the program don't give me any solution.
Can i test the program in the new version of photoscan, with the changes.

Thanks for the reply
Rob

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 13211
    • View Profile
Re: How can I compute the area that a camera is covering?
« Reply #8 on: January 26, 2015, 06:03:18 PM »
Hello Rob,

You can update PhotoScan to the actual version free of charge. You license key is valid for all version up to 1.9.x.

Note that script requires the model to be generated first.
Best regards,
Alexey Pasumansky,
Agisoft LLC

AerRob

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: How can I compute the area that a camera is covering?
« Reply #9 on: January 26, 2015, 06:32:04 PM »
Hello Alexey,

i have update photoscan and my workflow is arrived at the 3d model.
Now i have run the py program but the new error is appear that is:
......in <module>
    camera = chunk.photos[cam_index]
AttributeError: 'PhotoScan.Chunk' object has no attribute 'photos'.

Thanks again.
Rob

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 13211
    • View Profile
Re: How can I compute the area that a camera is covering?
« Reply #10 on: January 26, 2015, 06:42:24 PM »
Hello Rob,

Please try this one:
Code: [Select]
#compatibility - PhotoScan Professional v 1.1.0
#
#requires: 1) georeferenced chunk, 2) reconstructed mesh

import time
import PhotoScan

def cross(a, b):
result = PhotoScan.Vector([a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y *b.x])
return result

print("Script started")

cam_index = PhotoScan.app.getInt("Input camera index (starting from zero): ")
save_path = PhotoScan.app.getSaveFileName("Specify output file:")

t0 = time.time()
file = open(save_path, "wt")

doc = PhotoScan.app.document
chunk = doc.chunk
model = chunk.model
faces = model.faces
vertices = model.vertices

camera = chunk.cameras[cam_index]
sensor = camera.sensor
print(camera) #camera label

step = 100 #bigger value - faster processing.
steps = list(zip(list(range(0, sensor.width - 1, step)), [0]*((sensor.width - 1)// step)))
steps.extend( list(zip([sensor.width - 1]*((sensor.height - 1) // step), list(range(0, sensor.height - 1, step)))) )
steps.extend( list(zip(list(range((sensor.width - 1), 0, -step)), [sensor.height - 1]*((sensor.width - 1)// step))))
steps.extend( list(zip([0]*((sensor.height - 1) // step), list(range(sensor.height - 1, 0, -step)))) )

for x,y in steps:

point = PhotoScan.Vector([x, y])
point = sensor.calibration.unproject(point)
point = camera.transform.mulv(point)
vect = point
p = PhotoScan.Vector(camera.center)

for face in faces:

v = face.vertices

E1 = PhotoScan.Vector(vertices[v[1]].coord - vertices[v[0]].coord)
E2 = PhotoScan.Vector(vertices[v[2]].coord - vertices[v[0]].coord)
D = PhotoScan.Vector(vect)
T = PhotoScan.Vector(p - vertices[v[0]].coord)
P = cross(D, E2)
Q = cross(T, E1)

result = PhotoScan.Vector([Q * E2, P * T, Q * D]) / (P * E1)

if (0 < result[1]) and (0 < result[2]) and (result[1] + result[2] <= 1):
t = (1 - result[1] - result[2]) * vertices[v[0]].coord
u = result[1] * vertices[v[1]].coord
v_ = result[2] * vertices[v[2]].coord

res = chunk.transform.matrix.mulp(u + v_ + t)
res = chunk.crs.project(res)

file.write("{:>04d}".format(x + 1) + "\t" + "{:04d}".format(y + 1) + "\t" + "{:.4f}".format(res[0]) + "\t" + "{:.4f}".format(res[1]) + "\t" + "{:.4f}".format(res[2]) + "\n")
#face.selected = True
break #finish when the first intersection is found


file.close()
t1 = time.time()
t1 -= t0
t1 = float(t1)
print("Script finished in " + "{:.2f}".format(t1) + " seconds.")
Best regards,
Alexey Pasumansky,
Agisoft LLC

AerRob

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: How can I compute the area that a camera is covering?
« Reply #11 on: January 28, 2015, 05:24:02 PM »
Hello Alexey,

thanks for the new script, i can test it.

P.S. in my script i had forgotten to enter one command

Thanks again
Rob

markallan

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: How can I compute the area that a camera is covering?
« Reply #12 on: March 31, 2015, 04:34:17 PM »
Hi,

AerRob, did you manage to use this script?

I don't receive an error message when using the second script here (I received the same '...object has no attribute...' message with the first script), but Photoscan crashes two/three minutes after trying to run the second.

Currently running Photoscan v1.1.4 with a small image set (35 images, 5 GPS markers), 48.6 mill points in dense cloud and 9.7 mill faces on the resolved model.

I would be most grateful if you could suggest anything.

Mark

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 13211
    • View Profile
Re: How can I compute the area that a camera is covering?
« Reply #13 on: March 31, 2015, 04:37:17 PM »
Hello Mark,

Could you please try the script on the decimated model first (for example 50 000 - 100 000 polygons) and report if PhotoScan still crashes?

And have you submitted the crash report?
Best regards,
Alexey Pasumansky,
Agisoft LLC

markallan

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: How can I compute the area that a camera is covering?
« Reply #14 on: March 31, 2015, 04:53:03 PM »
Hi Alexey,

Thank you for the advice - decimating the mesh to 50,000 polygons has worked. Must be time for a better machine!

Many thanks,

Mark