微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何从 TIFF 文件中文本包围的具体行中获取数字如果在记事本中查看并在 Digital Micrograph 的脚本中使用它?

如何解决如何从 TIFF 文件中文本包围的具体行中获取数字如果在记事本中查看并在 Digital Micrograph 的脚本中使用它?

更新#2 链接到 TIFF 文件(需要的行是 135)https://drive.google.com/file/d/1g3e3xenm5b-awQwpvfZyhfXIqSVGGw2t/view

(更新#1) 亲爱的 stackoverflow 用户

首先,我需要提及的是,我是编程的业余爱好者,但我欣赏编码的可能性并尝试在我的工作中加以利用。

在我们的实验室中,我们使用蔡司显微镜获取图像,如果在记事本中查看,该显微镜以 TIFF 格式保存图像,并以文本形式附加细节。因此,当您将 TIFF 图像放入数码显微照片时,它不会被校准,您必须手动校准每张图像。

另一方面,在这些 TIFF 文件中,有一行(其编号是固定的,但因显微镜而异)的像素大小如下所示:

“像素尺寸 = 0.6 纳米”

我的想法是,如果我可以从这一行中提取数字并将其放入为每个打开的图像声明尺寸的脚本中 - 它将节省大量时间。 我做了几个步骤:

Image img
img.GetFrontimage()
While(img.ImageIsValid())
 {Number pixelsize
pixelsize = 0.5
img.imagesetdimensionscale(0,pixelsize)
img.imagesetdimensionscale(1,pixelsize)
img.imagesetdimensionunitstring(0,"nm")
img.imagesetdimensionunitstring(1,"nm")
imagedisplay imgdisp=img.imagegetimagedisplay(0)
imgdisp.applydatabar(2)
img.SetName(img.GetName()+"*")
img := FindNextimage(img)
 }

据我所知:

  1. 我使用“DM 脚本手册”中的脚本对所有打开的图像执行操作
  2. 我创建了一个名为 pixelsize 的变量
  3. 我从文件中手动设置
  4. 我把它放在 x 和 y 的维度中
  5. 我将尺寸单位设置为“nm”
  6. 我还创建了比例尺。

所以你能告诉我吗:

是否可以将像素大小设置为 TIFF 文件中一行中的一个数字?

真诚的

暗影之刃

解决方法

是的,这是可行的,但并非微不足道。我找到了一个我正在做的旧脚本。我不再能够测试它,所以我不能 100% 确定它会起作用。 另外,在这里发帖有点太长了,所以我也把它放在这个pastebin link下。

// Some constants (See TIFF Format)
number kLittleEndianTIFF    = 0x4949
number kBigEndianTIFF       = 0x4D4D 
number kMagicIDNumberTIFF   = 42

number FALSE = 0
number TRUE = 1

Interface I_ImportTiffWithTags
{
    // Aux. method to simplify single value read from stream
    number ReadValueOfType( object self,string type ); 
    
    // Aux. method to strip multiple pre- and post- string occurances from a string
    string ClipText( object self,string input,string leadIn,string leadOut,number doMultiple );
    string ClipTextWhiteSpaces( object self,string input );

    // Aux. method to convert ASCII text of specific format into a TagStructure
    TagGroup CreateTagsFromString( object self,string entrySep,string keyToValueSep,string GroupLeadIn,string GroupLeadOut );
    TagGroup CreateTagsFromString_FEI_Default( object self,string input );
    TagGroup CreateTagsFromString_ZEISS_Default( object self,string input );

    // Get all TIFF tags from file in path as tagGroup  
    TagGroup GetTIFFTagsAsTG( object self,string path,number doTextFields,number doSingleValues,number includedSkipped );   
    TagGroup GetTIFFTagsAsTG( object self,number includedSkipped );   // doTextField = true,doSingleValues = true
    TagGroup GetTIFFTagsAsTG( object self,string path );                           // doTextField = true,doSingleValues = true,includedSkipped = false
    
    // Get all ASCII TIFF tags as single string
    String  GetTIFFAscii( object self,number splitSeparateTags );
    String  GetTIFFAscii( object self,string path); // splitSeparateTags = true
    
    // Import Image and append TIFF tags as TagGroup "TIFF Tags" to image
    image OpenTIFFWithTags( object self,string path );
    
    // Import TIFF Image stored by FEI SEMs,import info from ASCII in image,calibrate if possible
    image OpenFEI_TIFF( object self,number withTiffTags );
    image OpenFEI_TIFF( object self,string path );
    
    // Import TIFF Image stored by ZEISS SEMs,calibrate if possible
    image OpenZEISS_TIFF( object self,number withTiffTags );
    image OpenZEISS_TIFF( object self,string path);
    
    // Aux. to find calibration from the tags,format specific
    number GetCalibrationFromTags_FEI( object self,tagGroup FEItgs,number &sx,number &ox,string &ux,number &sy,number &oy,string &uy );
    number GetCalibrationFromTags_ZEISS( object self,tagGroup ZEISStags,string &uy );
    
}

Class CImportTIFFWithTags
{
    object fStream
    number byteOrder
    number verbose
    number kMaxTextShow 
    
    CImportTIFFWithTags( object self )
    {
        verbose = FALSE
        kMaxTextShow = 20
    }
    
    number ReadValueOfType( object self,string type )
    {
        if ( !fStream.ScriptObjectIsValid() ) Throw( "Invalid file stream." )
        number val = 0
        TagGroup tg = NewTagGroup()
        if ( type == "bool" )
        {
            tg.TagGroupSetTagAsBoolean( type,0 )
            tg.TagGroupReadTagDataFromStream( type,fstream,byteOrder ) 
            tg.TagGroupGetTagAsBoolean( type,val )
        }
        else if ( type == "uint8" )
        {
            string str = fStream.StreamReadAsText(0,1)
            val = asc(str)
        }
        else if ( type == "uint16" )
        {
            tg.TagGroupSetTagAsUInt16( type,byteOrder ) 
            tg.TagGroupGetTagAsUInt16( type,val )
        }
        else if ( type == "uint32" )
        {
            tg.TagGroupSetTagAsUInt32( type,byteOrder ) 
            tg.TagGroupGetTagAsUInt32( type,val )
        }
        else if ( type == "float" )
        {
            tg.TagGroupSetTagAsFloat( type,byteOrder ) 
            tg.TagGroupGetTagAsFloat( type,val )
        }
        else if ( type == "double" )
        {
            tg.TagGroupSetTagAsDouble( type,byteOrder ) 
            tg.TagGroupGetTagAsDouble( type,val )
        }
        else Throw("Invalid read-type:"+type)
        return val
    }
    
    
    string ClipText( object self,number doMultiple )
    {
        string work = input
        if ( len(leadIn) <= len(work) )
        {
            while ( leadIn == left(work,len(leadIn)) )
            {
                work = right( work,len(work) - len(leadIn) )
                if ( !doMultiple ) break
                if ( len(work) < len(leadin) ) break
            }
        }
        if ( len(leadOut) <= len(work) )
        {
            while ( leadOut == right(work,len(leadout)) )
            {
                work = left( work,len(work) - len(leadOut) )
                if ( !doMultiple ) break
                if ( len(leadOut) <= len(work) ) break
            }
        }
        return work
    }
    
    string ClipTextWhiteSpaces( object self,string input )
    {
        return self.ClipText( input," ",TRUE );
    }
    
    TagGroup CreateTagsFromString( object self,string GroupLeadOut )
    {
        TagGroup tg = NewTagGroup()
        number bCheckGroup = ( len(GroupLeadIn) && len(GroupLeadOut) )  // true if groupLeads are specified
        string work = input
        string groupName = ""
        if ( "" == entrySep )
            entrySep = "\n"
        
        number pos = find( work,entrySep )
        number skipped = 0
        while( -1 != pos )
        {
            //OKDialog("work:"+work)
            //OKDialog("Entry:"+len(entrySep) )
            string entry = left( work,pos )
            work = right( work,len(work) - len(entry) - len(entrySep) + 1)
            number sep     = find( entry,keyToValueSep )
            
            if( -1 < sep )                                                  
            {
                // Entry matches format "KEY=VALUE" with '=' being the defined entrySep
                string key  = left( entry,sep )
                string value= right( entry,len(entry) - sep - len(keyToValueSep) )
                // Truncate trailing white spaces
                key   = self.ClipTextWhiteSpaces(key)
                value = self.ClipTextWhiteSpaces(value)
                
                string tagPath = groupName + ( "" == groupName ? "" : ":" ) + key
                tg.TagGroupSetTagAsString( tagPath,value )
            }
            else if ( bCheckGroup )
            {
                // Entry does not match format "KEY=VALUE",check if it is a groupname
                number leadIn  = find( entry,GroupLeadIn )
                number leadOut = find( entry,GroupLeadOut )
                if ( ( -1 < leadIn ) && ( -1 < leadOut ) && ( leadIn < leadOut ) ) // Is it a new group? "[GROUPNAME]"
                {
                    groupName = mid( entry,leadIn + len(GroupLeadIn),leadOut - leadIn - len(GroupLeadOut) )
                }   
                else
                    skipped++
            }
            else
            {
                skipped++   
            }
            // Find next entry
            pos = find( work,entrySep )        
        }
        if ( 0 != len(work) )
            skipped++
            
        if ( verbose )
        {
            if ( skipped )
                Result( "\nText To Tag skipped " + skipped + " lines.\n" )
        }
    
        return tg
    }
    
    TagGroup CreateTagsFromString_FEI_Default( object self,string input )
    {
        return self.CreateTagsFromString( input,"\n","=","[","]" )
    }
    
    TagGroup CreateTagsFromString_ZEISS_Default( object self,"","" )
    }
    
    
    TagGroup GetTIFFTagsAsTG( object self,number includedSkipped )
    {
        if ( !DoesFileExist( path ) ) Throw( "File not found.\n"+path)
        
        // Open Stream 
        number fileID = OpenFileForReading( path )
        fStream = NewStreamFromFileReference(fileID,1)
        
        // Find Byte Order
        number val
        byteOrder = 0
        val = self.ReadValueOfType( "uint16" )
        byteOrder = ( kLittleEndianTIFF == val  ) ? 2 : ( kBigEndianTIFF == val ? 1 : 0 )
        
        // Verify TIFF image
        val = self.ReadValueOfType( "uint16" )
        if ( val != kMagicIDNumberTIFF ) Throw( "Not a valid TIFF image" )
        
        // Find first directory start
        number offset = self.ReadValueOfType( "uint32" )
        
        // Browse all directories
        number nIFD = 0
        TagGroup AllTiffTagsTGlist = NewTagList()
        TagGroup TiffTGs
        while( 0 != offset )
        {
            // Set to start of directory and read it in
            nIFD++
            TiffTGs = NewTagGroup()
            if ( verbose )  Result( "Reading IFD #" + nIFD + " at \t" + offset )
                                
            fStream.StreamSetPos( 0,offset )   
            number nEntries = self.ReadValueOfType( "uint16" )
            for ( number e=0; e<nEntries; e++ )
            {
                number tag        = self.ReadValueOfType( "uint16" )
                string tagStr     = "ID("+tag+")"
                number typ        = self.ReadValueOfType( "uint16" )
                number count      = self.ReadValueOfType( "uint32" )
                number dataOffset = self.ReadValueOfType( "uint32" )
                if ( verbose )
                    Result( "\n DirEntry # "+Format(e,"%3.0f") + ": TiffIDTag: " + tag + "]ttyp: " + typ + "\tcount: " + count )

                // Read only,if it is either a single value or a string                                
                if ( ( doTextFields ) && ( 2 == typ )  )// ASCII
                {
                    number currentPos = fStream.StreamGetPos()
                    fStream.StreamSetPos( 0,dataOffset )
                    string textField = fStream.StreamReadAsText( 0,count )
                    fStream.StreamSetPos( 0,currentPos )
                    if ( verbose ) Result( "\t value: " + left( textField,min(len(textField),kMaxTextShow ) ) )
                    TiffTGs.TagGroupSetTagAsString( tagStr,textField )     
                }   
                else if ( ( doSingleValues ) && ( 1 == count )  ) // Single Value. 
                {
                    // Note that the 'dataOffset'-4-bytes are already the value for data fitting in 4-bytes!
                    // Otherwise,it specifies the staring offset for the value
                    
                    if ( 1 == typ )         // uInt8
                    {
                        TiffTGs.TagGroupSetTagAsShort( tagStr,dataOffset )
                        if ( verbose )  Result("\t value:" + dataOffset )
                    }
                    else if ( 3 == typ )    // uInt16
                    {
                        TiffTGs.TagGroupSetTagAsUInt16( tagStr,dataOffset )    
                        if ( verbose )  Result("\t value:" + dataOffset )
                    }
                    else if ( 4 == typ )    // uInt32
                    {
                        TiffTGs.TagGroupSetTagAsUInt32( tagStr,dataOffset )    
                        if ( verbose )  Result("\t value:" + dataOffset )
                    }
                    else if ( 5 == typ )    // uInt32 / uInt32 (rational)
                    {
                        number currentPos = fStream.StreamGetPos()
                        number val1 = self.ReadValueOfType( "uint32" )
                        number val2 = self.ReadValueOfType( "uint32" )
                        TiffTGs.TagGroupSetTagAsLongPoint( tagStr,val1,val2 )
                        fStream.StreamSetPos( 0,currentPos )
                        if ( verbose )  Result("\t value:" + val1 + "/" + val2 )
                    }
                    else if ( 11 == typ )   // float
                    {
                        TiffTGs.TagGroupSetTagAsFloat( tagStr,dataOffset )                 
                        if ( verbose )  Result("\t value:" + dataOffset )
                    }
                    else if ( 12 == typ )   // double
                    {
                        number currentPos = fStream.StreamGetPos()
                        number val = self.ReadValueOfType( "double" )
                        TiffTGs.TagGroupSetTagAsDouble( tagStr,val )
                        fStream.StreamSetPos( 0,currentPos )
                        if ( verbose )  Result("\t value:" + val )
                    }
                    else if ( includedSkipped )
                    {
                        if ( verbose )  Result("\t value: SKIPPED DATA TYPE" )
                        TiffTGs.TagGroupSetTagAsString( tagStr,"Not imported,TagType (TIFF "+typ+")" )
                    }               
                }
                else if ( includedSkipped )
                {
                    // Multiple value entries
                    if ( verbose )  Result("\t value: Multiple values. Arrays are not read." )
                    TiffTGs.TagGroupSetTagAsString( tagStr,TagType (TIFF "+typ+") "+count+" values" )
                }
            }
            // Read next directory offset. 
            // This is 0000 for the last directory according to spec
            offset = self.ReadValueOfType( "uint32" ) 
            AllTiffTagsTGlist.TagGroupAddTagGroupAtEnd(TiffTGs)
        }
        
        // Return list if entries or just one group if there is one directory only
        if ( 1 < nIFD ) 
            return AllTiffTagsTGlist
        else
            return TiffTGs
    }
    TagGroup GetTIFFTagsAsTG( object self,number includedSkipped )
    {
        return self.GetTIFFTagsAsTG( path,TRUE,includedSkipped )
    }
    TagGroup GetTIFFTagsAsTG( object self,string path )
    {
        return self.GetTIFFTagsAsTG( path,FALSE )
    }   
    
    String  GetTIFFAscii( object self,number splitSeparateTags )
    {
        String allText
        TagGroup tgs = self.GetTIFFTagsAsTG(path,FALSE,FALSE )
        number nTags = tgs.TagGroupCountTags()
        for ( number n=0; n<nTags; n++ )
        {
            string label = tgs.TagGroupGetTagLabel(n)
            if ( splitSeparateTags )
            {
                if ( 1<nTags ) 
                    allText += (n?"\n":"")+"TIFF Tag " + label + ":\n"
            }
            string text
            if ( tgs.TagGroupGetTagAsString( label,text ) ) 
                allText += text + "\n"          
        }
        
        return allText
    }
    
    String  GetTIFFAscii( object self,string path)
    {
        return self.GetTIFFAscii( path,true )
    }
    
    image OpenTIFFWithTags( object self,string path )
    {
        image Imported := OpenImage( path )
        TagGroup TIFFTags = self.GetTIFFTagsAsTG(path,TRUE)
        Imported.ImageGetTagGroup().TagGroupSetTagAsTagGroup( "TIFF Tags",TIFFTags )
        return Imported
    }
    
    image OpenFEI_TIFF( object self,number withTiffTags )
    {
        image Imported := OpenImage( path )
        if ( withTiffTags )
        {
            TagGroup TIFFTags = self.GetTIFFTagsAsTG(path,FALSE )
            Imported.ImageGetTagGroup().TagGroupSetTagAsTagGroup( "TIFF Tags",TIFFTags )
        }
        string ASCIITags = self.GetTIFFAscii(path)
        TagGroup FEITags = self.CreateTagsFromString_FEI_Default( ASCIITags )
        Imported.ImageGetTagGroup().TagGroupSetTagAsTagGroup( "Info",FEITags )
        number sx,sy,ox,oy
        string ux,uy
        if ( self.GetCalibrationFromTags_FEI(FEITags,sx,ux,oy,uy ) )
        {
            Imported.ImageSetDimensionCalibration(0,0)
            Imported.ImageSetDimensionCalibration(1,uy,0)
        }
        else
        {
            if ( verbose )
                Result( "\n FEI calibration not found. Image remains uncalibrated." )
        }
        return Imported
    }
    
    number GetCalibrationFromTags_FEI( object self,tagGroup FEItags,string &uy )
    {
        if ( !FEItags.TagGroupIsValid() ) return FALSE
        number foundSomething = FALSE
        ox=0
        oy=0
        sx=1
        sy=1
        ux=""
        uy=""
        number value
        if ( FEITags.TagGroupGetTagAsNumber( "Scan:PixelWidth",value ) )
        {
            foundSomething = TRUE
            // [value] is in [m],scale to nm or um
            if ( value < 1e-6 )
            {
                if ( value < 1e-9 )
                {
                    ux = "nm"
                    sx =  value * 1e9
                }
                else
                {
                    ux = "µm"
                    sx =  value * 1e6
                }
            }
        }
        if ( FEITags.TagGroupGetTagAsNumber( "Scan:PixelHeight",scale to nm or um
            if ( value < 1e-6 )
            {
                if ( value < 1e-9 )
                {
                    uy = "nm"
                    sy =  value * 1e9
                }
                else
                {
                    uy = "µm"
                    sy =  value * 1e6
                }
            }
        }
        return foundSomething 
    }
    
    
    image OpenFEI_TIFF( object self,string path )
    {
        return self.OpenFEI_TIFF( path,FALSE )
    }
    
    image OpenZEISS_TIFF( object self,TIFFTags )
        }
        string ASCIITags = self.GetTIFFAscii(path)
        TagGroup ZEISSTags = self.CreateTagsFromString_ZEISS_Default( ASCIITags )
        Imported.ImageGetTagGroup().TagGroupSetTagAsTagGroup( "Info",ZEISSTags  )
        number sx,uy
        if ( self.GetCalibrationFromTags_ZEISS(ZEISSTags,uy ) )
        {
            // "scale" gives full FOV!
            if ( sx!= 1)
                Imported.ImageSetDimensionCalibration(0,sx/Imported.ImageGetDimensionSize(0),0)
            if ( sy!= 1)
                Imported.ImageSetDimensionCalibration(1,sy/Imported.ImageGetDimensionSize(1),0)
        }
        else
        {
            if ( verbose )
                Result( "\n ZEISS calibration not found. Image remains uncalibrated." )
        }
        return Imported
    }
    
    image OpenZEISS_TIFF( object self,string path )
    {
        return self.OpenZEISS_TIFF( path,FALSE )
    }
    
    number GetCalibrationFromTags_ZEISS( object self,string &uy )
    {
        if ( !ZEISStags.TagGroupIsValid() ) return FALSE
        number foundSomething = FALSE
        ox=0
        oy=0
        sx=1
        sy=1
        ux=""
        uy=""
        string value
        if ( ZEISStags.TagGroupGetTagAsString( "Width",value ) )
        {
            number pos = find( value," " ) // separate unit!
            if ( -1 < pos )
            {
                sx = val( left(value,pos) )     // FOV width not scale!!
                ux  = right( value,len(value)-pos-1 )
                foundSomething = TRUE
            }
        }
        if ( ZEISStags.TagGroupGetTagAsString( "Height"," " ) // separate unit!
            if ( -1 < pos )
            {
                sy = val( left(value,pos) )     // FOV width not scale!!
                uy  = right( value,len(value)-pos-1 )
                foundSomething = TRUE
            }
        }
        return foundSomething   
    }
}

///////////////////
// CALL EXAMPLES //
///////////////////

number option = 1
string msg
msg += "IMPORT TIFF - EXAMPLE\n"
msg += "Select what you want to do:\n"
msg += "(1)\t Import and calibrate FEI TIFF.\n"
msg += "(2)\t Import and calibrate ZEISS TIFF.\n"
msg += "(3)\t Show text content of TIFF.\n"
msg += "(4)\t Show TIFF tags in browser.\n"

while ( 4<option || 1>option )
{
    if ( !GetNumber(msg,option,option)) exit(0)
}

string path = GetApplicationDirectory("open_save",0)
if (!OpenDialog(NULL,"Select TIFF file",path,path)) exit(0)

if ( 1 == option  )
    Alloc(CImportTIFFWithTags).OpenFEI_TIFF(path).ShowImage()
else if ( 2 == option  )
    Alloc(CImportTIFFWithTags).OpenZEISS_TIFF(path).ShowImage()
else if ( 3 == option )
    Result( "\n\n\n\n_____________________________\n" +Alloc(CImportTIFFWithTags).GetTIFFAscii(path) )
else if ( 4 == option )
    Alloc(CImportTIFFWithTags).GetTIFFTagsAsTG(path,true,true).TagGroupOpenBrowserWindow(path,0)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。