def alignphotos():
    print("*** Started...Align Photos *** ", datetime.datetime.utcnow())
    coord_system = PhotoScan.CoordinateSystem('EPSG::4326')
    chunk.crs = coord_system
    #chunk.matchPhotos(accuracy=config['accuracy'], preselection=PhotoScan.Preselection.GenericPreselection, filter_mask=False, keypoint_limit=40000, tiepoint_limit=10000)
    chunk.matchPhotos(accuracy=PhotoScan.Accuracy.LowestAccuracy,
                      preselection=PhotoScan.Preselection.GenericPreselection,
                      filter_mask=False,
                      keypoint_limit=40000,
                      tiepoint_limit=10000)
    chunk.alignCameras()
    if os.path.exists(marker_file) == True:
        print("marker file exist!")
        chunk.importMarkers(marker_file)

    if os.path.exists(reference_file) == True:
        print("reference file exist!")
        chunk.loadReference(reference_file, "csv", delimiter=';')

    chunk.optimizeCameras()

    for camera in chunk.cameras:
        camera.reference.enabled = False
    chunk.updateTransform()
    print("*** Finished - Align Photos ***")
Ejemplo n.º 2
0
def setCoordinateSystem(chunk, doc):
    '''
    Установить систему координат
    :return:
    '''
    chunk.crs = PhotoScan.CoordinateSystem(CK="EPSG::4326")
    chunk.updateTransform()
    doc.save()
Ejemplo n.º 3
0
 def export_model(self):
     """
     Export LAS and OBJ to path using the file name prefix
     
     #Texture file format is JPG for JPG input images and TIF for all others.
     """
     for _ in self.chunks:
         #Texture JPG for now as Cloudcompare doesn't like the TIFF format
         ext = PhotoScan.ImageFormatJPEG
         """ext = _.cameras[0].label[-3:]
         if ext.upper() == 'JPG':
             ext = PhotoScan.ImageFormatJPEG
         else:
             ext = PhotoScan.ImageFormatTIFF"""
         if self.exp_crs == 0:
             crs = _.crs
         else:
             crs = PhotoScan.CoordinateSystem('EPSG::{}'
                     .format(self.exp_crs))
         #write log information
         with open(self.log, 'a+') as logfile:
             start_t =  datetime.now()
             logfile.write('Exporting model {} at {} \n'.
                                         format(_, 
                                             start_t.strftime('%H:%M:%S')))
             logfile.write('    Export CRS: {}\n'.
                                         format(crs))
         #create export file name                                
         if str(_)[8:-4] == 'Chunk':
             name = ''
             num = str(_)[-3]
         else:
             name = str(_)[8:-2]
             num = ''
         try:
             file = '{}{}_LAS{}.las'.format(self.prefix, name, num)
             _.exportPoints(path = os.path.join(self.path, file),
                             format=PhotoScan.PointsFormatLAS,
                             projection=crs)
         except RuntimeError as e:
             if str(e) == 'Null point cloud':
                 print('There is no point cloud to export in chunk: {}'
                         .format(_))
                 continue
             else:
                 raise
         try:
             file = '{}{}_OBJ{}.obj'.format(self.prefix, name, num)
             _.exportModel(path = os.path.join(self.path, file),
                             texture_format=ext,
                             projection=crs)
         except RuntimeError as e:
             if str(e) == 'Null model':
                 print('There is no model to export in chunk: {}'.format(_))
                 continue
             else:
                 raise
Ejemplo n.º 4
0
def alignphotos():
    print("*** Started...Align Photos *** ", datetime.datetime.utcnow())
    coord_system = PhotoScan.CoordinateSystem('EPSG::4326')
    chunk.crs = coord_system
    chunk.matchPhotos(accuracy=PhotoScan.Accuracy.LowestAccuracy, preselection=PhotoScan.Preselection.GenericPreselection, filter_mask=False, keypoint_limit=4000, tiepoint_limit=500)
    chunk.alignCameras()
    chunk.optimizeCameras()
    doc.save(doc_name)
    PhotoScan.app.update()
    print("*** Finished - Align Photos ***")
Ejemplo n.º 5
0
def scale_cams(chunk, camdict, thd=[0.5, 0.7], lstring='_LC', d=0.4):
    '''
    thd: Min and Max overlaping desired to select camera pairs for scalebars
    lstring: unique string that identify the name of the cameras as the ones on the left-hand side
    d: Distance between the centre of the lens from each camera
    '''
    overlap = []
    cams = {'right': [], 'left': []}
    chunk.decimateModel(100000)  ## this is to minimise memory load

    for cam in chunk.cameras:
        if cam.transform:
            if cam.label.__contains__(camdict['lstring']):
                cams['left'].append(np.r_[cam.key, np.asarray(cam.center)])
            else:
                cams['right'].append(np.r_[cam.key, np.asarray(cam.center)])

    if chunk.crs == None:
        crs = PhotoScan.CoordinateSystem(
            'LOCAL_CS["Local CS",LOCAL_DATUM["Local Datum",0],UNIT["metre",1]]'
        )
        chunk.crs = crs

    #Find the closed camera pair and check that is a camera pair based on overlaping to set the scalebars
    for l in cams['left'][5::10]:
        lcam = l[1:]
        lcam_index = np.int(l[0])
        rcams = np.asarray(cams['right'])
        rcams = rcams[:, 1:]
        rcam_index = np.int(cams['right'][closest_pair(lcam, rcams)][0])
        scalebar = chunk.addScalebar(chunk.cameras[lcam_index],
                                     chunk.cameras[rcam_index])
        scalebar.label = chunk.cameras[
            lcam_index].label + " - " + chunk.cameras[rcam_index].label
        scalebar.reference.distance = camdict['cam_dist']
        PhotoScan.app.update()
        chunk.updateTransform()
        #fine-tune scalebars based on image-pair overlapping.
        #Remove those scalebars where images are not overlapping enough or too much.
        #This avoid false pairs
        try:
            thisIOI = co.IOI(lcam_index, rcam_index, chunk)
            overlap = np.r_[overlap, thisIOI]
            if (thisIOI < camdict['overlap_threshold'][0]
                    or thisIOI > camdict['overlap_threshold'][1]):
                chunk.remove(scalebar)
        except Exception as e:
            overlap = np.r_[
                overlap,
                0]  #most likely, these are cameras which edge falls outside the
            chunk.remove(scalebar)
            pass

    return (overlap)
Ejemplo n.º 6
0
def photoscanProcess(root_path):
    #PhotoScan.app.messageBox('hello world! \n')
    PhotoScan.app.console.clear()

    ## construct the document class
    doc = PhotoScan.app.document

    ## save project
    #doc.open("M:/Photoscan/practise.psx")
    psxfile = root_path + 'practise.psx'
    doc.save(psxfile)
    print('>> Saved to: ' + psxfile)

    ## point to current chunk
    #chunk = doc.chunk

    ## add a new chunk
    chunk = doc.addChunk()

    ## set coordinate system
    # - PhotoScan.CoordinateSystem("EPSG::4612") -->  JGD2000
    chunk.crs = PhotoScan.CoordinateSystem("EPSG::4612")

    ################################################################################################
    ### get photo list ###
    photoList = []
    getPhotoList(root_path, photoList)
    #print (photoList)

    ################################################################################################
    ### add photos ###
    # addPhotos(filenames[, progress])
    # - filenames(list of string) – A list of file paths.
    chunk.addPhotos(photoList)

    ################################################################################################
    ### align photos ###
    ## Perform image matching for the chunk frame.
    # matchPhotos(accuracy=HighAccuracy, preselection=NoPreselection, filter_mask=False, keypoint_limit=40000, tiepoint_limit=4000[, progress])
    # - Alignment accuracy in [HighestAccuracy, HighAccuracy, MediumAccuracy, LowAccuracy, LowestAccuracy]
    # - Image pair preselection in [ReferencePreselection, GenericPreselection, NoPreselection]
    chunk.matchPhotos(accuracy=PhotoScan.LowAccuracy,
                      preselection=PhotoScan.ReferencePreselection,
                      filter_mask=False,
                      keypoint_limit=0,
                      tiepoint_limit=0)
    chunk.alignCameras()

    ################################################################################################
    ### build dense cloud ###
    ## Generate depth maps for the chunk.
    # buildDenseCloud(quality=MediumQuality, filter=AggressiveFiltering[, cameras], keep_depth=False, reuse_depth=False[, progress])
    # - Dense point cloud quality in [UltraQuality, HighQuality, MediumQuality, LowQuality, LowestQuality]
    # - Depth filtering mode in [AggressiveFiltering, ModerateFiltering, MildFiltering, NoFiltering]
    chunk.buildDenseCloud(quality=PhotoScan.LowQuality,
                          filter=PhotoScan.AggressiveFiltering)

    ################################################################################################
    ### build mesh ###
    ## Generate model for the chunk frame.
    # buildModel(surface=Arbitrary, interpolation=EnabledInterpolation, face_count=MediumFaceCount[, source ][, classes][, progress])
    # - Surface type in [Arbitrary, HeightField]
    # - Interpolation mode in [EnabledInterpolation, DisabledInterpolation, Extrapolated]
    # - Face count in [HighFaceCount, MediumFaceCount, LowFaceCount]
    # - Data source in [PointCloudData, DenseCloudData, ModelData, ElevationData]
    chunk.buildModel(surface=PhotoScan.HeightField,
                     interpolation=PhotoScan.EnabledInterpolation,
                     face_count=PhotoScan.HighFaceCount)

    ################################################################################################
    ### build texture (optional) ###
    ## Generate uv mapping for the model.
    # buildUV(mapping=GenericMapping, count=1[, camera ][, progress])
    # - UV mapping mode in [GenericMapping, OrthophotoMapping, AdaptiveOrthophotoMapping, SphericalMapping, CameraMapping]
    #chunk.buildUV(mapping=PhotoScan.AdaptiveOrthophotoMapping)
    ## Generate texture for the chunk.
    # buildTexture(blending=MosaicBlending, color_correction=False, size=2048[, cameras][, progress])
    # - Blending mode in [AverageBlending, MosaicBlending, MinBlending, MaxBlending, DisabledBlending]
    #chunk.buildTexture(blending=PhotoScan.MosaicBlending, color_correction=True, size=30000)

    ################################################################################################
    ## save the project before build the DEM and Ortho images
    doc.save()

    ################################################################################################
    ### build DEM (before build dem, you need to save the project into psx) ###
    ## Build elevation model for the chunk.
    # buildDem(source=DenseCloudData, interpolation=EnabledInterpolation[, projection ][, region ][, classes][, progress])
    # - Data source in [PointCloudData, DenseCloudData, ModelData, ElevationData]
    chunk.buildDem(source=PhotoScan.DenseCloudData,
                   interpolation=PhotoScan.EnabledInterpolation,
                   projection=chunk.crs)

    ################################################################################################
    ## Build orthomosaic for the chunk.
    # buildOrthomosaic(surface=ElevationData, blending=MosaicBlending, color_correction=False[, projection ][, region ][, dx ][, dy ][, progress])
    # - Data source in [PointCloudData, DenseCloudData, ModelData, ElevationData]
    # - Blending mode in [AverageBlending, MosaicBlending, MinBlending, MaxBlending, DisabledBlending]
    chunk.buildOrthomosaic(surface=PhotoScan.ModelData,
                           blending=PhotoScan.MosaicBlending,
                           color_correction=True,
                           projection=chunk.crs)

    ################################################################################################
    ## auto classify ground points (optional)
    #chunk.dense_cloud.classifyGroundPoints()
    #chunk.buildDem(source=PhotoScan.DenseCloudData, classes=[2])

    ################################################################################################
    doc.save()
Ejemplo n.º 7
0
    chunk.elevation = float(
        ProcParams.photoscan.referencesettingsmiscellaneousgroundalt)

# Add Trajectory
if ProcParams.importfiles.trajectoryfilename != "":
    trajectoryname = rootdir + "\\" + ProcParams.importfiles.rootname + "\\" + ProcParams.importfiles.trajectoryfilename
    chunk.loadReference(trajectoryname)

# Add Markers
if ProcParams.importfiles.controlfilename != "":
    markername = rootdir + "\\" + ProcParams.importfiles.rootname + "\\" + ProcParams.importfiles.controlfilename
    chunk.importMarkers(markername)

# DEFINE COORDINATE SYSTEM
if not (ProcParams.importfiles.epsg == ''):
    doc.chunk.crs = PhotoScan.CoordinateSystem("EPSG::" +
                                               ProcParams.importfiles.epsg)
else:
    print("Using PhotoScan Default CRS")

msg = "Added Trajectory/Reference Data"
proctime.write(
    msg.ljust(40) + " , " + strftime("%Y-%m-%d %H:%M:%S", gmtime()) + " , " +
    elaptime(lasttime, time.time()) + "\n")
lasttime = time.time()
proctime.flush()

## Do Sparse Alignment
# Match Photos
if ProcParams.photoscan.aligngeneralaccuracy == 'lowest':
    matchacc = PhotoScan.Accuracy.LowestAccuracy
elif ProcParams.photoscan.aligngeneralaccuracy == 'low':
Ejemplo n.º 8
0
def local_coordinates(chunk):
    chunk.crs = PhotoScan.CoordinateSystem(
        'LOCAL_CS["Local CS",LOCAL_DATUM["Local Datum",0],UNIT["metre",1]]')
Ejemplo n.º 9
0
<%=orthoRes%>
<%=preset_RU%>
<%=preset_RE%>
<%=preset_PA%>
<%=loop_RU%>
<%=loop_RE%>
<%=loop_PA%>

if sys.argv[1:]:
    goal = sys.argv[1]
if sys.argv[2:]:
    imgPath = sys.argv[2]

if goal == "ortho":    
	# define short variables
	crs =  PhotoScan.CoordinateSystem("EPSG::32632")
	doc = PhotoScan.app.document
	chunk = doc.addChunk()
	PSPCF = PhotoScan.PointCloud.Filter()
	count = 0
	# creating image list
	image_list = glob.glob(imgPath + "/*.JPG")
	print(image_list)
	# load images
	chunk.addPhotos(image_list)
	# load exif data
	chunk.loadReferenceExif()
	# create project
	doc.save(imgPath + "/" + projName)
	# reopen it
	doc.open(imgPath + "/" + projName)
Ejemplo n.º 10
0
def script_setup():
    file_loc = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))

    input_file_B = (file_loc + "/" + "input_file.csv")
    input_file_B = input_file_B.replace('\\', '/')

    print (input_file_B)

    var_list = []

    with open(input_file_B, 'r') as f:
        mycsv = csv.reader(f)
        for row in mycsv:
            colB = row[1]
            var_list.append(colB)

    home = var_list[1]

    doc_title = var_list[2]

    datadir = var_list[3]

    coord_sys = var_list[4]

    marker_coords = var_list[5]
    marker_crs = var_list[6]

    Est_img_qual = var_list[8]

    img_qual_thresh = var_list[9]

    spc_quality = var_list[10]

    reproj_err_limit = var_list[32]

    rolling_shutter = var_list[37]
    
    print (home)
    print(doc_title)
    print (datadir)
    print (coord_sys)
    name = "/" + doc_title + ".psx"

    doc = PS.app.document

    PS.app.gpu_mask = 2 ** len(PS.app.enumGPUDevices()) - 1  # activate all available GPUs
    if PS.app.gpu_mask <= 1:
        PS.app.cpu_enable = True  # Enable CPU for GPU accelerated processing (faster with 1 no difference with 0 GPUs)
    elif PS.app.gpu_mask > 1:
        PS.app.cpu_enable = False # Disable CPU for GPU accelerated tasks (faster when multiple GPUs are present)

    doc.save(home+name)

    # Locate and add photos
    photos = os.listdir(datadir)  # Get the photos filenames
    photos = [os.path.join(datadir, p) for p in photos]  # convert to full paths

    chunk = PS.app.document.addChunk()  # create a chunk

    chunk.addPhotos([photos])  # add photos to chunk

    if rolling_shutter == 'TRUE':
        chunk.sensors[0].rolling_shutter = True  # Option to enable Rolling shutter compensation
    
    new_crs = PS.CoordinateSystem(coord_sys)  # define desired Coordinate System

    try:
        for camera in chunk.cameras:  # set the coordinates for cameras
            camera.reference.location = new_crs.project(chunk.crs.unproject(camera.reference.location))
    except Exception:
        print ("Images do not have projection data... No Worries! continue without!")

    # Optional import of markers if desired...
    if marker_coords == "NONE":  # if no markers are given then pass
        pass
    else:
        chunk.loadReference(marker_coords, columns="nxyzXYZ", delimiter=",", group_delimiters=False,  # if a path is given markers are added
                            skip_rows=1, ignore_labels=False, create_markers=True, threshold=0.1)

        if marker_crs == coord_sys:  # if marker and project crs match then pass otherwise convert marker crs
            pass
        else:
            for marker in chunk.markers:  # This needs testing  but should theoretically work...
                marker.reference.location = new_crs.project(chunk.crs.unproject(marker.reference.location))

    chunk.crs = new_crs  # set project coordinate system

    doc.save(home + name)

    orig_n_cams, n_filter_removed, perc_filter_removed, real_qual_thresh = preprocess(Est_img_qual, img_qual_thresh, chunk)

    doc.save(home + name)
    points, projections = build_SPC(chunk, spc_quality)

    total_points, perc_ab_thresh, nselected = filter_reproj_err(chunk, reproj_err_limit)

    n_not_aligned = ref_setting_setup(doc, points, projections, home, name)

    export_settings(orig_n_cams, n_filter_removed, perc_filter_removed, real_qual_thresh, n_not_aligned,
                    total_points, nselected, home, doc_title)

    # SAVE DOCUMENT
    doc.save(home + name)
    if perc_ab_thresh > 20:
        print ("-------------------------------------------------------------")
        print ("WARNING >20% OF POINTS ABOVE REPROJECTION ERROR THRESHOLD!!!!")
        print ("-------------------------------------------------------------")

        # Get Execution Time...
    print ("Total Time: " + str(datetime.now() - startTime))  # GET TOTAL TIME
Ejemplo n.º 11
0
import PhotoScan
import os

app = PhotoScan.app

filelist = app.getOpenFileNames("Select Images", "Images(*.jpg)")
chunk = app.document.addChunk()
chunk.addPhotos(filelist)

for camera in chunk.cameras:
    camera.reference.enabled = False

chunk.crs = PhotoScan.CoordinateSystem()
# chunk.crs = PhotoScan.CoordinateSystem('LOCAL_CS["Local CS",LOCAL_DATUM["Local Datum",0],UNIT["metre",1]]')

chunk.matchPhotos(accuracy=PhotoScan.HighAccuracy, generic_preselection=True,reference_preselection=False)

chunk.alignCameras()
# PhotoScan.LowQuality
chunk.buildDepthMaps(quality=PhotoScan.HighQuality, filter=PhotoScan.AggressiveFiltering)
chunk.buildDenseCloud()
tempPointCloudPath = os.path.join(os.path.dirname(filelist[0]),"pc.txt")
chunk.exportPoints(tempPointCloudPath, format= PhotoScan.PointsFormat.PointsFormatXYZ, binary=False, precision=6, normals=False, colors=False)

f = open(tempPointCloudPath)
pointcloud = []
for line in f:
    point = list(map(lambda x: float(x), line.split()))
    pointcloud.append(point)
f.close()
Ejemplo n.º 12
0
    def __init__(self, parent):
        #_____________Пременные уровня класса___________
        self.OUT_dir = ''  #выходная дирректория
        self.orthoBounds = []
        # ВЫХОДНАЯ ПРОЕКЦИЯ по умолчанию
        #out_crs='PROJCS["WGS 84 / UTM zone 37N",GEOGCS["WGS 84",DATUM["World Geodetic System 1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9102"]],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator",AUTHORITY["EPSG","9807"]],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",39],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","32637"]]'
        self.out_crs = PhotoScan.CoordinateSystem(
            'PROJCS["WGS 84 / UTM zone 37N",GEOGCS["WGS 84",DATUM["World Geodetic System 1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9102"]],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator",AUTHORITY["EPSG","9807"]],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",39],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","32637"]]'
        )
        #out_crs=PhotoScan.CoordinateSystem('PROJCS["WGS 84 / UTM zone 38N",GEOGCS["WGS 84",DATUM["World Geodetic System 1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9102"]],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator",AUTHORITY["EPSG","9807"]],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",45],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","32638"]]')
        self.crsShapes = PhotoScan.CoordinateSystem(
            'PROJCS["WGS 84 / UTM zone 37N",GEOGCS["WGS 84",DATUM["World Geodetic System 1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9102"]],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator",AUTHORITY["EPSG","9807"]],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",39],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","32637"]]'
        )
        self.DATA_OK = 0
        #print ('orthoBounds=',len(self.orthoBounds))
        #формат массива:0-имя ортофото, 1-Xmin, 2-Ymin, 3-sizeX, 4-sizeY, 5-ID полигона
        #__________________________________________________

        QDialog.__init__(self, parent)
        self.setWindowTitle("Экспорт Орто по разграфке")  #Заголвок окна
        self.resize(500, 250)  #размер окна
        self.txt_comment = QLabel(
            "	Модуль экспортирует ортофото и DEM из фотоскана по нарезке. \
Нарезка в текстовом файле: название листа, координаты нижнего левого угла, размеры. \n	Проекция нарезки должна совпадать с проекцией выходного ортофотоплана.\
Листы делятся по нарезке, а внутри нарезки по блокам, размеры задаются. ФОРМАТ JPG \n	При импорте SHP должно быть текстовое поле NAME \n \
Адрес сервера: " + ServerIP +
            " меняем в теле программы. Ваша версия фотоскана: " + PH_version +
            " \n")
        self.txt_comment.setWordWrap(True)
        self.now_prj = QLabel(str(self.out_crs))
        self.select_prj = QPushButton("Выберете проекцию")  #(" открыть ")
        self.select_prj.setFixedSize(170, 26)

        self.TXT_dif_pix = QLabel("<B>Размер пикселя: </B>")
        self.TXT_dif_pix.setFixedSize(170, 26)
        self.dif_pix = QLineEdit()
        self.dif_pix.setText('0.1')  # Задает размер пикселя по умолчанию
        self.dif_pix.setFixedSize(100, 26)

        items_bloksize = ('5000', '8192', '10000', '15000', '20000', '25000',
                          '29999', 'Full')  # список с размерами тайлов
        #items_bloksize = {5000:5000, 8192:8192, 10000:10000, 15000:15000, 20000:20000, 25000:25000, 29999:29999}
        self.TXT_block_size = QLabel("<B>Размер блока: </B>", )
        self.TXT_block_size.setFixedSize(170, 26)
        self.block_size = QComboBox()
        self.block_size.setFixedSize(100, 26)
        self.block_size.addItems(items_bloksize)
        self.block_size.setCurrentIndex(
            1)  #Устанавливает по умолчанию второе значение из списка - 8192

        self.TXT_SHPname = QLabel("Файл разграфки SHP (NAME,poligons)")
        self.SHPname = QPushButton(
            "Выберете файл разграфки SHP")  #(" открыть ")
        self.SHPname.setFixedSize(170, 26)

        self.TXT_filename = QLabel(
            "Файл разграфки TXT(имя; X0; Y0; sizeX; SizeY)")
        self.filename = QPushButton("Выберете Файл разграфки")  #(" открыть ")
        self.filename.setFixedSize(170, 26)

        self.TXT_CheckOrthoDem = QLabel("Вид выходной продукции")
        self.TXT_CheckOrthoDem.setFixedSize(170, 26)
        self.CheckOrtho_Radio = QRadioButton("Ортофото")
        self.CheckOrtho_Radio.setChecked(True)
        self.CheckDem_Radio = QRadioButton("ДЕМ")

        self.TXT_OUTFOLDER = QLabel("Выходная дирректория")
        self.OUTFOLDER = QPushButton("Выберете дирректорию")  #(" открыть ")
        self.OUTFOLDER.setFixedSize(170, 26)

        items_format = (
            'JPG', 'TIF'
        )  # список форматов, ПРИ выборе ДЕМ будет выбран второй формат - внимательно при изменении списка!!!
        self.file_format = QComboBox()
        self.file_format.setFixedSize(50, 26)
        self.file_format.addItems(items_format)
        self.file_format.setCurrentIndex(
            0)  #Устанавливает по умолчанию первое значение

        self.TXT_checkExportOrtho = QLabel("Построить ортофото:")  # Ортофото
        self.TXT_checkExportOrtho.setFixedSize(170, 26)
        self.checkExportOrtho = QCheckBox()
        self.checkExportOrtho.setChecked(False)

        self.GoGo = QPushButton("Экспорт локально")  #(" Экспорт локально ")
        self.GoGo.setFixedSize(170, 26)
        self.GoGo.setDisabled(True)

        self.GoGoNet = QPushButton("Экспорт по сети")  #(" Экспорт по сети ")
        self.GoGoNet.setFixedSize(170, 26)
        self.GoGoNet.setDisabled(True)

        hbox0 = QHBoxLayout()
        hbox0.addWidget(self.txt_comment, alignment=0)

        hbox1 = QHBoxLayout()
        hbox1.addWidget(self.select_prj, alignment=0)
        hbox1.addWidget(self.now_prj, alignment=0)

        hbox2 = QHBoxLayout()
        hbox2.addWidget(self.TXT_block_size, alignment=1)
        hbox2.addWidget(self.block_size, alignment=1)

        hbox3 = QHBoxLayout()
        hbox3.addWidget(self.TXT_dif_pix, alignment=1)
        hbox3.addWidget(self.dif_pix, alignment=1)

        hbox4 = QHBoxLayout()
        #hbox4.addStretch(1)
        hbox4.addWidget(self.SHPname, alignment=0)
        hbox4.addWidget(self.TXT_SHPname, alignment=0)

        hbox5 = QHBoxLayout()
        #hbox5.addStretch(1)
        hbox5.addWidget(self.filename, alignment=0)
        hbox5.addWidget(self.TXT_filename, alignment=0)

        hbox51 = QHBoxLayout()
        hbox51.addWidget(self.TXT_CheckOrthoDem, alignment=0)
        hbox51.addWidget(self.CheckOrtho_Radio, alignment=0)
        hbox51.addWidget(self.CheckDem_Radio, alignment=0)

        hbox6 = QHBoxLayout()
        #hbox5.addStretch(1)
        hbox6.addWidget(self.OUTFOLDER, alignment=0)
        hbox6.addWidget(self.TXT_OUTFOLDER, alignment=0)
        hbox6.addWidget(self.file_format, alignment=0)

        hbox7 = QHBoxLayout()  #build ortho
        hbox7.addWidget(self.TXT_checkExportOrtho, alignment=0)
        hbox7.addWidget(self.checkExportOrtho, alignment=0)

        hbox8 = QHBoxLayout()
        hbox8.addWidget(self.GoGo, stretch=0, alignment=0)
        hbox8.addWidget(self.GoGoNet, stretch=0, alignment=0)

        vbox = QVBoxLayout()  #Определяем вбокс и забиваем его Нбоксами
        #vbox.addStretch(1)
        vbox.addLayout(hbox0)
        vbox.addLayout(hbox1)
        vbox.addLayout(hbox2)
        vbox.addLayout(hbox3)
        vbox.addLayout(hbox4)
        vbox.addLayout(hbox5)
        vbox.addLayout(hbox51)  #выбор, что строить орто или дем
        vbox.addLayout(hbox6)
        #Функция построения ортофото спрятана, поскольку работает не стабильно и построение ортофото для каждого листа в сумме занимает очень много времени,
        #гораздо больше, чем один раз построить ортофото для всех
        #vbox.addLayout(hbox7) #build ortho
        vbox.addLayout(hbox8)

        self.setLayout(vbox)

        self.select_prj.clicked.connect(self.set_projection)
        self.SHPname.clicked.connect(self.input_razgr_SHPname)
        self.filename.clicked.connect(self.input_razgr_name)
        self.OUTFOLDER.clicked.connect(self.input_out_dir)
        self.GoGo.clicked.connect(self.ortho_local)
        self.GoGoNet.clicked.connect(self.ortho_net)
        #Организация блокировки интерфейса для радио кнопок
        self.CheckOrtho_Radio.clicked.connect(self.CheckOrtho_Radio_DO)
        self.CheckDem_Radio.clicked.connect(self.CheckDem_Radio_DO)
        #____________
        self.checkExportOrtho.clicked.connect(
            self.PrintChkStat)  #Функция для проверки работы чека
        #self.WindowContextHelpButtonHint.clicked.connect(self.prog_hint)
        #self.WindowTitleHint.clicked.connect(self.prog_hint)

        self.exec()
Ejemplo n.º 13
0
 def __init__(self, epsg):
     print("InnoPAM")
     self.my_crs = PhotoScan.CoordinateSystem('EPSG::%s' % str(epsg))
Ejemplo n.º 14
0
#Need to set the following appropriately

#Path to photos
#photo_fn_path = "/tmp/export"
photo_fn_path = "/Volumes/SHEAN_PHOTO/photo/20140825_MammothTerraces_SfM/export_orig"
photo_fn_ext = "*.jpg"
#Path to ground control file, can contain orientation
gc_fn = "/tmp/gcp.txt"
#Path to calibration file
cal_fn = "/tmp/D800_cal.xml"
#This is the base fn for output files
#out_fn = "/tmp/test"
out_fn = os.path.join(photo_fn_path, "test")

#Define input coordinate system as WGS84
in_crs = PhotoScan.CoordinateSystem()
in_crs.init("EPSG::4326")
#Define output coordinate system as UTM 10N, WGS84
out_crs = PhotoScan.CoordinateSystem()
#out_crs.init("EPSG::32610")
#This is Yellowstone
out_crs.init("EPSG::32612")

#Add timestamp
print("Started")

#Create project file
doc = PhotoScan.app.document

#***
#NOTE: the following (loading photos, ground control, calibration, etc.) can be done manually
Ejemplo n.º 15
0
def process2(showReady=True):
    try:
        saveTimestamp("process2.01")
        ts = time.time()
        settings = QtCore.QSettings()
        print(u"[[processing2.start]]")
        saveTimestamp("process2.02")
        doc = PhotoScan.app.document
        activeChunk = doc.activeChunk
        if doc == None or activeChunk == None:
            PhotoScan.app.messageBox(u"[[error.noDocChunk]]")
            return False

        doc.meta['mavinci.plugin.release'] = mavinciRelease
        doc.meta['mavinci.plugin.exportHeaderCore'] = exportHeader

        qual = doc.meta['mavinci.quality']
        resolution = float(doc.meta['mavinci.resolution'])
        accuracy = float(doc.meta['mavinci.camAccuracy'])
        print(u"[[gpsAccuracyAssumption]]" % (accuracy))

        mavinciOptimize(False)

        saveTimestamp("process2.10")
        if qual != 'low':
            doc.save()
            saveTimestamp("process2.11")
            testOp(
                activeChunk.buildDenseCloud(
                    quality=qual,
                    gpu_mask=int(settings.value('main/opencl_mask', 0)),
                    cpu_cores_inactive=int(
                        settings.value('main/opencl_cores_inactive', 0))),
                u"[[buildDenseCloud]]")
            saveTimestamp("process2.12")
            #activeChunk.buildDepth(quality=qual,gpu_mask=1, cpu_cores_inactive=1)
            #activeChunk.buildModel(object='height field', geometry='sharp', faces=0)
            testOp(
                doc.activeChunk.buildModel(surface='height field',
                                           source='dense',
                                           interpolation='enabled',
                                           faces=qual), u"[[buildModel]]")
            saveTimestamp("process2.13")
            doc.save()
            saveTimestamp("process2.14")
            testOp(
                doc.activeChunk.buildTexture(mapping='orthophoto',
                                             blending='mosaic',
                                             size=4096), u"[[buildTexture]]")
            saveTimestamp("process2.15")
            doc.save()
            saveTimestamp("process2.16")
        else:
            testOp(
                doc.activeChunk.buildModel(surface='height field',
                                           source='sparse',
                                           interpolation='enabled',
                                           faces=qual), u"[[buildModel]]")
            saveTimestamp("process2.18")
            testOp(
                doc.activeChunk.buildTexture(mapping='orthophoto',
                                             blending='mosaic',
                                             size=2048), u"[[buildTexture]]")
            saveTimestamp("process2.19")

        saveTimestamp("process2.20")
        crs = PhotoScan.CoordinateSystem()
        projection = PhotoScan.GeoProjection()  #chunk projection in WGS84
        crs.init(doc.meta['mavinci.wkt'])
        projection.init(doc.meta['mavinci.wkt'])

        folder = os.path.abspath(os.path.join(doc.path, os.pardir))

        #we take coordinates of first photo (you can add a check that it's aligned),
        #then take small horizontal vectors along OX and OY
        #and calculate their

        orgProjection = doc.activeChunk.ground_control.projection
        doc.activeChunk.ground_control.projection = projection
        doc.activeChunk.ground_control.apply()

        crd = doc.activeChunk.ground_control.locations.items(
        )[0][1].coord  #coordinates of first photo

        #longitude
        v1 = PhotoScan.Vector((crd[0], crd[1], 0))
        v2 = PhotoScan.Vector((crd[0] + 0.01, crd[1], 0))

        vm1 = doc.activeChunk.projection.unproject(v1)
        vm2 = doc.activeChunk.projection.unproject(v2)

        res_x = (vm1 - vm2).norm() * 100

        #latitude
        v2 = PhotoScan.Vector((crd[0], crd[1] + 0.01, 0))
        vm2 = doc.activeChunk.projection.unproject(v2)

        doc.activeChunk.ground_control.projection = orgProjection
        doc.activeChunk.ground_control.apply()

        res_y = (vm1 - vm2).norm() * 100

        pixel_x = pixel_y = resolution  #export resolution 50cm/pix
        d_x = pixel_x / res_x
        d_y = pixel_y / res_y

        print(u"d_x=%e  d_y=%e" % (d_x, d_y))

        vertices = activeChunk.model.vertices
        maxSamples = 100000
        step = 1
        if len(vertices) > maxSamples * step:
            step = int(len(vertices) / maxSamples)
        xmin = float('inf')
        xmax = -1 * float('inf')
        ymin = float('inf')
        ymax = -1 * float('inf')

        for i in range(0, len(vertices), step):
            v = vertices[i].coord
            v.size = 4
            v.w = 1
            v_t = activeChunk.transform * v
            v_t.size = 3

            v_new = activeChunk.crs.project(v_t)
            if v_new.x < xmin:
                xmin = v_new.x

            if v_new.x > xmax:
                xmax = v_new.x

            if v_new.y < ymin:
                ymin = v_new.y

            if v_new.y > ymax:
                ymax = v_new.y

        print("x=%f < %f  y=%f < %f" % (xmin, xmax, ymin, ymax))

        v0 = PhotoScan.Vector((xmin, ymin, 0))
        vX = PhotoScan.Vector((xmax, ymin, 0))
        vY = PhotoScan.Vector((xmin, ymax, 0))

        vm0 = doc.activeChunk.projection.unproject(v0)
        vmX = doc.activeChunk.projection.unproject(vX)
        vmY = doc.activeChunk.projection.unproject(vY)

        size_x = (vm0 - vmX).norm()
        size_y = (vm0 - vmY).norm()

        print("x-size=%f m  y-size=%f m" % (size_x, size_y))

        maxPix = 30000
        maxPixDem = maxPix
        blockOffset = 0.2

        pixX = math.ceil(size_x / resolution)
        pixY = math.ceil(size_y / resolution)
        pixXdem = math.ceil(size_x / (2 * resolution))
        pixYdem = math.ceil(size_y / (2 * resolution))

        print("x-pix=%i  y-pix=%i" % (pixX, pixY))
        print("x-pixDEM=%i  y-pixDEM=%i" % (pixXdem, pixYdem))

        blockCountX = math.ceil(pixX / maxPix + blockOffset)
        blockCountY = math.ceil(pixY / maxPix + blockOffset)

        blockCountXdem = math.ceil(pixXdem / maxPixDem + blockOffset)
        blockCountYdem = math.ceil(pixYdem / maxPixDem + blockOffset)

        print("blockCount x=%i  y=%i" % (blockCountX, blockCountY))
        print("blockCountDEM x=%i  y=%i" % (blockCountXdem, blockCountYdem))

        doc.meta['mavinci.blockCount.ortho'] = "%i:%i" % (blockCountX,
                                                          blockCountY)
        doc.meta['mavinci.blockCount.dem'] = "%i:%i" % (blockCountXdem,
                                                        blockCountYdem)

        blockw = math.ceil(pixX / blockCountX)
        blockh = math.ceil(pixY / blockCountY)

        blockwDEM = math.ceil(pixXdem / blockCountXdem)
        blockhDEM = math.ceil(pixYdem / blockCountYdem)

        print("block w=%i  h=%i" % (blockw, blockh))
        print("blockDEM w=%i  h=%i" % (blockwDEM, blockhDEM))

        reportPath = os.path.join(folder, 'report.pdf')
        saveTimestamp("process2.21")
        testOp(activeChunk.exportReport(reportPath), u"[[exportReport]]")
        saveTimestamp("process2.22")
        openFile(reportPath)

        saveTimestamp("process2.23")

        if blockCountX > 1 or blockCountY > 1:
            testOp(
                activeChunk.exportOrthophoto(
                    os.path.join(folder, 'ortho.tif'),
                    format='tif',
                    blending='mosaic',
                    color_correction=doc.meta['mavinci.enableColCorrection'] !=
                    '0',
                    projection=crs,
                    dx=d_x,
                    dy=d_y,
                    write_kml=False,
                    write_world=True,
                    blockw=blockw,
                    blockh=blockh), u"[[exportOrthophoto]]")
        else:
            testOp(
                activeChunk.exportOrthophoto(
                    os.path.join(folder, 'ortho.tif'),
                    format='tif',
                    blending='mosaic',
                    color_correction=doc.meta['mavinci.enableColCorrection'] !=
                    '0',
                    projection=crs,
                    dx=d_x,
                    dy=d_y,
                    write_kml=False,
                    write_world=True), u"[[exportOrthophoto]]")

        saveTimestamp("process2.24")
        if blockCountXdem > 1 or blockCountYdem > 1:
            testOp(
                activeChunk.exportDem(os.path.join(folder, 'dem.tif'),
                                      format='tif',
                                      projection=crs,
                                      dx=2 * d_x,
                                      dy=2 * d_y,
                                      write_world=True,
                                      blockw=blockwDEM,
                                      blockh=blockhDEM), u"[[exportDem]]")
        else:
            testOp(
                activeChunk.exportDem(os.path.join(folder, 'dem.tif'),
                                      format='tif',
                                      projection=crs,
                                      dx=2 * d_x,
                                      dy=2 * d_y,
                                      write_world=True), u"[[exportDem]]")

        saveTimestamp("process2.25")
        doc.save()
        saveTimestamp("process2.26")
        openFile(folder)

        saveTimestamp("process2.27")
        t = str(datetime.timedelta(seconds=round(time.time() - ts)))
        print(u"[[processing2.ready]]" % t)
        if showReady:
            PhotoScan.app.messageBox(u"[[processing2.ready]]" % t)
        return True

    except (KeyboardInterrupt, SystemExit):
        print('>>> INTERRUPTED BY USER <<<')
        return False
    except:
        e = sys.exc_info()[0]
        print(e)
        print('>>> traceback <<<')
        traceback.print_exc()
        print('>>> end of traceback <<<')
        PhotoScan.app.messageBox(u"[[error]]")
        return False
Ejemplo n.º 16
0
def main(root_path, image_folder):

    # PhotoScan.app.messageBox('hello world! \n')
    # PhotoScan.app.console.clear()
    # PhotoScan.app.gpu_mask = 1
    """1: creat project"""
    doc = createOrOpenProject(root_path, image_folder)
    """2: creat chunk"""
    chunk = PhotoScan.Chunk

    if len(doc.chunks) > 0:
        chunk = doc.chunk
        logAction("Using the existing chunk '{}'".format(chunk.label))
    else:
        chunk = doc.addChunk()
        chunk.crs = PhotoScan.CoordinateSystem("EPSG::4326")
        logAction("Created the new chunk '{}'".format(chunk.label))

    if len(chunk.cameras) > 0:
        logAction(
            "Skipping adding photos and aligning cameras because chunk already has {} cameras"
            .format(len(chunk.cameras)))
    else:
        logAction("Started adding photos")
        t = datetime.datetime.now()
        addPhotos(chunk, image_folder)
        logAction("Added photos ({})".format(datetime.datetime.now() - t))

        logAction("Started photos alignment")
        t = datetime.datetime.now()
        """3: alignPhotos"""
        alignPhotos(chunk)
        logAction("Aligned photos ({})".format(datetime.datetime.now() - t))
        saveProject(doc)
    """4:Create point cloud"""
    if chunk.dense_cloud is None:
        logAction("Started buildling dense cloud")
        t = datetime.datetime.now()
        buildDenseCloud(chunk)
        logAction("Built dense cloud ({})".format(datetime.datetime.now() - t))
        saveProject(doc)
    else:
        logAction(
            "Skipping dense cloud build because chunk already has {}".format(
                chunk.dense_cloud))
    """5:buildsource"""
    logAction("Started buildling source")
    t = datetime.datetime.now()
    buildsource(chunk)
    logAction("Built source ({})".format(datetime.datetime.now() - t))
    saveProject(doc)
    """6: buildtexture"""
    logAction("Started buildling texture")
    t = datetime.datetime.now()
    buildtexture(chunk)
    logAction("Built texture ({})".format(datetime.datetime.now() - t))
    saveProject(doc)
    """7: buildorthomosaic"""
    logAction("Started buildling orthomosaic")
    t = datetime.datetime.now()
    buildOrtho(chunk)
    logAction("Built orthomosaic ({})".format(datetime.datetime.now() - t))
    saveProject(doc)
    """8: exporting orthomosaic"""
    logAction("Started exporting orthomosaic")
    t = datetime.datetime.now()
    out_image_name = image_name(image_folder)
    exportOrtho(chunk, root_path, out_image_name)
    logAction("Exported orthomosaic ({})".format(datetime.datetime.now() - t))
Ejemplo n.º 17
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
Ejemplo n.º 18
0
 def export_geo(self):
     """
     Export LAS, DEM and Ortho to path using the file name prefix
     
     Ortho file format is JPG for JPG input images and TIF for all others, 
         unless the resulting JPG is > 65535 pixels, in which case a TIF will 
         be used.
     """
     jpg_limit = 65535
     for _ in self.chunks:
         ext = _.cameras[0].label[-3:]
         if self.exp_crs == 0:
             crs = _.crs
         else:
             crs = PhotoScan.CoordinateSystem('EPSG::{}'
                     .format(self.exp_crs))
         #write log information
         with open(self.log, 'a+') as logfile:
             start_t =  datetime.now()
             logfile.write('Exporting geo {} at {} \n'.
                                         format(_, 
                                             start_t.strftime('%H:%M:%S')))
             logfile.write('    Export CRS: {}\n'.
                                         format(crs))
         #check if input is JPG and below the limit            
         if (ext.upper() == 'JPG' 
             and not (_.orthomosaic.width > jpg_limit 
                     or _.orthomosaic.height > jpg_limit)):
             ext = 'jpg'
         else:
             ext = 'tif'
         if str(_)[8:-4] == 'Chunk':
             name = ''
             num = str(_)[-3]
         else:
             name = str(_)[8:-2]
             num = ''
         try:
             print('las crs: {}'.format(crs))
             file = '{}{}_LAS{}.las'.format(self.prefix, name, num)
             _.exportPoints(path = os.path.join(self.path, file),
                             format=PhotoScan.PointsFormatLAS,
                             projection=crs)
         except RuntimeError as e:
             if str(e) == 'Null point cloud':
                 print('There is no point cloud to export in chunk: {}'
                         .format(_))
                 continue
             else:
                 raise
         try:
             file = '{}{}_DSM{}.tif'.format(self.prefix, name, num)
             _.exportDem(path = os.path.join(self.path, file), 
                         write_world = True,
                         projection=crs)
         except RuntimeError as e:
             if str(e) == 'Null elevation':
                 print('There is no elevation to export in chunk: {}'
                         .format(_))
                 continue
             else:
                 raise
         try:
             file = '{}{}_Ortho{}.{}'.format(self.prefix, name, num, ext)
             _.exportOrthomosaic(path = os.path.join(self.path, file), 
                                 write_world = True,
                                 projection=crs)
         except RuntimeError as e:
             if str(e) == 'Null orthomosaic':
                 print('There is no orthomosaic to export in chunk: {}'
                         .format(_))
                 continue
             else:
                 raise
Ejemplo n.º 19
0
os.chdir(HomeDirectory)
print("Home directory: " + HomeDirectory)

# get main app objects
doc = PhotoScan.app.document
app = PhotoScan.Application()

# create chunk
chunk = PhotoScan.Chunk()
chunk.label = "New_Chunk"
doc.chunks.add(chunk)

# SET COORDINATE SYSTEM
print("---Settings coordinate system...")
# init coordinate system object
CoordinateSystem = PhotoScan.CoordinateSystem()
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
Ejemplo n.º 20
0
## author: Chia-Ching Lin             ##
##                                    ##
## 專案CHUNK名字必須與155上資料夾一致 ##
########################################
import os, sys, zipfile, pathlib,  datetime, shutil, subprocess
import PhotoScan, chardet
from tkinter.filedialog import *
from bs4 import BeautifulSoup
from subprocess import PIPE
from ftplib import FTP
import xml.etree.ElementTree as ET
from xml.dom import minidom


# 前置設定參數
tw97   = PhotoScan.CoordinateSystem("EPSG::3826")
ws84   = PhotoScan.CoordinateSystem("EPSG::3857")
ds84  = PhotoScan.CoordinateSystem("EPSG::4326") 
crs    = PhotoScan.CoordinateSystem('LOCAL_CS["Local CS",LOCAL_DATUM["Local Datum",0],UNIT["metre",1]]')


path = r'\\140.116.228.155\geodac_uav\2019'
dir  = r'C:\Users\RSLAB\Desktop\dir\\'

dir_1   = '1.測繪產品'
dir_1_1 = '1.1.Ortho_正射影像(包含附加檔)'
dir_1_2 = '1.2.OrigPhoto_原始照片'
dir_1_3 = '1.3.PrecEval_精度評估報告'
dir_1_4 = '1.4.ContCoor_控制點座標)'
dir_1_5 = '1.5.ContPhoto_控制點照片'
dir_1_6 = '1.6.FlyRec_飛行記錄'
Ejemplo n.º 21
0
class Agisoft:
    EXPORT_IMAGE_TYPE = '.tif'
    IMPORT_IMAGE_TYPE = '.tif'
    PROJECT_TYPE = '.psx'
    PROJECT_REPORT = '.pdf'
    REFERENCE_FILE = 'images_metadata.csv'

    WGS_84 = PhotoScan.CoordinateSystem("EPSG::4326")
    UTM_CA = PhotoScan.CoordinateSystem("EPSG::32611")
    UTM_CO = PhotoScan.CoordinateSystem("EPSG::32613")
    X_1M_IN_DEG = 1.13747e-05  # 1m in degree using EPSG:4326
    Y_1M_IN_DEG = 9.0094e-06   #
    X_5M_IN_DEG = 5.76345e-05  # 5m in degree using EPSG:4326
    Y_5M_IN_DEG = 4.50396e-05  #

    IMAGE_ACCURACY_MATCHING = PhotoScan.HighestAccuracy
    KEYPOINT_LIMIT = 40000
    TIEPOINT_LIMIT = 4000

    REPROJECTION_ERROR_THRESHOLD = 0.3
    REPROJECTION_ACCURACY_THRESHOLD = 10

    DENSE_POINT_QUALITY = dict(
        high=PhotoScan.HighQuality,
        medium=PhotoScan.MediumQuality,
    )

    EXPORT_DEFAULTS = dict(
        image_format=PhotoScan.ImageFormat.ImageFormatTIFF,
        projection=WGS_84,
        dx=X_1M_IN_DEG,
        dy=Y_1M_IN_DEG,
    )

    def __init__(self, options):
        # Ensure trailing slash
        self.project_base_path = os.path.join(options.base_path, '')
        self.project_file_name = self.project_file_path(options.project_name)

        self.setup_application()

        self.create_new_project()
        self.project = PhotoScan.app.document
        self.project.open(self.project_file_name + self.PROJECT_TYPE)
        self.chunk = self.project.chunk

        self.setup_camera()

        self.image_folder = os.path.join(
            self.project_base_path, options.image_folder, ''
        )
        self.image_type = options.image_type

    def create_new_project(self):
        if not os.path.exists(path=self.project_file_name + self.PROJECT_TYPE):
            new_project = PhotoScan.Document()
            chunk = new_project.addChunk()
            new_project.save(
                path=self.project_file_name + self.PROJECT_TYPE,
                chunks=[chunk]
            )

    def project_file_path(self, project_name):
        run_date = datetime.date.today().strftime('%Y_%m_%d')
        project_name = project_name + '_' + run_date
        return os.path.join(
            self.project_base_path, project_name
        )

    def setup_application(self):
        app = PhotoScan.Application()
        # Use all available GPUs, needs a bit mask
        number_of_gpus = len(PhotoScan.app.enumGPUDevices())
        mask = int(str('1' * number_of_gpus).rjust(8, '0'), 2)
        app.gpu_mask = mask
        # Allow usage of CPU and GPU
        app.cpu_enable = True

        settings = PhotoScan.Application.Settings()
        # Logging
        settings.log_enable = True
        settings.log_path = self.project_file_name + '_agisoft.log'
        settings.save()

    def setup_camera(self):
        # Imported camera coordinates projection
        self.chunk.crs = self.WGS_84
        # Accuracy for camera position in m
        self.chunk.camera_location_accuracy = PhotoScan.Vector([1, 1, 1])
        # Accuracy for camera orientations in degree
        self.chunk.camera_rotation_accuracy = PhotoScan.Vector([1, 1, 1])

    def save_and_exit(self):
        self.project.save()
        sys.exit(-1)

    def image_list(self):
        images = glob.glob(
            self.image_folder + '**/*' + self.image_type, recursive=True
        )
        if len(images) == 0:
            print('**** EXIT - ' + self.image_type +
                  ' no files found in directory:')
            print('    ' + self.image_folder)
            self.save_and_exit()
        else:
            return images

    def check_reference_file(self, file):
        """
        Check that the given reference file exists and has the image types
        loaded with this project by comparing file endings.
        """
        if os.path.exists(file):
            with open(file) as file:
                next(file)  # skip header line
                first_file = next(file).split(',')[0]
                if not first_file.endswith(self.image_type):
                    print('**** Reference file has different '
                          'source image types *****\n'
                          '   given: ' + self.image_type + '\n'
                          '   first image: ' + first_file)
                    self.save_and_exit()
        else:
            print('**** EXIT - No reference file found ****')
            self.save_and_exit()

    def load_image_references(self):
        reference_file = self.project_base_path + self.REFERENCE_FILE
        self.check_reference_file(reference_file)
        self.chunk.loadReference(
            path=reference_file,
            delimiter=',',
            format=PhotoScan.ReferenceFormatCSV,
        )

    def align_images(self):
        self.chunk.addPhotos(self.image_list())
        self.load_image_references()
        self.chunk.matchPhotos(
            accuracy=self.IMAGE_ACCURACY_MATCHING,
            generic_preselection=True,
            reference_preselection=True,
            keypoint_limit=self.KEYPOINT_LIMIT,
            tiepoint_limit=self.TIEPOINT_LIMIT,
        )
        self.chunk.alignCameras()
        self.project.save()

    def remove_by_criteria(self, criteria, threshold):
        point_cloud_filter = PhotoScan.PointCloud.Filter()
        point_cloud_filter.init(self.chunk, criterion=criteria)
        point_cloud_filter.removePoints(threshold)

    def filter_sparse_cloud(self):
        # Points that statistical error in point placement exceed threshold
        self.remove_by_criteria(
            PhotoScan.PointCloud.Filter.ReprojectionError,
            self.REPROJECTION_ERROR_THRESHOLD,
        )
        # Points that accuracy of point placement from local neighbor points
        # exceed threshold
        self.remove_by_criteria(
            PhotoScan.PointCloud.Filter.ProjectionAccuracy,
            self.REPROJECTION_ACCURACY_THRESHOLD,
        )

    def build_dense_cloud(self, dense_cloud_quality):
        self.chunk.buildDepthMaps(
            quality=self.DENSE_POINT_QUALITY.get(dense_cloud_quality, 'high'),
            filter=PhotoScan.AggressiveFiltering,
        )
        self.chunk.buildDenseCloud()
        self.project.save()

    def export_results(self):
        self.chunk.exportDem(
            path=self.project_file_name + '_dem' + self.EXPORT_IMAGE_TYPE,
            **self.EXPORT_DEFAULTS
        )
        self.chunk.exportOrthomosaic(
            path=self.project_file_name + self.EXPORT_IMAGE_TYPE,
            tiff_big=True,
            **self.EXPORT_DEFAULTS
        )
        self.chunk.exportReport(self.project_file_name + self.PROJECT_REPORT)

    def process(self, options):
        self.align_images()
        self.filter_sparse_cloud()
        self.build_dense_cloud(options.dense_cloud_quality)

        self.chunk.buildDem()
        self.chunk.buildOrthomosaic()
        self.project.save()

        if options.with_export:
            self.export_results()
Ejemplo n.º 22
0
def main(root_path, image_folder):
    # PhotoScan.app.messageBox('hello world! \n')
    # PhotoScan.app.console.clear()
    # PhotoScan.app.gpu_mask = 1

    doc = createOrOpenProject(root_path, image_folder)

    chunk = PhotoScan.Chunk
    if len(doc.chunks) > 0:
        chunk = doc.chunk
        logAction("Using the existing chunk '{}'".format(chunk.label))
    else:
        chunk = doc.addChunk()
        chunk.crs = PhotoScan.CoordinateSystem("EPSG::4326")
        logAction("Created the new chunk '{}'".format(chunk.label))

    if len(chunk.cameras) > 0:
        logAction(
            "Skipping adding photos and aligning cameras because chunk already has {} cameras"
            .format(len(chunk.cameras)))
    else:
        logAction("Started adding photos")
        t = datetime.datetime.now()
        addPhotos(chunk, root_path)
        logAction("Added photos ({})".format(datetime.datetime.now() - t))

        logAction("Started photos alignment")
        t = datetime.datetime.now()
        alignPhotos(chunk)
        logAction("Aligned photos ({})".format(datetime.datetime.now() - t))
        saveProject(doc)

    ################################################################################################
    if chunk.dense_cloud is None:
        logAction("Started buildling dense cloud")
        t = datetime.datetime.now()
        buildDenseCloud(chunk)
        logAction("Built dense cloud ({})".format(datetime.datetime.now() - t))
        saveProject(doc)
    else:
        logAction(
            "Skipping dense cloud build because chunk already has {}".format(
                chunk.dense_cloud))

    ################################################################################################
    # logAction("Started buildling DEM")
    # t = datetime.datetime.now()
    # buildDEM(chunk)
    # logAction("Built DEM ({})".format(datetime.datetime.now() - t))
    # saveProject(doc)

    ################################################################################################
    logAction("Started buildling orthomosaic")
    t = datetime.datetime.now()
    buildOrtho(chunk)
    logAction("Built orthomosaic ({})".format(datetime.datetime.now() - t))
    saveProject(doc)

    logAction("Started exporting orthomosaic")
    t = datetime.datetime.now()
    out_image_name = image_name(image_folder)
    exportOrtho(chunk, root_path, out_image_name)
    logAction("Exported orthomosaic ({})".format(datetime.datetime.now() - t))

    logAction("Started exporting dem")
    t = datetime.datetime.now()
    exportDem(chunk, root_path)
    logAction("Exported dem ({})".format(datetime.datetime.now() - t))
Ejemplo n.º 23
0
try:
    os.makedirs(workingPath + "pointcloud")
    print("Creating Point Cloud Directory.")
except OSError as exception:
    if exception.errno != errno.EEXIST:
        raise

project = workingPath + "ortho_dem_process.psx"

app = PhotoScan.Application()
doc = PhotoScan.app.document
doc.open(project)

chunk = doc.chunk
chunk.crs = PhotoScan.CoordinateSystem("EPSG::4326")

if int(pcTF) > 0:
    chunk.exportPoints(
        path=workingPath + "pointcloud\\dpc.txt",
        binary=False,
        precision=8,
        normals=False,
        colors=True,
        raster_transform=PhotoScan.RasterTransformType.RasterTransformNone,
        format=PhotoScan.PointsFormat.PointsFormatXYZ,
        projection=PhotoScan.CoordinateSystem("EPSG::4326"))
else:
    chunk.exportPoints(
        path=workingPath + "pointcloud\\dpc.txt",
        binary=False,
Ejemplo n.º 24
0
def process(images_path, output_path, reference_path, model_name):

    # Font settings
    os.environ['QT_QPA_FONTDIR'] = '/usr/share/fonts/truetype/dejavu/'

    # Below code was to enable all available GPUs, was throwing an error.
    #PhotoScan.app.gpu_mask = 2 ** len(PhotoScan.app.enumGPUDevices()) - 1 #setting GPU mask

    PhotoScan.app.gpu_mask = 3  # gpu_mask is a bitmask. 3 in binary = 11 so only two GPUs are used.
    if PhotoScan.app.gpu_mask:
        PhotoScan.app.cpu_enable = False
    else:
        PhotoScan.app.cpu_enable = True

    ### Processing parameters
    accuracy = PhotoScan.Accuracy.HighAccuracy  #align photos accuracy
    reference_preselection = False
    generic_preselection = True
    keypoints = 40000  # Align photos key point limit
    tiepoints = 4000  # Align photos tie point limit
    source = PhotoScan.DataSource.DenseCloudData  # Build mesh/DEM source
    surface = PhotoScan.SurfaceType.Arbitrary  # Build mesh surface type
    quality = PhotoScan.Quality.MediumQuality  # Build dense cloud quality
    filtering = PhotoScan.FilterMode.AggressiveFiltering  # Depth filtering
    interpolation = PhotoScan.Interpolation.EnabledInterpolation  # Build mesh interpolation
    mosaic_blending = PhotoScan.BlendingMode.MosaicBlending  # Blending mode
    average_blending = PhotoScan.BlendingMode.AverageBlending
    disabled_blending = PhotoScan.BlendingMode.DisabledBlending

    face_num = PhotoScan.FaceCount.HighFaceCount  # Build mesh polygon count
    mapping = PhotoScan.MappingMode.GenericMapping  #Build texture mapping
    atlas_size = 4096
    TYPES = ["jpg", "jpeg", "tif", "tiff", "png"]

    # Load images into master list of fore and aft.
    list_photos_master = load_images(TYPES, images_path)

    # Create PhotoScan document
    project_file = os.path.join(output_path, "Model.psx")
    doc = PhotoScan.Document()
    doc.save(project_file)
    chunk = doc.addChunk()
    chunk.label = model_name

    print("Saving PhotoScan project to: ", project_file)
    print("Chunk label: ", str(chunk.label))

    # Add Images to Chunk
    chunk.addPhotos(list_photos_master)

    # Load ref file.
    chunk.loadReference(path=reference_path,
                        format=PhotoScan.ReferenceFormat.ReferenceFormatCSV,
                        columns='zanxy',
                        delimiter=',')

    # Set coordinate system for lat lon values.
    chunk.crs = PhotoScan.CoordinateSystem("EPSG::4326")

    # TODO Load calibration parameters from file

    # Create Sensor definitions
    sensor_fore = chunk.addSensor()
    sensor_fore.label = "Fore Sensor"
    sensor_fore.type = PhotoScan.Sensor.Type.Frame
    sensor_fore.width = chunk.cameras[-1].sensor.width
    sensor_fore.height = chunk.cameras[-1].sensor.height
    sensor_fore.pixel_size = [0.00345, 0.00345]
    sensor_fore.focal_length = 6.7  # Focal length is 10.4mm, 14.6mm effective length in water.
    sensor_fore.antenna.location_ref = PhotoScan.Vector([0.38, 0, 0.25])

    sensor_aft = chunk.addSensor()
    sensor_aft.label = "Aft Sensor"
    sensor_aft.type = PhotoScan.Sensor.Type.Frame
    sensor_aft.width = chunk.cameras[-1].sensor.width
    sensor_aft.height = chunk.cameras[-1].sensor.height
    sensor_aft.pixel_size = [0.00345, 0.00345]
    sensor_aft.focal_length = 6.7
    sensor_aft.antenna.location_ref = PhotoScan.Vector([0.53, 0, 0.25])

    for camera in chunk.cameras:
        if "F" in camera.label:
            camera.sensor = sensor_fore
            print("Added ", camera.label, "to fore group")
        elif "A" in camera.label:
            camera.sensor = sensor_aft
            print("Added ", camera.label, "to aft group")
        else:
            print("No sensor defined for ", camera.label)

    # Add scalebars between stereo images
    # This is the baseline between two cameras.
    # Iver3 system is 6" baseline, 0.1524 meters.
    index = 0
    while (True):
        scalebar = chunk.addScalebar(chunk.cameras[index],
                                     chunk.cameras[index + 1])
        scalebar.reference.distance = 0.1524
        index += 2
        if index >= len(chunk.cameras):
            break

    ### Estimate image quality
    chunk.estimateImageQuality(chunk.cameras)
    badImages = 0
    #for camera in chunk.cameras:
    #	if float(camera.photo.meta["Image/Quality"]) < 0.5:
    #		camera.enabled = False
    #		badImages+=1
    print("Removed ", badImages, " from chunk")

    ### Align photos
    chunk.matchPhotos(accuracy=accuracy,
                      generic_preselection=generic_preselection,
                      reference_preselection=reference_preselection,
                      filter_mask=False,
                      keypoint_limit=keypoints,
                      tiepoint_limit=tiepoints,
                      progress=progress_print)

    chunk.alignCameras()
    chunk.optimizeCameras()
    chunk.resetRegion()
    doc.read_only = False
    doc.save()

    ###building dense cloud
    chunk.buildDepthMaps(quality=quality,
                         filter=filtering,
                         progress=progress_print)
    chunk.buildDenseCloud(point_colors=True, progress=progress_print)
    doc.save()

    ###building mesh
    chunk.buildModel(surface=surface,
                     source=source,
                     interpolation=interpolation,
                     face_count=face_num,
                     progress=progress_print)
    doc.save()

    ###build texture
    chunk.buildUV(mapping=mapping, count=1, progress=progress_print)
    chunk.buildTexture(blending=mosaic_blending,
                       size=atlas_size,
                       progress=progress_print)
    doc.save()

    ###export model
    chunk.exportModel(path=os.path.join(output_path, chunk.label + ".obj"),
                      binary=False,
                      texture_format=PhotoScan.ImageFormatJPEG,
                      texture=True,
                      normals=False,
                      colors=False,
                      cameras=False,
                      format=PhotoScan.ModelFormatOBJ)

    ### Export GeoTiff file
    chunk.buildDem(source=source,
                   interpolation=interpolation,
                   projection=chunk.crs,
                   progress=progress_print)
    chunk.exportDem(
        path=os.path.join(output_path, chunk.label + '_DEM.jpeg'),
        image_format=PhotoScan.ImageFormat.ImageFormatJPEG,
        raster_transform=PhotoScan.RasterTransformType.RasterTransformPalette,
        projection=chunk.crs,
        nodata=-32767,
        write_kml=True,
        write_world=True,
        write_scheme=True,
        tiff_big=True)

    # Export orthomosaic
    chunk.buildOrthomosaic(surface=PhotoScan.DataSource.ElevationData,
                           blending=mosaic_blending,
                           fill_holes=True)
    chunk.exportOrthomosaic(path=os.path.join(
        output_path,
        chunk.label + '_' + str(mosaic_blending) + '_orthomosaic.tif'),
                            projection=chunk.crs)

    chunk.buildOrthomosaic(surface=PhotoScan.DataSource.ElevationData,
                           blending=average_blending,
                           fill_holes=True)
    chunk.exportOrthomosaic(path=os.path.join(
        output_path,
        chunk.label + '_' + str(average_blending) + '_orthomosaic.tif'),
                            projection=chunk.crs)

    chunk.buildOrthomosaic(surface=PhotoScan.DataSource.ElevationData,
                           blending=disabled_blending,
                           fill_holes=True)
    chunk.exportOrthomosaic(path=os.path.join(
        output_path,
        chunk.label + '_' + str(disabled_blending) + '_orthomosaic.tif'),
                            projection=chunk.crs)

    ### Export camera poses
    export_camera_pose(
        chunk, os.path.join(output_path, chunk.label + '_camera_pose.csv'))

    ### Generate report
    chunk.exportReport(os.path.join(output_path, chunk.label + '_report.pdf'))
    print("Processed " + chunk.label)
    return True
# precision is not lost when coordinates are saved as floats. The offset will be subtracted from point coordinates.
# [RECOMMENDED] - Leave as NaN; the script will automatically calculate and apply a suitable offset, which will be saved
# as a text file for further processing, OR edit the line to impose a specific offset of your choice -
# e.g.  pts_offset = PhotoScan.Vector( [266000, 4702000, 0] )
pts_offset = PhotoScan.Vector([NaN, NaN, NaN])

###################################   END OF SETUP   ###################################
########################################################################################
# Initialisation
chunk = PhotoScan.app.document.chunk
point_proj = chunk.point_cloud.projections

# Need CoordinateSystem object, but PS only returns 'None' if an arbitrary coordinate system is being used
# thus need to set manually in this case; otherwise use the Chunk coordinate system.
if chunk.crs == None:
    crs = PhotoScan.CoordinateSystem(
        'LOCAL_CS["Local CS",LOCAL_DATUM["Local Datum",0],UNIT["metre",1]]')
    chunk.crs = crs
else:
    crs = chunk.crs

# Find which markers are enabled for use as control points in the bundle adjustment
act_marker_flags = []
for marker in chunk.markers:
    act_marker_flags.append(marker.reference.enabled)
num_act_markers = sum(act_marker_flags)

# Write the active marker flags to a text file - one line per BA iteration
# This is actually relict code and not strictly needed.
with open(dir_path + act_ctrl_file, 'w') as f:
    fwriter = csv.writer(f, delimiter=' ', lineterminator='\n')
    for line_ID in range(0, num_randomisations):
# Which will be calculated later
Max_Angle = 13
Cell_Size = 10
#
# Variable for building orthomosaic
# Since 1.4.0, users can choose performing color correction (vignetting) and balance separately.
# Blending: AverageBlending, MosaicBlending, MinBlending, MaxBlending, DisabledBlending
# Color_correction: True, False
# Color_balance: True, False
BlendingMode = PhotoScan.BlendingMode.MosaicBlending
Color_correction = True
Color_balance = False
#
#######################################################

wgs_84 = PhotoScan.CoordinateSystem("EPSG::4326")


def AlignPhoto(chunk, Accuracy, Key_Limit, Tie_Limit):
    chunk.matchPhotos(accuracy=Accuracy,
                      generic_preselection=True,
                      reference_preselection=True,
                      filter_mask=False,
                      keypoint_limit=Key_Limit,
                      tiepoint_limit=Tie_Limit)
    chunk.alignCameras(adaptive_fitting=True)


def BuildDenseCloud(chunk, Quality, FilterMode):
    try:
        chunk.buildDenseCloud(quality=Quality,
Ejemplo n.º 27
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
Ejemplo n.º 28
0
import PhotoScan
import os
from math import ceil
chunk = PhotoScan.app.document.chunk
# ВЫХОДНАЯ ПРОЕКЦИЯ - Краснодарская первый варинат, без номера зоны
out_crs = PhotoScan.CoordinateSystem(
    'PROJCS["SK-42/GK_ZONE7_noZone (var1)",GEOGCS["Pulkovo 1942",DATUM["Pulkovo 1942",SPHEROID["Krassowsky 1940",6378245,298.3,AUTHORITY["EPSG","7024"]],TOWGS84[82.28,-123.01,-138.08,1.07,-2.371,1.15,1.867],AUTHORITY["EPSG","----"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9102"]],AUTHORITY["EPSG","----"]],PROJECTION["Transverse_Mercator",AUTHORITY["EPSG","9807"]],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",39],PARAMETER["scale_factor",1],PARAMETER["false_easting",7500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]]]'
)
# предварительные настройки
difX = 0.15
difY = 0.15
sizeXM = 1000.05
sizeYM = 1000.05
sizeXMpix = ceil(sizeXM / difX)
sizeYMpix = ceil(sizeYM / difY)
#if sizeXMpix%2: sizeXMpix=sizeXMpix+1
#if sizeYMpix%2: sizeYMpix=sizeYMpix+1
sizeXMround = sizeXMpix * difX
sizeYMround = sizeYMpix * difY
# КООРДИАНТЫ ДОЛЖНЫ БЫТЬ В ВЫХОДНОЙ ПРОЕКЦИИ!!!!!
FileRazgr = os.path.dirname(__file__) + "/orthoexport_full_file_razgrafka.txt"

#ЗДЕСЬ ПОМЕНЯТЬ ПУТИ!!!
OFolder = "v:\\Photoscan_Cluster\\test_test\\Ortho\\"

with open(FileRazgr) as file_razgr:
    for line in file_razgr:
        cu_string = line.split(";")
        print(cu_string)
        OName = cu_string[0]
        XMLeft = float(cu_string[1])
Ejemplo n.º 29
0
args = vars(ap.parse_args())
workingPath = args["wpath"] + "\\"
markerFile = args["mfile"]
print("Working path is: %s" % workingPath)

project = workingPath + "ortho_dem_process.psx"

app = PhotoScan.Application()
doc = PhotoScan.app.document
doc.open(project)

PhotoScan.app.gpu_mask = 1
# PhotoScan.app.cpu_enable = 8

chunk = doc.chunk
chunk.crs = PhotoScan.CoordinateSystem("EPSG::4326")

# Assign GCPs
markerList = open(markerFile, "rt")
# print(markerList)
eof = False
line = markerList.readline()  #reading the line in input file
# print(line)
while not eof:
    photos_total = len(chunk.cameras)  #number of photos in chunk
    # print(photos_total)
    markers_total = len(chunk.markers)  #number of markers in chunk
    sp_line = line.rsplit(",", 6)  #splitting read line by four parts
    camera_name = sp_line[0]  #camera label
    marker_name = sp_line[1]  #marker label
    x = int(sp_line[2])  #x- coordinate of the current projection in pixels
Ejemplo n.º 30
0
# for each member in the list try to add it to our active chunk
### the try except is very important because the list goes one beyond our photos and returns an error
for photo_name in photo_list:
	try:
		chunk.addPhotos([path_photos + "\\" + photo_name]) 
	except:
		continue

# match, align, and optimize photos that have been added
chunk.matchPhotos(accuracy=photo_accuracy, preselection=PhotoScan.GenericPreselection)
chunk.alignCameras()
chunk.optimizeCameras(fit_f=True, fit_cxcy=True, fit_aspect=True, fit_skew=True, fit_k1k2k3=True, fit_p1p2=True, fit_k4=False)

# set coordinate system for each camera
n_crs = PhotoScan.CoordinateSystem(coordinate_system)
for camera in chunk.cameras:
	camera.reference.location = PhotoScan.CoordinateSystem.transform(camera.reference.location, chunk.crs, n_crs)

# build the dense cloud and then build the model
doc.save
chunk.buildDenseCloud()
chunk.buildModel(surface=PhotoScan.Arbitrary, interpolation=PhotoScan.EnabledInterpolation, face_count=num_faces, vertex_colors=True)

# build UV has to be done before the texture can be built
# chunk.buildUV(mapping=PhotoScan.GenericMapping)
# chunk.buildTexture(blending=PhotoScan.MosaicBlending, size=texture_size, fill_holes=True)

# generate the .ply for the points and the .pdf for the report
### photoscan requires the project is aved before a report can be generated
doc.save()