如何解决如何从 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)
}
据我所知:
- 我使用“DM 脚本手册”中的脚本对所有打开的图像执行操作
- 我创建了一个名为 pixelsize 的变量
- 我从文件中手动设置
- 我把它放在 x 和 y 的维度中
- 我将尺寸单位设置为“nm”
- 我还创建了比例尺。
所以你能告诉我吗:
是否可以将像素大小设置为 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 举报,一经查实,本站将立刻删除。