dm script - Find a pattern image (binary file) -
for string variable in digitalmicrograph, can find position of particular pattern using "find" function:
number find( string str, string sub_str ) i same image data. example, can create image
image img := exprsize(1024, icol); and pattern want find
image pattern := exprsize( 15, icol+64 ); in above case, know offset of pattern w.r.t. data @ column number 64. real case won't have such simple pattern (i.e. straight line). brutal force approach "for" loop work gets painfully slow when data size getting bigger. has better/elegant suggestion? 1d image may easier, how 2d image?
many thanks!
as requested, here snipped showing how 1 search in "raw" data stream. i'm not claiming script below fastest or elegant solution, showing how according commands work. (you find them documented in "file input , output" section of online f1 help.)
the 'idea' i've put it: search occurrences of last value of search pattern in stream. when found, see if start-value @ given distance match. in case, check whole pattern. should useful method long search patterns, might not optimal short ones.
{ number patternsize = 8 number datasize = 24000 number patternpos = trunc( random() * ( datasize - patternsize ) ) number const = 200 number datatypesizebyte = 4 number stream_byte_order = 0 // prepare test-dummies image searchset := integerimage( "search", datatypesizebyte, 0, patternsize ) searchset = const * sin( icol/iwidth * pi() ) // searchset.showimage() image dataset := integerimage( "data", datatypesizebyte, 0, datasize ) dataset = const * random() * 0.3 dataset.slice1( patternpos, 0, 0, 0, patternsize, 1 ) = searchset // dataset.showimage() // prepare data rawstream object buffer = newmemorybuffer( datasize * datatypesizebyte ) object stream = newstreamfrombuffer(buffer) dataset.imagewriteimagedatatostream( stream, stream_byte_order ) stream.streamsetpos(0,0) // prepare aux. tags streaming taggroup tg = newtaggroup(); tg.taggroupsettagasuint32( "uint32_0", 0 ) // prepare values search number startvalue = searchset.getpixel(0,0) number lastvalue = searchset.getpixel(patternsize-1,0) // search pattern // search last value of pattern only. // if found, check if first value in appropriated distance matches // compare whole pattern. number value number streamendpos = stream.streamgetsize() number streampos = (patternsize-1) * datatypesizebyte // can skip first few tests stream.streamsetpos(0, streampos ) while( streampos < streamendpos ) { tg.taggroupreadtagdatafromstream( "uint32_0", stream, stream_byte_order ) streampos = stream.streamgetpos() tg.taggroupgettagasuint32( "uint32_0", value ) // use appropriate data type! if ( lastvalue == value ) { result("\n pattern might end at: "+streampos/datatypesizebyte) // shift start-value (relative) check first value! stream.streamsetpos(1, -1 * patternsize * datatypesizebyte ) tg.taggroupreadtagdatafromstream( "uint32_0", stream, stream_byte_order ) tg.taggroupgettagasuint32( "uint32_0", value ) if ( startvalue == value ) { result("\t (start fits!) " ) // check of it! stream.streamsetpos(1, -1 * datatypesizebyte ) image comptemp := integerimage( "sectiondata", datatypesizebyte, 0, patternsize ) comptemp.imagereadimagedatafromstream( stream, stream_byte_order ) if ( 0 == sum( abs(comptemp - searchset) ) ) { number foundpos = (stream.streamgetpos()/datatypesizebyte - patternsize) result("\n correct starting position: " + patternpos ) result("\n found starting position : " + foundpos ) okdialog( "found subset @ position : " + foundpos ) exit(0) } } stream.streamsetpos(0, streampos ) } } okdialog("nothing found.") }
Comments
Post a Comment