查找图案图像(二进制文件) [英] Find a pattern image (binary file)

查看:184
本文介绍了查找图案图像(二进制文件)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于DigitalMicrograph中的字符串变量,我们可以使用查找"功能找到特定模式的位置:

For string variable in DigitalMicrograph, we can find the position of a particular pattern using the "find" function:

Number find( String str, String sub_str )

除了图像数据外,我想做同样的事情.例如,我可以使用

I would like to do the same but with image data. For example, I can create an image with

image img := exprsize(1024, icol);

我要查找的模式是

image pattern := exprsize( 15, icol+64 );

在上述情况下,我们知道模式w.r.t的偏移量.数据位于第64列.在实际情况下,我们没有这样简单的模式(即直线).带有"for"循环的野蛮方法当然可以工作,但是当数据大小变大时,它会变得非常缓慢.有人有更好/更好的建议吗?一维图像可能更容易,而二维图像呢?

In above case, we know the offset of pattern w.r.t. the data is at column number 64. A real case we won't have a such simple pattern (i.e. a straight line). A brutal force approach with a "for" loop will certainly work but it gets painfully slow when the data size is getting bigger. Anyone has a better/elegant suggestion? 1D image may be easier, how about 2D image?

非常感谢!

推荐答案

根据要求,下面的片段显示了如何在原始"数据流中进行搜索.我并不是说下面的脚本是最快或最优雅的解决方案,它只是显示相应命令的工作方式. (您可以在在线F1帮助的文件输入和输出" 部分中找到它们的文档.)

As requested, here is a snipped showing how one could do a search in a "raw" data stream. I'm not claiming that the script below is the fastest or most elegant solution, it is just showing how the according commands work. (You find them documented in the "File Input and Output" section of the online F1 help.)

我输入的想法":只需在流中搜索您的搜索模式的最后一个值.仅当找到时,查看给定距离处的起始值是否也将匹配.仅在这种情况下,请检查整个模式.对于 long 搜索模式,这应该是一种有用的方法,但是对于非常短的搜索模式而言,它可能不是最佳选择.

The 'idea' I've put into it: Just search for the occurrences of last value of your search pattern in the stream. Only when found, see if the start-value at given distance would also match. Only in this case, check the whole pattern. This should be a useful method for long search patterns, but it might not be so optimal for very 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 as RawStream
        object buffer = NewMemoryBuffer( dataSize * dataTypeSizeByte )
        object stream = NewStreamFromBuffer(buffer)
        dataSet.ImageWriteImageDataToStream( stream, stream_byte_order )
        stream.StreamSetPos(0,0)

    // Prepare aux. Tags for streaming
        TagGroup tg = NewTagGroup();
        tg.TagGroupSetTagAsUInt32( "UInt32_0", 0 )

    // Prepare values to search for 
        number startValue = searchSet.GetPixel(0,0)
        number lastValue =  searchSet.GetPixel(patternSize-1,0)

    // search for the pattern
        // Search for the LAST value of the pattern only.
        // If found, check if the FIRST value in appropriated distance also matches
        // Only then compare whole pattern.

        number value
        number streamEndPos = stream.StreamGetSize() 
        number streamPos = (patternSize-1) * dataTypeSizeByte // we can skip the 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 to start-value (relative) to 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 also fits!) " )

                    // Now check all 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 at position : " + foundPos )
                        exit(0)
                    }       
                }
                stream.StreamSetPos(0, streamPos )  
            }   
    }
    OKDialog("Nothing found.")
}

这篇关于查找图案图像(二进制文件)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆