Forum

Author Topic: Fail to load calibration  (Read 5635 times)

Yoann Courtois

  • Sr. Member
  • ****
  • Posts: 316
  • Engineer in Geodesy, Cartography and Surveying
    • View Profile
Fail to load calibration
« on: October 31, 2019, 02:30:00 PM »
Hello !

I struggle with personal calibration loading. Here is my code :

Code: [Select]
chunk=Metashape.app.document.chunk

# importing cameras from only one sensor

my_sensor = chunk.sensors[0]
my_sensor.type = Metashape.Sensor.Type.Fisheye
my_sensor.user_calib = Metashape.Calibration()
my_sensor.calibration.load("my_path/my_calibration.xml", format='xml')
It return False ...

I've checked everything (file existence, sensor name, sensor type, etc.).
I've able to set my_sensor.fixed = True, but not able to load my calibration ...

Thanks for your help
--
Yoann COURTOIS
R&D Engineer in photogrammetric process and mobile application
Lyon, FRANCE
--

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14813
    • View Profile
Re: Fail to load calibration
« Reply #1 on: October 31, 2019, 04:03:41 PM »
Hello Yoann,

Please try the following:
Code: [Select]
my_sensor = chunk.sensors[0]
my_sensor.type = Metashape.Sensor.Type.Fisheye
my_calib = Metashape.Calibration()
my_calib.load("my_path/my_calibration.xml", format='xml')
my_sensor.user_calib = my_calib
also make sure that the calibration file that you are loading also has "fisheye" type.
Best regards,
Alexey Pasumansky,
Agisoft LLC

Yoann Courtois

  • Sr. Member
  • ****
  • Posts: 316
  • Engineer in Geodesy, Cartography and Surveying
    • View Profile
Re: Fail to load calibration
« Reply #2 on: October 31, 2019, 04:18:14 PM »
It's indeed a fisheye type calibration file.
my_calib.load() return also False ...
--
Yoann COURTOIS
R&D Engineer in photogrammetric process and mobile application
Lyon, FRANCE
--

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14813
    • View Profile
Re: Fail to load calibration
« Reply #3 on: October 31, 2019, 05:11:47 PM »
Hello Yoann,

Which version of Metashape you are using?

You might need to use "format=Metashape.CalibrationFormatXML" instead of string parameter value.

However, are there any errors related to this operation?
Best regards,
Alexey Pasumansky,
Agisoft LLC

Yoann Courtois

  • Sr. Member
  • ****
  • Posts: 316
  • Engineer in Geodesy, Cartography and Surveying
    • View Profile
Re: Fail to load calibration
« Reply #4 on: October 31, 2019, 05:36:42 PM »
Hello Alexey,

I'm currently using Metashape 1.5.0, but regarding change log, nothing changed until 1.5.5.
I'm gonna upgrade on 1.6.0 when it will be released, but most of my code will need changes at that point !

Trying "format=Metashape.CalibrationFormatXML" return me an AttributeError: module 'Metashape' has no attribute 'CalibrationFormatXML'
--
Yoann COURTOIS
R&D Engineer in photogrammetric process and mobile application
Lyon, FRANCE
--

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14813
    • View Profile
Re: Fail to load calibration
« Reply #5 on: October 31, 2019, 06:56:39 PM »
Hello Yoann,

I'm not observing issues with the following code in 1.5.5:
Code: [Select]
n [4]: my_sensor = chunk.sensors[0]
my_sensor.type = Metashape.Sensor.Type.Frame
my_calib = Metashape.Calibration()
my_calib.load(path, format="xml")
my_sensor.user_calib = my_calib
The calibration data is loaded to the Initial values for the sensor.
Best regards,
Alexey Pasumansky,
Agisoft LLC

Yoann Courtois

  • Sr. Member
  • ****
  • Posts: 316
  • Engineer in Geodesy, Cartography and Surveying
    • View Profile
Re: Fail to load calibration
« Reply #6 on: November 04, 2019, 11:58:01 AM »
Ok, after some debug and retry, I guess some old code meddled in my work.
This code indeed works well in 1.5.0 too.

Thanks for your help.
Regards
--
Yoann COURTOIS
R&D Engineer in photogrammetric process and mobile application
Lyon, FRANCE
--

Yoann Courtois

  • Sr. Member
  • ****
  • Posts: 316
  • Engineer in Geodesy, Cartography and Surveying
    • View Profile
Re: Fail to load calibration
« Reply #7 on: April 14, 2021, 05:02:58 PM »
Dear Alexey,

We recently updated to 1.7.1 version, but we face up to a new problem about calibration import.
We use following code :

Code: [Select]
precalibation = Metashape.Calibration()
precalibation.load(path="mycalib.xml", format=Metashape.CalibrationFormatXML)

But we got a RunTimeError :

Code: [Select]
RuntimeError: Can't load calibration
Nevertheless, our variable "precalibation" has got mycalib.xml parameters... So why have we got this error ? That's strange...

Regards
--
Yoann COURTOIS
R&D Engineer in photogrammetric process and mobile application
Lyon, FRANCE
--

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14813
    • View Profile
Re: Fail to load calibration
« Reply #8 on: April 14, 2021, 05:55:54 PM »
Hello Yoann,

Can you post here the contents of the XML file or attach it to the reply?
Best regards,
Alexey Pasumansky,
Agisoft LLC

Yoann Courtois

  • Sr. Member
  • ****
  • Posts: 316
  • Engineer in Geodesy, Cartography and Surveying
    • View Profile
Re: Fail to load calibration
« Reply #9 on: April 14, 2021, 06:12:44 PM »
Hello Alexey,

Here it is !
--
Yoann COURTOIS
R&D Engineer in photogrammetric process and mobile application
Lyon, FRANCE
--

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14813
    • View Profile
Re: Fail to load calibration
« Reply #10 on: April 14, 2021, 07:00:26 PM »
Hello Yoann,

It seems that API doesn't yet support Fisheye calibration import. It will be fixed in the next 1.7.3 update.
Best regards,
Alexey Pasumansky,
Agisoft LLC

Yoann Courtois

  • Sr. Member
  • ****
  • Posts: 316
  • Engineer in Geodesy, Cartography and Surveying
    • View Profile
Re: Fail to load calibration
« Reply #11 on: April 15, 2021, 03:51:48 PM »
Actually, after some more tests, the calibration import works !

We managed to catch the RunTimeError exception and then we were able to set our sensor.user_calib with our imported calibration.
It looks the exception doesn't affect the import.

Let me know if it could be fixed one day so that we could removed the exception catch.

Regards
--
Yoann COURTOIS
R&D Engineer in photogrammetric process and mobile application
Lyon, FRANCE
--

mihapajo123

  • Newbie
  • *
  • Posts: 8
    • View Profile
Re: Fail to load calibration
« Reply #12 on: May 10, 2021, 09:01:07 PM »
Hello i need help :)

I'm interested in how to write in the script that I'm using a fisheye camera and that I already have the internal parameters given. These internal parameters, it would make sense to always ask me when I run the script.

Thank you very much for your help




MY SKRIPT:


import Metashape
import time, math, os, glob

TYPES = ["DNG", "JPG", "JPEG", "TIF", "TIFF"] #supported file types/extensions

def calc_reprojection(chunk):
   point_cloud = chunk.point_cloud
   points = point_cloud.points
   npoints = len(points)
   projections = chunk.point_cloud.projections
   err_sum = 0
   num = 0
   maxe = 0

   point_ids = [-1] * len(point_cloud.tracks)
   #point_errors = dict()
   for point_id in range(0, npoints):
      point_ids[points[point_id].track_id] = point_id

   for camera in chunk.cameras:
      if not camera.transform:
         continue
      for proj in projections[camera]:
         track_id = proj.track_id
         point_id = point_ids[track_id]
         if point_id < 0:
            continue
         point = points[point_id]
         if not point.valid:
            continue
         error = camera.error(point.coord, proj.coord).norm() ** 2
         err_sum += error
         num += 1
         #if point_id not in point_errors.keys():
         #   point_errors[point_id] = [error]
         #else:
         #   point_errors[point_id].append(error)
         #if error > maxe: maxe = error
           
   reproj = math.sqrt(err_sum / num)
   return (reproj) #return (sigma, point_errors, maxe)

def autoprocess():

   #project_path = "D:/Project/project.psx"
   project_path = Metashape.app.getSaveFileName("Specify project save filename:", filter = "Metashape Project (*.psx)")
   if not project_path:
      Metashape.app.messageBox("Invalid project path")
      return 0
   image_folder_path = Metashape.app.getExistingDirectory("Specify the folder with images:")
   if not image_folder_path:
      Metashape.app.messageBox("Invalid image folder path")
      return 0
   reference_path = Metashape.app.getOpenFileName("Specify reference file with targes:", filter = "CSV files (*.txt *.csv)")
   if not reference_path:
      Metashape.app.messageBox("Invalid reference file path")
      return 0
     
   doc = Metashape.Document()
   doc.save(project_path)
   doc = Metashape.app.document #open the same project in applicaiton GUI
   doc.open(project_path)
   
   chunk = doc.addChunk()
   chunk.crs = Metashape.CoordinateSystem('LOCAL_CS["Local Coordinates (m)",LOCAL_DATUM["Local Datum",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]]]') #set crs to local coordinates (m)
   
   image_list = [photo for photo in glob.iglob(image_folder_path + "\\*.*", recursive = False) if os.path.isfile(photo) and os.path.splitext(photo)[1][1:].upper() in TYPES]
   chunk.addPhotos(image_list) #add images
   doc.save()
   
   
   #align photos
   chunk.matchPhotos(downscale = 4, generic_preselection = True, keypoint_limit = 50000, tiepoint_limit = 4000, guided_matching = True)   #we recommend downscale = 1, guided_matchinf = False
   chunk.alignCameras(adaptive_fitting = False) #we recommend adaptive_fitting = False
   doc.save()
   
   #gradual selection Reconstruction uncertainty
   #criterion = True
   #n = 0
   #while criterion:
   #   n += 1
   #   TARGET_PERCENT = 50
    #
   #   f = Metashape.PointCloud.Filter()
   #   f.init(chunk, criterion = Metashape.PointCloud.Filter.ReconstructionUncertainty)
   #   list_values = f.values
   #   list_values_valid = list()
   #   for i in range(len(list_values)):
   #      if points.valid:
   #         list_values_valid.append(list_values)
   #   list_values_valid.sort()
   #   target = int(len(list_values_valid) * TARGET_PERCENT / 100)
   #   threshold = list_values_valid[target]
   #   if threshold < 50:
   #      f.selectPoints(threshold)
   #      f.removePoints(threshold)
   #   else:
   #      f.selectPoints(50)
   #      f.removePoints(50)
   #   chunk.optimizeCameras(fit_f = True, fit_cx = True, fit_cy = True, fit_k1 = True, fit_k2 = True, fit_k3 = True, fit_p1 = True, fit_p2 = True, fit_b1 = True, fit_b2 = True, fit_corrections = False, tiepoint_covariance = True)
   #   
   #   reproj =  calc_reprojection(chunk)
   #   if (float(chunk.meta['OptimizeCameras/sigma0']) >= 1) or (reproj >= 3.0):
   #      criterion = True
   #   else:
   #      criterion = False
   #   if (threshold <= 10) and (n > 2):
   #      criterion = False
   #doc.save()
   #
   ##gradual selection Projection accuracy
   #criterion = True
   #n = 0
   #while criterion:
   #   n += 1
   #   TARGET_PERCENT = 50
    #
   #   f = Metashape.PointCloud.Filter()
   #   f.init(chunk, criterion = Metashape.PointCloud.Filter.ProjectionAccuracy)
   #   list_values = f.values
   #   list_values_valid = list()
   #   for i in range(len(list_values)):
   #      if points.valid:
   #         list_values_valid.append(list_values)
   #   list_values_valid.sort()
   #   target = int(len(list_values_valid) * TARGET_PERCENT / 100)
   #   threshold = list_values_valid[target]
   #   if threshold < 2:
   #      f.selectPoints(2)
   #      f.removePoints(2)
   #   elif threshold < 3:
   #      f.selectPoints(threshold)
   #      f.removePoints(threshold)
   #   else:
   #      f.selectPoints(3)
   #      f.removePoints(3)
   #   chunk.optimizeCameras(fit_f = True, fit_cx = True, fit_cy = True, fit_k1 = True, fit_k2 = True, fit_k3 = True, fit_p1 = True, fit_p2 = True, fit_b1 = True, fit_b2 = True, fit_corrections = False, tiepoint_covariance = True)
   #   
   #   if (threshold <= 2) and (n > 2):
   #      criterion = False
   #doc.save()
   #
   ##modify tie point accuracy
   #
   #chunk.tiepoint_accuracy = 0.1
   #criterion = True
   #n = 0
   #while criterion:
   #   n += 1
   #   chunk.optimizeCameras(fit_f = True, fit_cx = True, fit_cy = True, fit_k1 = True, fit_k2 = True, fit_k3 = True, fit_p1 = True, fit_p2 = True, fit_b1 = True, fit_b2 = True, fit_corrections = False, tiepoint_covariance = True)
   #   reproj =  calc_reprojection(chunk)
   #   if (float(chunk.meta['OptimizeCameras/sigma0']) >= 1) or (reproj >= 3.0):
   #      criterion = True
   #   else:
   #      criterion = False
   #   if (n > 5):
   #      criterion = False
   #doc.save()

   ####

   #detect markers
   chunk.detectMarkers(target_type = Metashape.CircularTarget12bit, tolerance = 50)
   chunk.importReference(reference_path, format = Metashape.ReferenceFormatCSV, columns = "nxyz", delimiter = ",") #import coordinates from file, delimiter = "comma"
   chunk.marker_location_accuracy = Metashape.Vector([0.002, 0.002, 0.002])
   chunk.optimizeCameras(fit_f = True, fit_cx = True, fit_cy = True, fit_k1 = True, fit_k2 = True, fit_k3 = True, fit_k4 = True, fit_p1 = True, fit_p2 = True, fit_b1 = True, fit_b2 = True, fit_corrections = False, tiepoint_covariance = True) #we recommend fit_corrections = False
   chunk.updateTransform()
   doc.save()
   
   ###add scalebars???
   
   ##gradual selection Reprojction Error
   #criterion = True
   #n = 0
   #while criterion:
   #   n += 1
   #   TARGET_PERCENT = 90
    #
   #   f = Metashape.PointCloud.Filter()
   #   f.init(chunk, criterion = Metashape.PointCloud.Filter.ReprojectionError)
   #   list_values = f.values
   #   list_values_valid = list()
   #   for i in range(len(list_values)):
   #      if points.valid:
   #         list_values_valid.append(list_values)
   #   list_values_valid.sort()
   #   target = int(len(list_values_valid) * TARGET_PERCENT / 100)
   #   threshold = list_values_valid[target]
   #   if threshold >= 3:
   #      f.selectPoints(threshold)
   #      f.removePoints(threshold)
   #   else:
   #      f.selectPoints(3)
   #      f.removePoints(3)
   #   chunk.optimizeCameras(fit_f = True, fit_cx = True, fit_cy = True, fit_k1 = True, fit_k2 = True, fit_k3 = True, fit_p1 = True, fit_p2 = True, fit_b1 = True, fit_b2 = True, fit_corrections = False, tiepoint_covariance = True)
   #   
   #   reproj =  calc_reprojection(chunk)
   #   if (float(chunk.meta['OptimizeCameras/sigma0']) >= 1) or (reproj >= 3.0):
   #      criterion = True
   #   else:
   #      criterion = False
   #   if (threshold < 3) and (n > 3):
   #      criterion = False
   #doc.save()
   ####
   
   chunk.resetRegion()
   #build dense cloud
   chunk.buildDepthMaps(downscale = 4, filter_mode = Metashape.AggressiveFiltering)
   doc.save()
   chunk.buildDenseCloud(point_colors = True, point_confidence = True)
   doc.save()
   
   ##build mesh
   #chunk.depth_maps = None
   #chunk.buildDepthMaps(downscale = 4, filter_mode = Metashape.MildFiltering)
   #doc.save()
   #chunk.buildModel(surface_type = Metashape.Arbitrary, source_data = Metashape.DataSource.DenseCloudData, face_count = Metashape.HighFaceCount, vertex_colors = True)
   #doc.save()
   #
   ##build texture
   #chunk.buildUV(mapping_mode = Metashape.GenericMapping, texture_size = 8192)
   #chunk.buildTexture(blending_mode = Metashape.MosaicBlending, texture_size = 8192, fill_holes = True, ghosting_filter = True, texture_type = Metashape.Model.TextureType.DiffuseMap)
   #doc.save()
   
   #export
   export_base_path = os.path.dirname(doc.path)
   try:
      os.mkdir(export_base_path + "/REZULTATI")
   except:
      print("Can't create directory")
      return 0
   
   if chunk.dense_cloud:
      chunk.exportPoints(path = export_base_path + "/REZULTATI/1_OBLAK_TOCK.las", format = Metashape.PointsFormatLAS, source_data = Metashape.DataSource.DenseCloudData, save_colors = True)
   
   #if chunk.model:
   #   chunk.exportModel(path = export_base_path + "/REZULTATI/2_3D_MODEL.obj", format = Metashape.ModelFormatOBJ, texture_format = Metashape.ImageFormatJPEG, save_texture = True, save_uv = True, save_normals = True, save_colors = True)
   
   chunk.exportReport(path = export_base_path + "/REZULTATI/3_Fotogrametrično_poročilo.pdf")
   
   #undistort
   #for camera in chunk.cameras:
   #   image = camera.image()
   #   calib = camera.sensor.calibration
   #   undist = image.undistort(calib, center_principal_point = True, square_pixels = True)
   #   label = camera.label
   #   undist.save(export_base_path + "/REZULTATI/" + camera.label + os.path.basename(camera.photo.path)[-4:])
   
   print("ODLIČNO, BREZ NAPAK JE OBDELALO FOTOGRAMETRIČNO OBDELAVO!!")
   Metashape.app.messageBox("ODLIČNO, BREZ NAPAK JE OBDELALO FOTOGRAMETRIČNO OBDELAVO!!")
   return 1
   
   
autoprocess()
« Last Edit: May 10, 2021, 09:03:01 PM by mihapajo123 »

Yoann Courtois

  • Sr. Member
  • ****
  • Posts: 316
  • Engineer in Geodesy, Cartography and Surveying
    • View Profile
Re: Fail to load calibration
« Reply #13 on: May 10, 2021, 09:49:54 PM »
Hi mihapajo123,

To set your camera as a fisheye lens, you should use the following code :

Code: [Select]
sensor.type = Metashape.Sensor.Type.Fisheye
To apply your personnal internal parameters, use this :

Code: [Select]
personal_param = Metashape.Calibration()
personal_param.load(path=my_path)
sensor.user_calib = personal_param

Regards
--
Yoann COURTOIS
R&D Engineer in photogrammetric process and mobile application
Lyon, FRANCE
--

mihapajo123

  • Newbie
  • *
  • Posts: 8
    • View Profile
Re: Fail to load calibration
« Reply #14 on: May 11, 2021, 07:57:07 AM »
WELCOME,

LET ME KNOW THIS ERROR ATTACHED IN THE PICTURE. Is it possible for you to enter the code parameters into my code, since I am not skilled in javascript programming. Are you more proficient in javascript programming? If you had I would have some questions for you.