Пример #1
0
def camera_calibration(chunk, path_projekt):
    path = path_projekt + 'kalibrierung.xml'
    s = chunk.sensors[0]
    s.user_calib = PhotoScan.Calibration()
    c = PhotoScan.Calibration()
    c.load(path)
    s.user_calib = c
    s.fixed = True
Пример #2
0
if not (CoordinateSystem.init(CoordinateSystemEPSG)):
    app.messageBox("Coordinate system EPSG code not recognized!")
# define coordinate system in chunk
chunk.crs = CoordinateSystem
chunk.projection = CoordinateSystem

# FIND ALL PHOTOS IN PATH
AerialImageFiles = glob.glob(AerialImagesPattern)

# LOAD CAMERA CALIBRATION
print("---Loading camera calibration...")
# we need to open first image to define image size
cam = PhotoScan.Camera()
cam.open(AerialImageFiles[0])
# Load sensor calib
user_calib = PhotoScan.Calibration()
if not (user_calib.load(CalibFile)):
    app.messageBox("Loading of calibration file failed!")
# build sensor object
sensor = PhotoScan.Sensor()
sensor.label = "MyCamera"
sensor.width = cam.width
sensor.height = cam.height
sensor.fixed = False
sensor.user_calib = user_calib
chunk.sensors.add(sensor)

# LOAD AERIAL IMAGES
print("---Loading images...")
# load each image
for FileName in AerialImageFiles:
Пример #3
0
def generate3D(filePath):
   
    fullPathPhotoDirectoryName=filePath   
    
    # Define: AlignPhotosAccuracy ["high", "medium", "low"]
    #change me
    
    AlignPhotosAccuracy = "medium"

  
    
    TireAuditDataRoot=os.path.dirname(os.path.dirname(fullPathPhotoDirectoryName))+"\\"
 
    PhotoScanInputGCPFileTireAuditMarkers=generate_3DSettings.photoScanGCPFile
    PhotoScanInputGCPFileAgisoftMarkers=TireAuditDataRoot+"gcp_agisoft.csv"
    PhotoScanInputGCPFileAgisoftMarkers=TireAuditDataRoot+"foo4.txt"
    PhotoScanInputCalibFile=generate_3DSettings.photoScanCalibrationFile

    
    #fdebug.write("\n ********************* TireAuditDataRoot  PhotoScanInputCalibFile  PhotoScanInputGCPFileAgisoftMarkers  PhotoScanInputGCPFileAgisoftMarkers PhotoScanInputCalibFile\n ",TireAuditDataRoot , PhotoScanInputCalibFile , PhotoScanInputGCPFileAgisoftMarkers,  PhotoScanInputGCPFileAgisoftMarkers ,PhotoScanInputCalibFile)
  
        
    PhotoScanPlyFile = fullPathPhotoDirectoryName+"\\"+generate_3DSettings.photoScanPlyName 

    PhotoScanLogFile = fullPathPhotoDirectoryName+"\\"+   generate_3DSettings.photoScanLogName
    PhotoScanDebugFile = fullPathPhotoDirectoryName+"\\"+   generate_3DSettings.photoScanDebugName
    PhotoScanProjectFile= fullPathPhotoDirectoryName+"\\"+   generate_3DSettings.photoScanProjectName
    PhotoScanReprojectionErrorsFile = fullPathPhotoDirectoryName+"\\"+   generate_3DSettings.photoScanReprojectionErrorsName
    PhotoScanMarkerFile =  fullPathPhotoDirectoryName+"\\"+generate_codesSettings.markerInformationPixelToCode

    
    
    #fdebug.write("\n*********** Checking for %s \n", PhotoScanProjectFile)
    # if path already has a psz file in exit then go onto nex directory
    if os.path.exists(PhotoScanProjectFile):
        #fdebug.write("\n*********** already proceessed %s \n", PhotoScanProjectFile)
        exit
        
    fdebug=open(PhotoScanDebugFile,'w') 
    flog = open(PhotoScanLogFile,'w') 
    start=time.time()
    
    #####pattern = 'IMG_*[02468].JPG'
    pattern = 'IMG_*'
    #print 'Pattern :', pattern
    print ( "abc")
    
    #files = os.listdir('.')
    files = os.listdir(fullPathPhotoDirectoryName)
    
    photoList=[]
    for filename in fnmatch.filter(files,pattern):
        #print ('Filename: %-25s %s' % (name, fnmatch.fnmatch(name, pattern))   )
    	#item = fullPathPhotoDirectoryName+"\\"+filename
    	item = os.path.join(fullPathPhotoDirectoryName,filename)
    	photoList.append(item)
    	
    
    print ("\n777 Photolist is ", photoList)
    
    doc = PhotoScan.app.document
    chunk = PhotoScan.app.document.addChunk()
    chunk.crs = PhotoScan.CoordinateSystem('LOCAL_CS["Local Coordinates",LOCAL_DATUM["Local Datum",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]]]')
    #successLoad=chunk.loadReference("c:\\temp\\pgcp.csv","csv")
    #successLoad=chunk.loadReference("c:\\temp\\foo1.csv","csv")
    #successLoad=chunk.loadReference("c:\\temp\\dtest.csv","csv")
    #print ("\n ############# Success Load is ", successLoad)
    #chunk.updateTransform()
    
    
    
    
    chunk.label = "New ChunkB"
    
    cameraDictionary={}
    user_calib = PhotoScan.Calibration()
   
    success=user_calib.load(PhotoScanInputCalibFile)
    print ("\n success loading calib file ", success)
    sensor = chunk.addSensor() #creating camera calibration group for the loaded image
    sensor.label = "Calibration Group 1"
    sensor.type = PhotoScan.Sensor.Type.Frame
    #sensor.width = camera.photo.image().width
    
    #sensor.height = camera.photo.image().height
    sensor.width = 5312
    sensor.height = 2988
    sensor.fixed=True   
    sensor.user_calib=user_calib
    #sensor.width = 3264
    #sensor.height = 2448
    #sensor.calibration.cx=1.61822175e+03
    #sensor.calibration.cy=1.26702669e+03
    #sensor.calibration.fx=3.08768833e+03
    #sensor.calibration.fy=3.08786068e+03
    #sensor.calibration.k1=0.23148765
    #sensor.calibration.k2=0.51836559
    #sensor.calibration.k3=-0.48297284
    
#    sensor.calibration.fx = 3.99411182e+03 
#    sensor.calibration.fy = 3.99418122e+03 
#    sensor.calibration.cx = 2.68713926e+03
#    sensor.calibration.cy = 1.51055154e+03
#    sensor.calibration.k1= 0.24503953  
#    sensor.calibration.k2 = -0.80636859 
#    sensor.calibration.k3 = 0.77637451
#    sensor.user_calib.fx = 3.99411182e+03 
#    sensor.user_calib.fy = 3.99418122e+03 
#    sensor.user_calib.cx = 2.68713926e+03
#    sensor.user_calib.cy = 1.51055154e+03
#    sensor.user_calib.k1= 0.24503953  
#    sensor.user_calib.k2 = -0.80636859 
#    sensor.user_calib.k3 = 0.77637451
#    sensor.user_calib = True
    
    
#    sensor.calibration.fx = 4.05913e+03 
#    sensor.calibration.fy = 4.06049e+03 
#    sensor.calibration.cx = 2.68463e+03
#    sensor.calibration.cy =  1.52241e+03
#    sensor.calibration.k1= 0.273712  
#    sensor.calibration.k2 = -1.03971
#    sensor.calibration.k3 =  1.05705
    
    
    chunk.accuracy_markers=0.0002
    
    
    
    for i,filepath in enumerate(photoList):
            fdebug.write("\nxxxxxxxx     filepath" + " " +  filepath)
            camera=chunk.addCamera() 
            camera.sensor = sensor
            pos= filepath.find("IMG")
            img= filepath[pos:]
            #cameraDictionary[img]=i
            cameraDictionary[img]=camera.key
            camera.open(filepath)
            #camera.open("c:\\Projects\\123DCatch\\Tires_25982510_B_Samsung6ChoppedExampleForTesting\\A\\IMG_14.JPG")
            camera.label=img
            #fdebug.write("\n filepath key", filepath, camera.key,camera.photo.image().width,camera.photo.image().height)
            fdebug.write("\n filepath key" +  " " + filepath + " "+ str(camera.key)+ " "+camera.photo.path)
    
    fdebug.write("\n^^^^^^^^^^ Camera Dictionary" + " " + str(cameraDictionary) )
    
    
    fdebug.write ("\n PhotoList &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\n" + " " + str(photoList))
    
    
    fdebug.write("hello")


    if (os.path.isfile(PhotoScanMarkerFile)):
        automaticMarkers=False
    else:
        automaticMarkers=True  
        
    fdebug.write ("\n ^^^^^^^^^^^^^^^^^ automatic markers is \n " +  str(automaticMarkers) + "\n")

    
    if (automaticMarkers):
        chunk.detectMarkers(PhotoScan.TargetType.CircularTarget20bit,44)
        print ("\n ^^^^^^^^^^^^^^^^^ loading automatic ground contreol information\n", PhotoScanInputGCPFileAgisoftMarkers,"\n")
        successLoad=chunk.loadReference(PhotoScanInputGCPFileAgisoftMarkers,"csv")

        fdebug.write("\n succes load is" + " "+ str(successLoad))
    else:
    
    
        markerNamePosList=[]
        processTAMarkers(PhotoScanMarkerFile,markerNamePosList,chunk,cameraDictionary,fdebug)
        fdebug.write ("\n ^^^^^^^^^^^^^^^^^ loading ground contreol information\n" + " " + PhotoScanInputGCPFileTireAuditMarkers + "\n")
        #successLoad=chunk.loadReference("c:\\temp\\gcp_25982510.csv","csv")
        successLoad=chunk.loadReference(PhotoScanInputGCPFileTireAuditMarkers,"csv")
    
    # load in ground control information 
    # load in masks
    templateName=fullPathPhotoDirectoryName+ "\\" + "M{filename}.JPG"
    #templateName=fullPathPhotoDirectoryName+ "\\" + "M{filename}.JPG"
    successMask=chunk.importMasks(path=templateName,method='file',tolerance=10)
    	
    #ALIGN PHOTOS
    fdebug.write("---Aligning photos ...")
    fdebug.write("Accuracy: " + AlignPhotosAccuracy)
    fdebug.write("\nBefore Matching **** \n")
    
    if (generate_3DSettings.matchAccuracy=="Low"):
        accuracyMatch=  PhotoScan.Accuracy.LowAccuracy
    elif (generate_3DSettings.matchAccuracy=="High"):
        accuracyMatch=  PhotoScan.Accuracy.HighAccuracy
    else:
        accuracyMatch= PhotoScan.Accuracy.MediumAccuracy
    
    if (generate_3DSettings.modelAccuracy=="Ultra"):
        accuracyModel= PhotoScan.Quality.UltraQuality
    elif (generate_3DSettings.modelAccuracy=="High"):
        accuracyModel=  PhotoScan.Quality.HighQuality
    elif (generate_3DSettings.modelAccuracy=="Low"):
        accuracyModel= PhotoScan.Quality.LowQuality
    elif (generate_3DSettings.modelAccuracy=="Lowest"):
        accuracyModel= PhotoScan.Quality.LowestQuality
    else:
        accuracyModel= PhotoScan.Quality.MediumQuality  
           
    
    chunk.matchPhotos(accuracy=  accuracyMatch, preselection=PhotoScan.Preselection.GenericPreselection)
    fdebug.write("\nBefore Align **** \n")
    chunk.alignCameras()
    fdebug.write("\nBefore Optimize **** \n")
    chunk.optimizeCameras()
    fdebug.write("\nBefore Build Dense **** \n")
    chunk.buildDenseCloud(quality=accuracyModel) 
    fdebug.write("\nBefore Build Model **** \n")
    chunk.buildModel(surface= PhotoScan.SurfaceType.Arbitrary, interpolation=PhotoScan.Interpolation.EnabledInterpolation, source= PhotoScan.PointsSource.DensePoints , face_count=generate_3DSettings.faceCount)
    fdebug.write("\nBefore Build Texture **** \n")
    
    mapping = PhotoScan.MappingMode.GenericMapping #build texture mapping
    chunk.buildUV(mapping = mapping, count = 1)
    chunk.buildTexture()
    
    chunk.exportModel(PhotoScanPlyFile, format = "ply", texture_format='jpg')
    
    PhotoScan.app.update()
    
    #save ground control information a
    
    if not(chunk.saveReference(PhotoScanReprojectionErrorsFile,"csv")):
       app.messageBox("Saving GCP info failed!")
    
    # SAVE PROJECT
    fdebug.write("---Saving project...")
    fdebug.write("File: " + PhotoScanProjectFile)
    if not(doc.save(PhotoScanProjectFile)):
       app.messageBox("Saving project failed!")
    
       
    
    doc.chunks.remove(chunk)
    end=time.time()
    fdebug.close()
    flog.write('\nelapsed time ='+str(end-start)) # python will convert \n to os.linesep
    flog.close()
    return
Пример #4
0
def preProcess(doc, chunk, scaletxt, camdict):
    '''
    Pre-processing chunks by:
    1) detecting markers
    2) adding scale bars
    3) filtering images by quality
    4) Roller shutter compensation
    5) Add Camera callibration
    
    Inputs:
    * doc: Photoscan document object(e.g., PhotoScan.app.document)
    * scaletxt: name of the file containing the distance between markers and date of measurements (e.g., scalebars.csv)
    * qual: quality threshold used to filter images
    * ttshold:  tolerance threshold for marker detection
    *calfile= calibration parameters in XML format. If no calibration exist type 'NONE'
    '''

    ### SET ENVIRONMENTAL VARIABLES

    # docpath=doc.path
    #c=docpath.split('/projects')[0] #this is just to know the root dir when working over the network
    #load scalebar reference file
    sbar = os.path.join('.', 'reference_scales', scaletxt)
    df = pd.read_csv(sbar, delimiter='\t')
    df['DATE'] = pd.to_datetime(df['DATE'], format='%d/%m/%Y')

    ############### Enabling rolling shutter compensation ################################
    print("---Rolling shutter compensation---")

    try:
        for sensor in chunk.sensors:
            sensor.rolling_shutter = True
            if camdict['fisheye']:
                sensor.type = PhotoScan.Sensor.Type.Fisheye
    except Exception as e:
        print("Error:", e)
        raise

    ############## Import Camera calibration parameters ###############
    if camdict['calfile'] != 'NONE':
        print("---Importing calibration parameters---")
        calib = PhotoScan.Calibration()
        calib.load(os.path.join('.', 'calibration', camdict['calfile']),
                   format="xml")
        sensor = chunk.sensors[0]  #first calibration group in the active chunk

        #sensor.calibration = calib # this will set the Adjusted values according to the XML
        sensor.user_calib = calib  #and this will load the XML values to the Initial values

    ############### Image quality control ###############################
    print("---Estimating image quality---")
    chunk.estimateImageQuality(chunk.cameras)
    for camera in chunk.cameras:
        if float(camera.meta["Image/Quality"]) < camdict['qual_threshold']:
            camera.enabled = False

    ############### Marker detection ###############################
    print("---Detecting Markers---")
    chunk.detectMarkers(PhotoScan.TargetType.CircularTarget12bit,
                        camdict['tol_threshold'])

    ############### Add ScaleBars and distande from file ###############################
    print("---Adding ScaleBars---")
    camera = chunk.cameras[0]
    img_date = datetime.strptime(camera.photo.meta['Exif/DateTimeOriginal'],
                                 camdict['dateformat'])
    if img_date < min(
            df['DATE']
    ):  ## FIXME this is a temporary fisx for when the camera time is not set properly
        time_diff = datetime(2018, 1, 1, 0, 0, 0) - img_date
        img_date = img_date + time_diff
    ref_date = pst.nearest(df['DATE'], img_date)

    markers = {}
    for marker in chunk.markers:
        markers[marker.label] = marker

    with open(sbar, 'r', errors='replace') as f:
        lines = f.readlines()[1:]
    for line in lines:
        #FIXME there is a problem with the date format time data 'A' does not match format '%d/%m/%y' <MGR>
        tdate, t1, t2, dist = datetime.strptime(
            line.split('\t')[0], '%d/%m/%Y'), line.split('\t')[1], line.split(
                '\t')[2], line.split('\t')[3]

        if t1 in markers.keys() and t2 in markers.keys() and ref_date == tdate:
            s = chunk.addScalebar(markers[t1], markers[t2])
            s.reference.distance = float(dist)
Пример #5
0
def processing(dwg, quality):
    '''Contains process-steps that are called in PhotoScan'''

    config = configparser.ConfigParser()
    cwd = os.path.dirname(os.path.abspath(__file__))
    config_file_path = cwd+'/config_cor.ini'
    config.read(config_file_path)

    input_dir_path = config["PATHS"]["input_images_path"]
    save_path = input_dir_path +"/PSResults/"+config["MISC"]["pro_name"]

    types = (input_dir_path+"/*.jpg",input_dir_path+"/*.JPG")
    all_fotos = []
    for files in types:
        all_fotos.extend(glob.glob(files))

    if not os.path.exists(os.path.dirname(save_path)):
         os.makedirs(os.path.dirname(save_path))

    doc = PS.app.document
    doc.save(path = save_path +".psx")

    chunk = doc.addChunk ()
    chunk.label = config["MISC"]["pro_name"] +"_"+ quality

    input_list_file = input_dir_path + '/list.txt'
    input_fotos = [line.rstrip('\n') for line in open(input_list_file)]

    chunk.addPhotos(input_fotos)

    if config["MISC"]["calibfile"] == "true":
        calib = PS.Calibration()
        calib.load(config["PATHS"]["calibfile_path"])

    doc.save(path = save_path +".psx")
    chunk.matchPhotos(accuracy = dwg["accuracy"], 
                    preselection = dwg["preselection"],
                    filter_mask = dwg["filter_mask"], keypoint_limit = dwg["keypoint_limit"], 
             tiepoint_limit = dwg["tiepoint_limit"])

    chunk.alignCameras()
    chunk.optimizeCameras(fit_f=True, fit_cxcy=True, fit_b1=True, fit_b2=True,
                          fit_k1k2k3=True, fit_p1p2=True, fit_k4=True,
                          fit_p3=True, fit_p4=True)
    doc.save(path = save_path +".psx")

    ###########################################################################
    if dwg["no_DenseCloud"] == False:
        chunk.buildDepthMaps(quality = dwg["quality"], filter = dwg["filter"], reuse_depth=False)
        chunk.buildDenseCloud()
    ###########################################################################

    doc.save(path = save_path +".psx")

    chunk.buildModel(dwg["surface_M"], dwg["interpolation"], dwg["face_count"])

    doc.save(path = save_path +".psx")

    chunk.buildUV(PS.MappingMode.AdaptiveOrthophotoMapping,count=1)
    chunk.buildTexture(PS.BlendingMode.MosaicBlending)

    doc.save(path = save_path +".psx")

    chunk.buildDem(dwg["source_cloud"], dwg["interpolation"])

    doc.save(path = save_path +".psx")

    chunk.buildOrthomosaic(surface = dwg["surface_O"], blending = dwg["blending"])

    chunk.buildContours(source_data = dwg["source_data"], interval = dwg["interval"])

    doc.save(path = save_path +".psx")

    return
Пример #6
0
def generate3D(filePath):

    fullPathPhotoDirectoryName = filePath

    # Define: AlignPhotosAccuracy ["high", "medium", "low"]
    #change me
    print("\n**enum gpu devices", PhotoScan.app.enumGPUDevices())
    print("\n**gpu mask ", PhotoScan.app.gpu_mask)

    TireAuditDataRoot = os.path.dirname(
        os.path.dirname(fullPathPhotoDirectoryName)) + "\\"

    #1    PhotoScanInputGCPFileTireAuditMarkers=generate_3DSettings.photoScanGCPFile
    #1    PhotoScanInputGCPFileAgisoftMarkers=TireAuditDataRoot+"gcp_agisoft.csv"
    #1    PhotoScanInputGCPFileAgisoftMarkers=TireAuditDataRoot+"foo4.txt"
    PhotoScanInputCalibFile = generate_3DSettings.photoScanCalibrationFile

    #fdebug.write("\n ********************* TireAuditDataRoot  PhotoScanInputCalibFile  PhotoScanInputGCPFileAgisoftMarkers  PhotoScanInputGCPFileAgisoftMarkers PhotoScanInputCalibFile\n ",TireAuditDataRoot , PhotoScanInputCalibFile , PhotoScanInputGCPFileAgisoftMarkers,  PhotoScanInputGCPFileAgisoftMarkers ,PhotoScanInputCalibFile)

    PhotoScanPlyFile = fullPathPhotoDirectoryName + "\\" + generate_3DSettings.photoScanPlyName

    PhotoScanLogFile = fullPathPhotoDirectoryName + "\\" + generate_3DSettings.photoScanLogName
    PhotoScanDebugFile = fullPathPhotoDirectoryName + "\\" + generate_3DSettings.photoScanDebugName
    PhotoScanProjectFile = fullPathPhotoDirectoryName + "\\" + generate_3DSettings.photoScanProjectName
    PhotoScanReprojectionErrorsFile = fullPathPhotoDirectoryName + "\\" + generate_3DSettings.photoScanReprojectionErrorsName
    #PhotoScanMarkerFile =  fullPathPhotoDirectoryName+"\\"+generate_codesSettings.markerInformationPixelToCode

    #fdebug.write("\n*********** Checking for %s \n", PhotoScanProjectFile)
    # if path already has a psz file in exit then go onto nex directory
    if os.path.exists(PhotoScanProjectFile):
        #fdebug.write("\n*********** already proceessed %s \n", PhotoScanProjectFile)
        exit

    fdebug = open(PhotoScanDebugFile, 'w')
    flog = open(PhotoScanLogFile, 'w')
    start = time.time()

    #####pattern = 'IMG_*[02468].JPG'
    pattern = 'IMG_*'
    #print 'Pattern :', pattern
    print("abc")

    #files = os.listdir('.')
    files = os.listdir(fullPathPhotoDirectoryName)

    photoList = []
    for filename in fnmatch.filter(files, pattern):
        #print ('Filename: %-25s %s' % (name, fnmatch.fnmatch(name, pattern))   )
        #item = fullPathPhotoDirectoryName+"\\"+filename
        item = os.path.join(fullPathPhotoDirectoryName, filename)
        photoList.append(item)

    print("\n777 Photolist is ", photoList)

    doc = PhotoScan.Document()
    chunk = doc.addChunk()

    chunk.crs = PhotoScan.CoordinateSystem(
        'LOCAL_CS["Local Coordinates",LOCAL_DATUM["Local Datum",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]]]'
    )

    chunk.label = "New ChunkB"

    cameraDictionary = {}
    user_calib = PhotoScan.Calibration()

    success = user_calib.load(PhotoScanInputCalibFile)
    print("\n success loading calib file ", success)
    sensor = chunk.addSensor(
    )  #creating camera calibration group for the loaded image
    sensor.label = "Calibration Group 1"
    sensor.type = PhotoScan.Sensor.Type.Frame
    #sensor.width = camera.photo.image().width

    #sensor.height = camera.photo.image().height
    sensor.width = 5312
    sensor.height = 2988
    sensor.fixed = True
    sensor.user_calib = user_calib
    #sensor.width = 3264

    #1 chunk.marker_projection_accuracy=0.0002

    for i, filepath in enumerate(photoList):
        fdebug.write("\nxxxxxxxx     filepath" + " " + filepath)
        camera = chunk.addCamera()
        camera.sensor = sensor
        pos = filepath.find("IMG")
        img = filepath[pos:]
        #cameraDictionary[img]=i
        cameraDictionary[img] = camera.key
        camera.open(filepath)
        #camera.open("c:\\Projects\\123DCatch\\Tires_25982510_B_Samsung6ChoppedExampleForTesting\\A\\IMG_14.JPG")
        camera.label = img
        #fdebug.write("\n filepath key", filepath, camera.key,camera.photo.image().width,camera.photo.image().height)
        fdebug.write("\n filepath key" + " " + filepath + " " +
                     str(camera.key) + " " + camera.photo.path)

    fdebug.write("\n^^^^^^^^^^ Camera Dictionary" + " " +
                 str(cameraDictionary))

    fdebug.write("\n PhotoList &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\n" + " " +
                 str(photoList))

    fdebug.write("hello")

    templateName = fullPathPhotoDirectoryName + "\\" + "M{filename}.JPG"
    #templateName=fullPathPhotoDirectoryName+ "\\" + "M{filename}.JPG"
    #successMask=chunk.importMasks(path=templateName,method='file',tolerance=10)
    successMask = chunk.importMasks(
        path=templateName,
        source=PhotoScan.MaskSourceFile,
        operation=PhotoScan.MaskOperationReplacement,
        tolerance=10,
        cameras=chunk.cameras)

    print(
        "\n***********************&&&&&&&&&&&&&&&&& successMask ************",
        successMask)

    #ALIGN PHOTOS
    fdebug.write("---Aligning photos ...")
    fdebug.write("Accuracy: " + generate_3DSettings.matchAccuracy)
    fdebug.write("\nBefore Matching **** \n")

    if (generate_3DSettings.matchAccuracy == "Low"):
        accuracyMatch = PhotoScan.Accuracy.LowAccuracy
    elif (generate_3DSettings.matchAccuracy == "High"):
        accuracyMatch = PhotoScan.Accuracy.HighAccuracy
    else:
        accuracyMatch = PhotoScan.Accuracy.MediumAccuracy

    if (generate_3DSettings.modelAccuracy == "Ultra"):
        accuracyModel = PhotoScan.Quality.UltraQuality
    elif (generate_3DSettings.modelAccuracy == "High"):
        accuracyModel = PhotoScan.Quality.HighQuality
    elif (generate_3DSettings.modelAccuracy == "Low"):
        accuracyModel = PhotoScan.Quality.LowQuality
    elif (generate_3DSettings.modelAccuracy == "Lowest"):
        accuracyModel = PhotoScan.Quality.LowestQuality
    else:
        accuracyModel = PhotoScan.Quality.MediumQuality

    chunk.matchPhotos(accuracy=accuracyMatch,
                      preselection=PhotoScan.Preselection.GenericPreselection,
                      filter_mask=True)
    fdebug.write("\nBefore Align **** \n")
    chunk.alignCameras()
    fdebug.write("\nBefore Optimize **** \n")
    chunk.optimizeCameras()
    fdebug.write("\nBefore Build Dense **** \n")
    chunk.buildDenseCloud(quality=accuracyModel)
    fdebug.write("\nBefore Build Model **** \n")
    #chunk.buildModel(surface= PhotoScan.SurfaceType.Arbitrary, interpolation=PhotoScan.Interpolation.EnabledInterpolation , face_count=generate_3DSettings.faceCount)

    #chunk.buildModel(surface= PhotoScan.SurfaceType.Arbitrary, interpolation=PhotoScan.Interpolation.EnabledInterpolation , face_count=300000)
    fdebug.write("\nBefore Build Texture **** \n")

    mapping = PhotoScan.MappingMode.GenericMapping  #build texture mapping
    chunk.buildUV(mapping=mapping, count=1)
    chunk.buildTexture()

    #chunk.exportModel(path=PhotoScanPlyFile, format = 'ply', texture_format='jpg')
    chunk.exportModel(PhotoScanPlyFile,
                      format=PhotoScan.ModelFormat.ModelFormatPLY,
                      texture_format=PhotoScan.ImageFormat.ImageFormatJPEG)
    #chunk.exportModel(path_export + "\\model.obj", format = "obj", texture_format='PhotoScan.ImageFormat.ImageFormatJPEG)

    PhotoScan.app.update()

    #save ground control information a
    chunk.saveReference(PhotoScanReprojectionErrorsFile,
                        PhotoScan.ReferenceFormat.ReferenceFormatCSV)
    #
    #    if not(chunk.saveReference(PhotoScanReprojectionErrorsFile, PhotoScan.ReferenceFormat.ReferenceFormatCSV              )):
    #       app.messageBox("Saving GCP info failed!")
    #
    # SAVE PROJECT
    fdebug.write("---Saving project...")
    fdebug.write("File: " + PhotoScanProjectFile)
    doc.save(PhotoScanProjectFile)

    doc.chunks.remove(chunk)
    end = time.time()
    fdebug.close()
    flog.write('\nelapsed time =' +
               str(end - start))  # python will convert \n to os.linesep
    flog.close()
    return