Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何实现位图的最小分配搜索?_C#_In Memory - Fatal编程技术网

C# 如何实现位图的最小分配搜索?

C# 如何实现位图的最小分配搜索?,c#,in-memory,C#,In Memory,首先,我的问题是,找出新的方法来实现快速高效的图像搜索,试图让它超过0.65~0.80毫秒的时间 到目前为止,我已经通过使用并行不安全位图解析、在初始索引后对部分进行排序以及许多其他简化,对搜索进行了广泛的改进。但让我感到困惑的是一种不使用中介来存储和比较数据的方法,额外的好处还包括对搜索到的位图进行最小解析(即对目标进行解析搜索) 既然有了这个算法,我们能做些什么来改进它呢 [MethodImpl(MethodImplOptions.AggressiveInlining)] p

首先,我的问题是,找出新的方法来实现快速高效的图像搜索,试图让它超过0.65~0.80毫秒的时间

到目前为止,我已经通过使用并行不安全位图解析、在初始索引后对部分进行排序以及许多其他简化,对搜索进行了广泛的改进。但让我感到困惑的是一种不使用中介来存储和比较数据的方法,额外的好处还包括对搜索到的位图进行最小解析(即对目标进行解析搜索)

既然有了这个算法,我们能做些什么来改进它呢

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public unsafe static Point InMemSearch(Bitmap Haystack, Bitmap NeedleStack)
    {
        if (NeedleStack == null)
            throw new System.ArgumentNullException(nameof(NeedleStack));

        if (Haystack == null)
        {
            return default;
        }

        BitmapData Stack = Haystack.LockBits(new Rectangle(0, 0, Haystack.Width, Haystack.Height), ImageLockMode.ReadOnly, PixelFormat.Format1bppIndexed);
        BitmapData Needle = NeedleStack.LockBits(new Rectangle(0, 0, NeedleStack.Width, NeedleStack.Height), ImageLockMode.ReadOnly, PixelFormat.Format1bppIndexed);
        Point p = default;
        byte* PtrStackPixel = (byte*)Stack.Scan0;
        byte* PtrNeedlePixel = (byte*)Needle.Scan0;
        Dictionary<int, IEnumerable<byte>> NeedleLookup = new Dictionary<int, IEnumerable<byte>>();
        Dictionary<int, IEnumerable<byte>> StackLookup = new Dictionary<int, IEnumerable<byte>>();
        IEnumerable<byte> GetNeedleLine(int needleY)
        {
            if(NeedleLookup.ContainsKey(needleY))
            {
                return NeedleLookup[needleY];
            }
            var NeedleLine = new byte[Needle.Width];
            for (int x = 0; x < Needle.Width; x++)
            {
                byte np = *(PtrNeedlePixel + (needleY * Needle.Stride) + (x >> 3));
                np &= (byte)(0x80 >> (x & 0x7));
                NeedleLine[x] = np;
            }
            NeedleLookup.Add(needleY, NeedleLine);
            return NeedleLine;
        }
        IEnumerable<byte> GetStackLine(int stackY)
        {
            if(StackLookup.ContainsKey(stackY))
            {
                return StackLookup[stackY];
            }
            var StackLine = new byte[Stack.Width];
            for (var x = 0; x < Stack.Width; x++)
            {
                byte sp = *(PtrStackPixel + (stackY * Stack.Stride) + (x >> 3));
                sp &= (byte)(0x80 >> (x & 0x7));
                StackLine[x] = sp;
            }
            StackLookup[stackY] = StackLine;
            return StackLine;
        }
        int Bad = 0;
        while(!GetNeedleLine(0 + Bad).Any(b => b > 0))
        {
            Bad++;
        }
        int BadStackLines = 0;
        int GoodIndex = 0;
        while (GoodIndex <= 0)
        {
            GoodIndex = SubListIndex(GetStackLine(Stack.Height - BadStackLines), 0, GetNeedleLine(0 + Bad));
            if (GoodIndex == -1)
            {
                BadStackLines++;
            }
            else
            {
                if (GetStackLine(Stack.Height - BadStackLines - 1).Skip(GoodIndex).Take(Needle.Width).SequenceEqual(GetNeedleLine(0 + Bad - 1)))
                {
                    p = new Point(GoodIndex, Stack.Height - BadStackLines);
                }
                else
                {
                    GoodIndex = 0;
                }
            }
        }
        Haystack.UnlockBits(Stack);
        NeedleStack.UnlockBits(Needle);
        return p;
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static int SubListIndex<T>(IEnumerable<T> list, int start, IEnumerable<T> sublist)
    {
        int Index = 0;
        var LoopResult = Parallel.For(start, list.Count() - sublist.Count() + 1, (listIndex, loopState) =>
          {
              int count = 0;
              while (count < sublist.Count() && sublist.ElementAt(count).Equals(list.ElementAt(listIndex + count)))
              {
                  count++;
              }
              if (count == sublist.Count())
              {
                  Index = listIndex;
                  loopState.Break();
              }
          });
        if (LoopResult.IsCompleted)
        {
            return -1;
        }
        else
        {
            return Index;
        }
    }
[MethodImpl(MethodImplOptions.AggressiveInline)]
MemSearch中的公共不安全静态点(位图草堆、位图针堆)
{
if(NeedleStack==null)
抛出新的System.ArgumentNullException(nameof(NeedleStack));
if(Haystack==null)
{
返回默认值;
}
BitmapData Stack=Haystack.LockBits(新矩形(0,0,Haystack.Width,Haystack.Height),ImageLockMode.ReadOnly,PixelFormat.Format1BPindexed);
BitmapData Pineder=NeedleStack.LockBits(新矩形(0,0,NeedleStack.Width,NeedleStack.Height),ImageLockMode.ReadOnly,PixelFormat.Format1BPindexed);
p点=默认值;
字节*PtrStackPixel=(字节*)Stack.Scan0;
字节*PtrNeedlePixel=(字节*)Needle.Scan0;
Dictionary NeedleLookup=新建字典();
Dictionary StackLookup=新建字典();
IEnumerable GetNeedline(无针)
{
if(needleokup.ContainsKey(needleY))
{
返回NeedleLookup[needrey];
}
var-needline=新字节[指针宽度];
用于(int x=0;x>3));
np&=(字节)(0x80>>(x&0x7));
针线[x]=np;
}
NeedleLookup.Add(needey,NeedleLine);
回针线;
}
IEnumerable GetStackLine(int stackY)
{
if(StackLookup.ContainsKey(stackY))
{
返回StackLookup[stackY];
}
var StackLine=新字节[Stack.Width];
对于(var x=0;x>3));
sp&=(字节)(0x80>>(x&0x7));
StackLine[x]=sp;
}
StackLookup[stackY]=StackLine;
返回堆垛线;
}
int Bad=0;
而(!GetNeedleLine(0+坏).Any(b=>b>0))
{
坏++;
}
int BadStackLines=0;
int-GoodIndex=0;
while(GoodIndex)
{
整数计数=0;
而(count

这仍然有数据结构需要比较,需要改进,但它实现了想法的一部分。

尝试创建一个可以从c#调用的Matlab dll。在做DSP时,Matlab函数比c要好得多。对我来说,这与其说是速度问题,不如说是实现了这个想法,把它包含在我用来解决其他问题的想法包中。:)如果速度不重要,那么在Matlab中处理DSP的功能仍然更多,在C语言中。另一个选择是C++。如果使用C++/CLI,仍然可以与.NET代码的其余部分交互。C#当然可以完成所有这些低级的丑陋,但它并没有真正针对它进行优化。另一方面,尝试.NET内核和
Vector
操作,而不是通过线程和低级数组摸索实现并行(显然,这可能需要大量重写)。即使
Span
也能帮上忙。谢谢你,但我会放弃,并继续尝试用我喜欢使用的工具找出最好的方法。我更新了我的代码,为其他人提供了我的第一种工作方法。