示例#1
0
    def runTest(self):
        numThreadsInTest = 100

        CreateFile(self.TestOutputPath, 0)
        ExpectedPath = os.path.join(self.TestOutputPath,
                                    TestThreadPool.FilenameTemplate % 0)
        self.assertTrue(
            os.path.exists(ExpectedPath),
            "Function we are testing threads with does not seem to work")
        os.remove(ExpectedPath)

        # Create a 100 threads and have them create files
        TPool = pools.GetGlobalThreadPool()
        self.assertIsNotNone(TPool)

        VerifyExceptionBehaviour(self, TPool)

        runFunctionOnPool(self, TPool)
        runFileIOOnPool(self, TPool)

        #No need to test even distribution of work because the threads are all in the same process
        #runEvenDistributionOfWorkTestOnThePool(self,TPool)

        TPool = pools.GetThreadPool("Test local thread pool")
        self.assertIsNotNone(TPool)
        runFileIOOnPool(self, TPool)
    def _ShowMosaic(self,
                    mosaic,
                    mosaic_path=None,
                    openwindow=True,
                    usecluster=True,
                    title=None,
                    target_space_scale=None,
                    source_space_scale=None):

        (assembledImage,
         mask) = mosaic.AssembleImage(tilesPath=None,
                                      usecluster=usecluster,
                                      target_space_scale=target_space_scale,
                                      source_space_scale=source_space_scale)

        if not mosaic_path is None:
            pool = nornir_pools.GetGlobalThreadPool()
            pool.add_task("Save %s" % mosaic_path, core.SaveImage, mosaic_path,
                          assembledImage)
            #core.SaveImage(mosaic_path, assembledImage)

        if openwindow:
            if title is None:
                title = "A mosaic with no tiles out of place"

            self.assertTrue(
                nornir_imageregistration.ShowGrayscale(assembledImage,
                                                       title=title,
                                                       PassFail=True))
示例#3
0
    def runTest(self):
        TPool = pools.GetGlobalThreadPool()
        self.assertIsNotNone(TPool)

        runFunctionOnPool(self, TPool, Func=SquareTheNumberWithDelay)
        runFileIOOnPool(self,
                        TPool,
                        CreateFunc=CreateFileWithDelay,
                        ReadFunc=ReadFileWithDelay)
示例#4
0
    def LoadMosaic(self, mosaicFullPath, tiles_dir=None):
        '''Return a list of image transform views for the mosaic file'''

        mosaic = Mosaic.LoadFromMosaicFile(mosaicFullPath)
        if len(mosaic.ImageToTransform) == 0:
            return None

        mosaic.TranslateToZeroOrigin()

        tiles_dir = MosaicState.GetMosaicTilePath(
            list(mosaic.ImageToTransform.keys())[0], mosaicFullPath, tiles_dir)
        if tiles_dir is None:
            return None

        tilesPathList = mosaic.CreateTilesPathList(tiles_dir)
        transform_scale = nornir_imageregistration.tileset.MostCommonScalar(
            list(mosaic.ImageToTransform.values()), tilesPathList)

        ImageTransformViewList = []

        z_step = 1.0 / float(len(mosaic.ImageToTransform))
        z = z_step - (z_step / 2.0)
        output_len = 0

        pools = nornir_pools.GetGlobalThreadPool()

        tasks = []
        for image_filename, transform in list(mosaic.ImageToTransform.items()):
            tile_full_path = os.path.join(tiles_dir, image_filename)

            task = pools.add_task(str(z), self.AllocateMosaicTile, transform,
                                  tile_full_path, transform_scale)
            task.z = z
            tasks.append(task)

            # image_transform_view = self.AllocateMosaicTile(transform, tile_full_path, transform_scale)
            # image_transform_view.z = z
            z += z_step
            # ImageTransformViewList.append(image_transform_view)

        wx.Yield()

        for t in tasks:
            image_transform_view = t.wait_return()
            image_transform_view.z = t.z
            ImageTransformViewList.append(image_transform_view)

            output = '%g' % (z * 100.0)

            sys.stdout.write('\b' * output_len)
            sys.stdout.write(output)

            output_len = len(output)

        self.ImageTransformViewList = ImageTransformViewList
        return ImageTransformViewList
def GetFixedAndWarpedImageStats(imFixed, imWarped):
    tpool = nornir_pools.GetGlobalThreadPool()

    fixedStatsTask = tpool.add_task(
        'FixedStats', nornir_imageregistration.ImageStats.CalcStats, imFixed)
    warpedStats = nornir_imageregistration.ImageStats.CalcStats(imWarped)

    fixedStats = fixedStatsTask.wait_return()

    return (fixedStats, warpedStats)
示例#6
0
def ClearTempDirectories(level_paths):
    '''Deletes temporary directories used to generate levels'''
    
    if level_paths is None:
        return 
    
    if len(level_paths) == 0:
        return 
    
    temp_dir = tempfile.gettempdir()
    
    pool = nornir_pools.GetGlobalThreadPool()
    for level_path in level_paths:
        LevelDir = os.path.join(temp_dir, os.path.basename(level_path))
        pool.add_task("Remove temp directory {0}".format(LevelDir), shutil.rmtree, LevelDir, ignore_errors=True)
        
    pool.wait_completion()
示例#7
0
def __ScaleImage(ImageNode,
                 HtmlPaths,
                 MaxImageWidth=None,
                 MaxImageHeight=None):
    '''Scale an image to be smaller than the maximum dimensions.  Vector based images such as SVG will not be scaled
    :return: (Image_source_path, Width, Height) Image source path may refer to a copy or the original.
    '''
    Height = MaxImageHeight
    Width = MaxImageWidth
    try:
        (Height, Width) = ImageNode.Dimensions
        #[Height, Width] = nornir_imageregistration.GetImageSize(ImageNode.FullPath)
    except IOError:
        return (HtmlPaths.GetSubNodeFullPath(ImageNode), Height, Width)

    # Create a thumbnail if needed
    if Width > MaxImageWidth or Height > MaxImageHeight:
        Scale = max(
            float(Width) / MaxImageWidth,
            float(Height) / MaxImageHeight)
        Scale = 1.0 / Scale

        os.makedirs(HtmlPaths.ThumbnailDir, exist_ok=True)

        ThumbnailFilename = GetTempFileSaltString() + ImageNode.Path
        ImgSrcPath = os.path.join(HtmlPaths.ThumbnailRelative,
                                  ThumbnailFilename)

        ThumbnailOutputFullPath = os.path.join(HtmlPaths.ThumbnailDir,
                                               ThumbnailFilename)

        # nfiles.RemoveOutdatedFile(ImageNode.FullPath, ThumbnailOutputFullPath)
        # if not os.path.exists(ThumbnailOutputFullPath):
        Pool = nornir_pools.GetGlobalThreadPool()
        Pool.add_task(ImageNode.FullPath, nornir_imageregistration.Shrink,
                      ImageNode.FullPath, ThumbnailOutputFullPath, Scale)
        #cmd = "magick convert " + ImageNode.FullPath + " -resize " + str(Scale * 100) + "% " + ThumbnailOutputFullPath

        #Pool.add_process(cmd, cmd + " && exit", shell=True)

        Width = int(Width * Scale)
        Height = int(Height * Scale)
    else:
        ImgSrcPath = HtmlPaths.GetSubNodeFullPath(ImageNode)

    return (ImgSrcPath, Height, Width)
    def CalculateRBFWeights(self,
                            WarpedPoints,
                            ControlPoints,
                            BasisFunction=None):

        BetaMatrix = RBFWithLinearCorrection.CreateBetaMatrix(
            WarpedPoints, BasisFunction)
        (SolutionMatrix_X, SolutionMatrix_Y
         ) = RBFWithLinearCorrection.CreateSolutionMatricies(ControlPoints)

        thread_pool = nornir_pools.GetGlobalThreadPool()

        Y_Task = thread_pool.add_task("WeightsY", scipy.linalg.solve,
                                      BetaMatrix, SolutionMatrix_Y)
        WeightsX = scipy.linalg.solve(BetaMatrix, SolutionMatrix_X)
        WeightsY = Y_Task.wait_return()

        return numpy.hstack([WeightsX, WeightsY])
示例#9
0
    def OnTransformChanged(self):
        '''Calls every function registered to be notified when the transform changes.'''

        # Calls every listener when the transform has changed in a way that a point may be mapped to a new position in the fixed space

        if len(self.OnChangeEventListeners) > 1:
            Pool = nornir_pools.GetGlobalThreadPool()
            tlist = list()

            for func in self.OnChangeEventListeners:
                tlist.append(
                    Pool.add_task("OnTransformChanged calling " + str(func),
                                  func))

            #Call wait on all tasks so we see exceptions
            while len(tlist) > 0:
                t = tlist.pop(0)
                t.wait()
        else:
            for func in self.OnChangeEventListeners:
                func()
示例#10
0
    def OnSaveWarpedImage(self, e):
        # Set the path for the output directory.
        if not (pyre.state.currentStosConfig.FixedImageViewModel is None
                or pyre.state.currentStosConfig.WarpedImageViewModel is None):
            dlg = wx.FileDialog(self, "Choose a Directory",
                                StosWindow.imagedirname, "", "*.png",
                                wx.FD_SAVE)
            if dlg.ShowModal() == wx.ID_OK:
                StosWindow.imagedirname = dlg.GetDirectory()
                self.filename = dlg.GetFilename()
                state.currentStosConfig.OutputImageFullPath = os.path.join(
                    StosWindow.imagedirname, self.filename)

                #                 common.SaveRegisteredWarpedImage(pyre.state.currentStosConfig.OutputImageFullPath,
                #                                                  pyre.state.currentStosConfig.Transform,
                #                                                  pyre.state.currentStosConfig.WarpedImageViewModel.Image)
                pool = pools.GetGlobalThreadPool()
                pool.add_task(
                    "Save " + pyre.state.currentStosConfig.OutputImageFullPath,
                    common.SaveRegisteredWarpedImage,
                    state.currentStosConfig.OutputImageFullPath,
                    state.currentStosConfig.Transform,
                    state.currentStosConfig.WarpedImageViewModel.Image)
示例#11
0
def ParseSections(InputVolumeNode, OutputVolumeNode):

    # Find all of the section tags
    Pool = nornir_pools.GetGlobalThreadPool()

    SectionTasks = []

    print("Adding Sections\n")
    for BlockNode in InputVolumeNode.findall('Block'):
        for SectionNode in BlockNode.Sections:

            OutputSectionNode = OutputVolumeNode.find("Section[@Number='%d']" %
                                                      SectionNode.Number)
            assert (OutputSectionNode is None)

            #if not ECLIPSE:
            #print('\b' * 3)

            print('Queue %g' % SectionNode.Number)

            task = Pool.add_task(str(SectionNode.Number), ParseSection,
                                 BlockNode.Path, SectionNode)
            SectionTasks.append(task)

    for t in SectionTasks:
        if not ECLIPSE:
            print('\b' * 8)

        print('%s' % t.name)

        OutputSectionNode = t.wait_return()

        OutputVolumeNode.append(OutputSectionNode)

    AllSectionNodes = OutputVolumeNode.findall('Section')
    OutputVolumeNode.attrib['num_sections'] = str(len(AllSectionNodes))
示例#12
0
    def LoadStos(self, stosFullPath):

        if stosFullPath is None:
            return False

        success = True

        dirname = os.path.dirname(stosFullPath)
        filename = os.path.basename(stosFullPath)

        obj = StosFile.Load(os.path.join(dirname, filename))
        self.LoadTransform(stosFullPath)

        pool = nornir_pools.GetGlobalThreadPool()
        ControlImageTask = None
        WarpedImageTask = None
        ControlImageMaskTask = None
        WarpedImageMaskTask = None

        # First check the absolute path in the .stos file for images, then
        # check relative to the .stos file's directory
        ControlImagePath = self._try_locate_file(obj.ControlImageFullPath,
                                                 [dirname])
        if ControlImagePath is not None:
            ControlImageTask = pool.add_task(
                'load fixed %s' % ControlImagePath, self.LoadImage,
                ControlImagePath)
        else:
            print("Could not find fixed image: " + obj.ControlImageFullPath)
            success = False

        WarpedImagePath = self._try_locate_file(obj.MappedImageFullPath,
                                                [dirname])
        if WarpedImagePath is not None:
            WarpedImageTask = pool.add_task('load warped %s' % WarpedImagePath,
                                            self.LoadImage, WarpedImagePath)
        else:
            print("Could not find warped image: " + obj.MappedImageFullPath)
            success = False

        if obj.HasMasks and success:
            ControlMaskImagePath = self._try_locate_file(
                obj.ControlMaskFullPath, [dirname])
            if ControlMaskImagePath:
                ControlImageMaskTask = pool.add_task(
                    'load fixed mask %s' % ControlMaskImagePath,
                    self.LoadImage, ControlMaskImagePath)

            WarpedMaskImagePath = self._try_locate_file(
                obj.MappedMaskFullPath, [dirname])
            if WarpedMaskImagePath:
                WarpedImageMaskTask = pool.add_task(
                    'load warped mask %s' % WarpedMaskImagePath,
                    self.LoadImage, WarpedMaskImagePath)

        if ControlImageTask is not None:
            self.FixedImageViewModel = ControlImageTask.wait_return()

        if WarpedImageTask is not None:
            self.WarpedImageViewModel = WarpedImageTask.wait_return()

        if ControlImageMaskTask is not None:
            self.FixedImageMaskViewModel = ControlImageMaskTask.wait_return()

        if WarpedImageMaskTask is not None:
            self.WarpedImageMaskViewModel = WarpedImageMaskTask.wait_return()

        return success
示例#13
0
    def RunStosRefinement(self,
                          stosFilePath,
                          ImageDir=None,
                          SaveImages=False,
                          SavePlots=True):
        '''
        This is a test for the refine mosaic feature which is not fully implemented
        '''

        #stosFile = self.GetStosFile("0164-0162_brute_32")
        #stosFile = self.GetStosFile("0617-0618_brute_64")
        stosObj = nornir_imageregistration.files.StosFile.Load(stosFilePath)
        #stosObj.Downsample = 64.0
        #stosObj.Scale(2.0)
        #stosObj.Save(os.path.join(self.TestOutputPath, "0617-0618_brute_32.stos"))

        fixedImage = stosObj.ControlImageFullPath
        warpedImage = stosObj.MappedImageFullPath

        if ImageDir is not None:
            fixedImage = os.path.join(ImageDir, stosObj.ControlImageFullPath)
            warpedImage = os.path.join(ImageDir, stosObj.MappedImageFullPath)

        fixedImageData = nornir_imageregistration.ImageParamToImageArray(
            fixedImage, dtype=np.float16)
        warpedImageData = nornir_imageregistration.ImageParamToImageArray(
            warpedImage, dtype=np.float16)

        stosTransform = nornir_imageregistration.transforms.factory.LoadTransform(
            stosObj.Transform, 1)

        unrefined_image_path = os.path.join(self.TestOutputPath,
                                            'unrefined_transform.png')

        #        if not os.path.exists(unrefined_image_path):
        #            unrefined_warped_image = nornir_imageregistration.assemble.TransformStos(stosTransform,
        #                                                                                     fixedImage=fixedImage,
        #                                                                                     warpedImage=warpedImage)
        #            nornir_imageregistration.SaveImage(unrefined_image_path, unrefined_warped_image, bpp=8)
        #        else:
        #            unrefined_warped_image = nornir_imageregistration.LoadImage(unrefined_image_path)

        num_iterations = 10

        cell_size = np.asarray((128, 128), dtype=np.int32) * 2.0
        grid_spacing = (256, 256)

        i = 1

        finalized_points = {}

        min_percentile_included = 5.0

        final_pass = False
        final_pass_angles = np.linspace(-7.5, 7.5, 11)

        CutoffPercentilePerIteration = 10.0

        angles_to_search = None

        pool = nornir_pools.GetGlobalThreadPool()

        while i <= num_iterations:

            cachedFileName = '{5}_pass{0}_alignment_Cell_{2}x{1}_Grid_{4}x{3}'.format(
                i, cell_size[0], cell_size[1], grid_spacing[0],
                grid_spacing[1], self.TestName)
            alignment_points = self.ReadOrCreateVariable(cachedFileName)

            if alignment_points is None:
                alignment_points = _RunRefineTwoImagesIteration(
                    stosTransform,
                    fixedImageData,
                    warpedImageData,
                    os.path.join(ImageDir, stosObj.ControlMaskFullPath),
                    os.path.join(ImageDir, stosObj.MappedMaskFullPath),
                    cell_size=cell_size,
                    grid_spacing=grid_spacing,
                    finalized=finalized_points,
                    angles_to_search=angles_to_search,
                    min_alignment_overlap=None)
                self.SaveVariable(alignment_points, cachedFileName)

            print("Pass {0} aligned {1} points".format(i,
                                                       len(alignment_points)))

            if i == 1:
                cell_size = cell_size / 2.0

            combined_alignment_points = alignment_points + list(
                finalized_points.values())

            percentile = 100.0 - (CutoffPercentilePerIteration * i)
            if percentile < 10.0:
                percentile = 10.0
            elif percentile > 100:
                percentile = 100

#         if final_pass:
#             percentile = 0

            if SavePlots:
                histogram_filename = os.path.join(
                    self.TestOutputPath,
                    'weight_histogram_pass{0}.png'.format(i))
                nornir_imageregistration.views.PlotWeightHistogram(
                    alignment_points,
                    histogram_filename,
                    cutoff=percentile / 100.0)
                vector_field_filename = os.path.join(
                    self.TestOutputPath, 'Vector_field_pass{0}.png'.format(i))
                nornir_imageregistration.views.PlotPeakList(
                    alignment_points,
                    list(finalized_points.values()),
                    vector_field_filename,
                    ylim=(0, fixedImageData.shape[1]),
                    xlim=(0, fixedImageData.shape[0]))

            updatedTransform = local_distortion_correction._PeakListToTransform(
                combined_alignment_points, percentile)

            new_finalized_points = local_distortion_correction.CalculateFinalizedAlignmentPointsMask(
                combined_alignment_points,
                percentile=percentile,
                min_travel_distance=0.333)

            new_finalizations = 0
            for (ir, record) in enumerate(alignment_points):
                if not new_finalized_points[ir]:
                    continue

                key = tuple(record.SourcePoint)
                if key in finalized_points:
                    continue

                #See if we can improve the final alignment
                refined_align_record = nornir_imageregistration.stos_brute.SliceToSliceBruteForce(
                    record.TargetROI,
                    record.SourceROI,
                    AngleSearchRange=final_pass_angles,
                    MinOverlap=0.25,
                    SingleThread=True,
                    Cluster=False,
                    TestFlip=False)

                if refined_align_record.weight > record.weight:
                    record = nornir_imageregistration.alignment_record.EnhancedAlignmentRecord(
                        ID=record.ID,
                        TargetPoint=record.TargetPoint,
                        SourcePoint=record.SourcePoint,
                        peak=refined_align_record.peak,
                        weight=refined_align_record.weight,
                        angle=refined_align_record.angle,
                        flipped_ud=refined_align_record.flippedud)

                #Create a record that is unmoving
                finalized_points[key] = EnhancedAlignmentRecord(
                    record.ID,
                    TargetPoint=record.AdjustedTargetPoint,
                    SourcePoint=record.SourcePoint,
                    peak=np.asarray((0, 0), dtype=np.float32),
                    weight=record.weight,
                    angle=0,
                    flipped_ud=record.flippedud)

                new_finalizations += 1

            print("Pass {0} has locked {1} new points, {2} of {3} are locked".
                  format(i, new_finalizations, len(finalized_points),
                         len(combined_alignment_points)))

            stosObj.Transform = updatedTransform
            stosObj.Save(
                os.path.join(self.TestOutputPath,
                             "UpdatedTransform_pass{0}.stos".format(i)))

            if SaveImages:
                warpedToFixedImage = nornir_imageregistration.assemble.TransformStos(
                    updatedTransform,
                    fixedImage=fixedImageData,
                    warpedImage=warpedImageData)

                Delta = warpedToFixedImage - fixedImageData
                ComparisonImage = np.abs(Delta)
                ComparisonImage = ComparisonImage / ComparisonImage.max()

                #nornir_imageregistration.SaveImage(os.path.join(self.TestOutputPath, 'delta_pass{0}.png'.format(i)), ComparisonImage, bpp=8)
                #nornir_imageregistration.SaveImage(os.path.join(self.TestOutputPath, 'image_pass{0}.png'.format(i)), warpedToFixedImage, bpp=8)

                pool.add_task('delta_pass{0}.png'.format(i),
                              nornir_imageregistration.SaveImage,
                              os.path.join(self.TestOutputPath,
                                           'delta_pass{0}.png'.format(i)),
                              np.copy(ComparisonImage),
                              bpp=8)
                pool.add_task('image_pass{0}.png'.format(i),
                              nornir_imageregistration.SaveImage,
                              os.path.join(self.TestOutputPath,
                                           'image_pass{0}.png'.format(i)),
                              np.copy(warpedToFixedImage),
                              bpp=8)

            #nornir_imageregistration.core.ShowGrayscale([fixedImageData, unrefined_warped_image, warpedToFixedImage, ComparisonImage])

            i = i + 1

            stosTransform = updatedTransform

            if final_pass:
                break

            if i == num_iterations:
                final_pass = True
                angles_to_search = final_pass_angles

            #If we've locked 10% of the points and have not locked any new ones we are done
            if len(finalized_points) > len(combined_alignment_points
                                           ) * 0.1 and new_finalizations == 0:
                final_pass = True
                angles_to_search = final_pass_angles

            #If we've locked 90% of the points we are done
            if len(finalized_points) > len(combined_alignment_points) * 0.9:
                final_pass = True
                angles_to_search = final_pass_angles

        #Convert the transform to a grid transform and persist to disk
        stosObj.Transform = local_distortion_correction.ConvertTransformToGridTransform(
            stosObj.Transform,
            source_image_shape=warpedImageData.shape,
            cell_size=cell_size,
            grid_spacing=grid_spacing)
        stosObj.Save(os.path.join(self.TestOutputPath, "Final_Transform.stos"))
        return
def AttemptAlignPoint(transform,
                      fixedImage,
                      warpedImage,
                      controlpoint,
                      alignmentArea,
                      anglesToSearch=None):
    '''Try to use the Composite view to render the two tiles we need for alignment'''
    if anglesToSearch is None:
        anglesToSearch = np.linspace(-7.5, 7.5, 11)

    FixedRectangle = nornir_imageregistration.Rectangle.CreateFromPointAndArea(
        point=[
            controlpoint[0] - (alignmentArea[0] / 2.0),
            controlpoint[1] - (alignmentArea[1] / 2.0)
        ],
        area=alignmentArea)

    FixedRectangle = nornir_imageregistration.Rectangle.SafeRound(
        FixedRectangle)
    FixedRectangle = nornir_imageregistration.Rectangle.change_area(
        FixedRectangle, alignmentArea)

    rigid_transforms = nornir_imageregistration.local_distortion_correction.ApproximateRigidTransform(
        input_transform=transform, target_points=controlpoint)

    # Pull image subregions
    rigid_warpedImageROI = nornir_imageregistration.assemble.WarpedImageToFixedSpace(
        rigid_transforms[0],
        fixedImage.shape,
        warpedImage,
        botleft=FixedRectangle.BottomLeft,
        area=FixedRectangle.Size,
        extrapolate=True)

    warpedImageROI = nornir_imageregistration.assemble.WarpedImageToFixedSpace(
        transform,
        fixedImage.shape,
        warpedImage,
        botleft=FixedRectangle.BottomLeft,
        area=FixedRectangle.Size,
        extrapolate=True)

    fixedImageROI = nornir_imageregistration.CropImage(
        fixedImage.copy(),
        FixedRectangle.BottomLeft[1],
        FixedRectangle.BottomLeft[0],
        int(FixedRectangle.Size[1]),
        int(FixedRectangle.Size[0]),
        cval="random")

    fixedImageROI.setflags(write=False)

    #nornir_imageregistration.ShowGrayscale(([fixedImageROI, warpedImageROI],[rigid_warpedImageROI, fixedImageROI - warpedImageROI,]))

    pool = nornir_pools.GetGlobalThreadPool()

    # task = pool.add_task("AttemptAlignPoint", nornir_imageregistration.FindOffset, fixedImageROI, warpedImageROI, MinOverlap = 0.2)
    # apoint = task.wait_return()
    # apoint = nornir_imageregistration.FindOffset(fixedImageROI, warpedImageROI, MinOverlap=0.2)
    # nornir_imageregistration.ShowGrayscale([fixedImageROI, warpedImageROI], "Fixed <---> Warped")

    # nornir_imageregistration.ShowGrayscale([fixedImageROI, warpedImageROI])

    t = pool.add_task(
        "Rigid align point {0},{1}".format(controlpoint[1], controlpoint[0]),
        nornir_imageregistration.stos_brute.SliceToSliceBruteForce,
        fixedImageROI,
        rigid_warpedImageROI,
        AngleSearchRange=anglesToSearch,
        MinOverlap=0.25,
        SingleThread=True,
        Cluster=False,
        TestFlip=False)
    #     rigid_apoint = nornir_imageregistration.stos_brute.SliceToSliceBruteForce(fixedImageROI, rigid_warpedImageROI,
    #                                                                         AngleSearchRange=anglesToSearch,
    #                                                                         MinOverlap=0.25, SingleThread=True,
    #                                                                         Cluster=False, TestFlip=False)

    apoint = nornir_imageregistration.stos_brute.SliceToSliceBruteForce(
        fixedImageROI,
        warpedImageROI,
        AngleSearchRange=anglesToSearch,
        MinOverlap=0.25,
        SingleThread=True,
        Cluster=False,
        TestFlip=False)

    rigid_apoint = t.wait_return()

    if rigid_apoint.weight > apoint.weight:
        return rigid_apoint
    else:
        # print("Auto-translate result: " + str(apoint))
        return apoint
示例#15
0
    def ToMosaic(cls, VolumeObj, idocFileFullPath, ContrastCutoffs, OutputImageExt=None, TargetBpp=None, FlipList=None, ContrastMap=None, CameraBpp=None, debug=None):
        '''
        This function will convert an idoc file in the given path to a .mosaic file.
        It will also rename image files to the requested extension and subdirectory.
        TargetBpp is calculated based on the number of bits required to encode the values
        between the median min and max values
        :param list FlipList: List of section numbers which should have images flipped
        :param dict ContrastMap: Dictionary mapping section number to (Min, Max, Gamma) tuples 
        '''
        if(OutputImageExt is None):
            OutputImageExt = 'png'
  
        if TargetBpp is None:
            TargetBpp = 8

        if FlipList is None:
            FlipList = []

        if ContrastMap is None:
            ContrastMap = {}
   
        SaveChannel = False

        idocFilePath = serialem_utils.GetPathWithoutSpaces(idocFileFullPath)
 
        OutputPath = VolumeObj.FullPath

        os.makedirs(OutputPath, exist_ok=True)

        logger = logging.getLogger(__name__ + '.' + str(cls.__name__) + "ToMosaic")

        # Report the current stage to the user
        prettyoutput.CurseString('Stage', "SerialEM to Mosaic " + str(idocFileFullPath))

        SectionNumber = 0
        sectionDir = os.path.dirname(idocFileFullPath) #serialem_utils.GetDirectories(idocFileFullPath)

        BlockObj = BlockNode.Create('TEM')
        [saveBlock, BlockObj] = VolumeObj.UpdateOrAddChild(BlockObj)

        # If the parent directory doesn't have the section number in the name, change it
        ExistingSectionInfo = shared.GetSectionInfo(sectionDir)
        if(ExistingSectionInfo[0] < 0):
            i = 5
#            SectionNumber = SectionNumber + 1
#            newPathName = ('%' + nornir_buildmanager.templates.Current.SectionFormat) % SectionNumber + '_' + sectionDir
#            newPath = os.path.join(ParentDir, newPathName)
#            prettyoutput.Log('Moving: ' + InputPath + ' -> ' + newPath)
#            shutil.move(InputPath, newPath)
#
#            InputPath = newPath
#
#            #Run glob again because the dir changes
#            idocFiles = glob.glob(os.path.join(InputPath,'*.idoc'))
        else:
            SectionNumber = ExistingSectionInfo.number

        prettyoutput.CurseString('Section', str(SectionNumber))

        # Check for underscores.  If there is an underscore and the first part is the sectionNumber, then use everything after as the section name
        SectionName = ('%' + nornir_buildmanager.templates.Current.SectionFormat) % ExistingSectionInfo.number
        SectionPath = ('%' + nornir_buildmanager.templates.Current.SectionFormat) % ExistingSectionInfo.number
        try:
            parts = sectionDir.partition("_")
            if not parts is None:
                if len(parts[2]) > 0:
                    SectionName = parts[2]
        except:
            pass

        sectionObj = SectionNode.Create(SectionNumber,
                                        SectionName,
                                        SectionPath)

        [saveSection, sectionObj] = BlockObj.UpdateOrAddChildByAttrib(sectionObj, 'Number')
        sectionObj.Name = SectionName

        # Create a channel group 
        [saveChannel, channelObj] = sectionObj.UpdateOrAddChildByAttrib(ChannelNode.Create('TEM'), 'Name')
   
        # Create a channel group for the section

        # I started ignoring existing supertile.mosaic files so I could rebuild sections where
        # a handful of tiles were corrupt
        # if(os.path.exists(SupertilePath)):
        #    continue

        Flip = SectionNumber in FlipList;
        if(Flip):
            prettyoutput.Log("Found in FlipList.txt, flopping images")

        IDocData = IDoc.Load(idocFilePath, CameraBpp=CameraBpp)

        assert(hasattr(IDocData, 'PixelSpacing'))
        assert(hasattr(IDocData, 'DataMode'))
        assert(hasattr(IDocData, 'ImageSize'))

        # If there are no tiles... return
        if IDocData.NumTiles == 0:
            prettyoutput.Log("No tiles found in IDoc: " + idocFilePath)
            return

        # See if we can find a notes file...
        shared.TryAddNotes(channelObj, sectionDir, logger)
        serialem_utils.TryAddLogs(channelObj, sectionDir, logger)

        AddIdocNode(channelObj, idocFilePath, IDocData, logger)

        # Set the scale
        [added, ScaleObj] = cls.CreateScaleNode(IDocData, channelObj)
        
        # Parse the images
        ImageBpp = IDocData.GetImageBpp()            
        if ImageBpp is None:
            ImageBpp = cls.GetImageBpp(IDocData, sectionDir) 

        FilterName = 'Raw' + str(TargetBpp)
        if(TargetBpp is None):
            FilterName = 'Raw'

        histogramFullPath = os.path.join(sectionDir, 'Histogram.xml')
        
        IDocData.RemoveMissingTiles(sectionDir)
        source_tile_list = [os.path.join(sectionDir, t.Image) for t in IDocData.tiles ]
          
        (ActualMosaicMin, ActualMosaicMax, Gamma) = cls.GetSectionContrastSettings(SectionNumber, ContrastMap, ContrastCutoffs, source_tile_list, IDocData, histogramFullPath)
        ActualMosaicMax = numpy.around(ActualMosaicMax)
        ActualMosaicMin = numpy.around(ActualMosaicMin)
        
        contrast_mismatch = channelObj.RemoveFilterOnContrastMismatch(FilterName, ActualMosaicMin, ActualMosaicMax, Gamma)
    
        Pool = nornir_pools.GetGlobalThreadPool()
        #_PlotHistogram(histogramFullPath, SectionNumber, ActualMosaicMin, ActualMosaicMax)
        Pool.add_task(histogramFullPath, _PlotHistogram, histogramFullPath, SectionNumber, ActualMosaicMin, ActualMosaicMax, force_recreate=contrast_mismatch)
        
        
        ImageConversionRequired = contrast_mismatch

        # Create a channel for the Raw data 
        [added_filter, filterObj] = channelObj.UpdateOrAddChildByAttrib(FilterNode.Create(Name=FilterName), 'Name')
        if added_filter:
            ImageConversionRequired = True

        filterObj.SetContrastValues(ActualMosaicMin, ActualMosaicMax, Gamma)
        filterObj.BitsPerPixel = TargetBpp

        SupertileName = 'Stage'
        SupertileTransform = SupertileName + '.mosaic'
        SupertilePath = os.path.join(channelObj.FullPath, SupertileTransform)

        # Check to make sure our supertile mosaic file is valid
        RemoveOutdatedFile(idocFilePath, SupertilePath)

        [added_transform, transformObj] = channelObj.UpdateOrAddChildByAttrib(TransformNode.Create(Name=SupertileName,
                                                                         Path=SupertileTransform,
                                                                         Type='Stage'),
                                                                         'Path')

        [added_tilepyramid, PyramidNodeObj] = filterObj.UpdateOrAddChildByAttrib(TilePyramidNode.Create(Type='stage',
                                                                            NumberOfTiles=IDocData.NumTiles),
                                                                            'Path')

        [added_level, LevelObj] = PyramidNodeObj.GetOrCreateLevel(1, GenerateData=False)

        Tileset = NornirTileset.CreateTilesFromIDocTileData(IDocData.tiles, InputTileDir=sectionDir, OutputTileDir=LevelObj.FullPath, OutputImageExt=OutputImageExt)

        # Make sure the target LevelObj is verified        
        if not os.path.exists(LevelObj.FullPath):
            os.makedirs(LevelObj.FullPath, exist_ok=True)
        else:
            Tileset.RemoveStaleTilesFromOutputDir(SupertilePath=SupertilePath)
            VerifyTiles(filterObj.TilePyramid.GetLevel(1))

        SourceToMissingTargetMap = Tileset.GetSourceToMissingTargetMap()

        # Figure out if we have to move or convert images
        if len(SourceToMissingTargetMap) == 0:
            ImageConversionRequired = False
        else:
            ImageConversionRequired = (not ImageBpp == TargetBpp) or (ImageConversionRequired or Tileset.ImageConversionRequired)

        if(ImageConversionRequired):
            Invert = False 
            filterObj.SetContrastValues(ActualMosaicMin, ActualMosaicMax, Gamma)
            filterObj.TilePyramid.NumberOfTiles = IDocData.NumTiles
            # andValue = cls.GetBitmask(ActualMosaicMin, ActualMosaicMax, TargetBpp)
            #nornir_shared.images.ConvertImagesInDict(SourceToMissingTargetMap, Flip=Flip, Bpp=TargetBpp, Invert=Invert, bDeleteOriginal=False, MinMax=[ActualMosaicMin, ActualMosaicMax])
            nornir_imageregistration.ConvertImagesInDict(SourceToMissingTargetMap, Flip=Flip, InputBpp=ImageBpp, OutputBpp=TargetBpp, Invert=Invert, bDeleteOriginal=False, MinMax=[ActualMosaicMin, ActualMosaicMax], Gamma=Gamma)

        elif(Tileset.ImageMoveRequired):
            for f in SourceToMissingTargetMap:
                shutil.copy(f, SourceToMissingTargetMap[f])

        # If we wrote new images replace the .mosaic file
        if len(SourceToMissingTargetMap) > 0 or not os.path.exists(SupertilePath):
            # Writing this file indicates import succeeded and we don't need to repeat these steps, writing it will possibly invalidate a lot of downstream data
            # We need to flip the images.  This may be a Utah scope issue, our Y coordinates are inverted relative to the images.  To fix this
            # we flop instead of flip and reverse when writing the coordinates
            mosaicfile.MosaicFile.Write(SupertilePath, Entries=Tileset.GetPositionsForTargets(), Flip=not Flip, ImageSize=IDocData.ImageSize, Downsample=1);
            MFile = mosaicfile.MosaicFile.Load(SupertilePath)

            # Sometimes files fail to convert, when this occurs remove them from the .mosaic
            if MFile.RemoveInvalidMosaicImages(LevelObj.FullPath):
                MFile.Save(SupertilePath)
 
            Mosaic.TranslateMosaicFileToZeroOrigin(SupertilePath)
            transformObj.ResetChecksum()
            SaveChannel = True
            # transformObj.Checksum = MFile.Checksum

        if saveBlock:
            return VolumeObj
        elif saveSection:
            return BlockObj
        elif saveChannel:
            return sectionObj
        elif  added_transform or added_tilepyramid or added_level or ImageConversionRequired or SaveChannel or contrast_mismatch:
            return channelObj
        return None