예제 #1
0
        static Image LoadAndPrepareStack(string path, decimal scaleFactor, int maxThreads = 8)
        {
            Image stack = null;

            MapHeader header = MapHeader.ReadFromFilePatient(50, 500,
                                                             path,
                                                             HeaderlessDims,
                                                             (int)HeaderlessOffset,
                                                             ImageFormatsHelper.StringToType(HeaderlessType));

            string Extension = Helper.PathToExtension(path).ToLower();
            bool   IsTiff    = header.GetType() == typeof(HeaderTiff);
            bool   IsEER     = header.GetType() == typeof(HeaderEER);

            if (GainRef != null)
            {
                if (!IsEER)
                {
                    if (header.Dimensions.X != GainRef.Dims.X || header.Dimensions.Y != GainRef.Dims.Y)
                    {
                        throw new Exception("Gain reference dimensions do not match image.");
                    }
                }
            }

            int EERSupersample = 1;

            if (GainRef != null && IsEER)
            {
                if (header.Dimensions.X == GainRef.Dims.X)
                {
                    EERSupersample = 1;
                }
                else if (header.Dimensions.X * 2 == GainRef.Dims.X)
                {
                    EERSupersample = 2;
                }
                else if (header.Dimensions.X * 4 == GainRef.Dims.X)
                {
                    EERSupersample = 3;
                }
                else
                {
                    throw new Exception("Invalid supersampling factor requested for EER based on gain reference dimensions");
                }
            }

            HeaderEER.SuperResolution = EERSupersample;

            if (IsEER && GainRef != null)
            {
                header.Dimensions.X = GainRef.Dims.X;
                header.Dimensions.Y = GainRef.Dims.Y;
            }

            int NThreads   = (IsTiff || IsEER) ? 6 : 2;
            int GPUThreads = 2;

            int CurrentDevice = GPU.GetDevice();

            if (RawLayers == null || RawLayers.Length != NThreads || RawLayers[0].Length != header.Dimensions.ElementsSlice())
            {
                RawLayers = Helper.ArrayOfFunction(i => new float[header.Dimensions.ElementsSlice()], NThreads);
            }

            Image[] GPULayers  = Helper.ArrayOfFunction(i => new Image(IntPtr.Zero, header.Dimensions.Slice()), GPUThreads);
            Image[] GPULayers2 = Helper.ArrayOfFunction(i => new Image(IntPtr.Zero, header.Dimensions.Slice()), GPUThreads);

            if (scaleFactor == 1M)
            {
                stack = new Image(header.Dimensions);
                float[][] OriginalStackData = stack.GetHost(Intent.Write);

                object[] Locks = Helper.ArrayOfFunction(i => new object(), GPUThreads);

                Helper.ForCPU(0, header.Dimensions.Z, NThreads, threadID => GPU.SetDevice(DeviceID), (z, threadID) =>
                {
                    if (IsTiff)
                    {
                        TiffNative.ReadTIFFPatient(50, 500, path, z, true, RawLayers[threadID]);
                    }
                    else if (IsEER)
                    {
                        EERNative.ReadEERPatient(50, 500, path, z * 10, (z + 1) * 10, EERSupersample, RawLayers[threadID]);
                    }
                    else
                    {
                        IOHelper.ReadMapFloatPatient(50, 500,
                                                     path,
                                                     HeaderlessDims,
                                                     (int)HeaderlessOffset,
                                                     ImageFormatsHelper.StringToType(HeaderlessType),
                                                     new[] { z },
                                                     null,
                                                     new[] { RawLayers[threadID] });
                    }

                    int GPUThreadID = threadID % GPUThreads;

                    lock (Locks[GPUThreadID])
                    {
                        GPU.CopyHostToDevice(RawLayers[threadID], GPULayers[GPUThreadID].GetDevice(Intent.Write), RawLayers[threadID].Length);

                        if (GainRef != null)
                        {
                            if (IsEER)
                            {
                                GPULayers[GPUThreadID].DivideSlices(GainRef);
                            }
                            else
                            {
                                GPULayers[GPUThreadID].MultiplySlices(GainRef);
                            }
                        }

                        if (DefectMap != null)
                        {
                            GPU.CopyDeviceToDevice(GPULayers[GPUThreadID].GetDevice(Intent.Read),
                                                   GPULayers2[GPUThreadID].GetDevice(Intent.Write),
                                                   header.Dimensions.Elements());
                            DefectMap.Correct(GPULayers2[GPUThreadID], GPULayers[GPUThreadID]);
                        }

                        GPU.Xray(GPULayers[GPUThreadID].GetDevice(Intent.Read),
                                 GPULayers2[GPUThreadID].GetDevice(Intent.Write),
                                 20f,
                                 new int2(header.Dimensions),
                                 1);

                        GPU.CopyDeviceToHost(GPULayers2[GPUThreadID].GetDevice(Intent.Read),
                                             OriginalStackData[z],
                                             header.Dimensions.ElementsSlice());
                    }
                }, null);
            }
            else
            {
                int3 ScaledDims = new int3((int)Math.Round(header.Dimensions.X * scaleFactor) / 2 * 2,
                                           (int)Math.Round(header.Dimensions.Y * scaleFactor) / 2 * 2,
                                           header.Dimensions.Z);

                stack = new Image(ScaledDims);
                float[][] OriginalStackData = stack.GetHost(Intent.Write);

                int[] PlanForw = Helper.ArrayOfFunction(i => GPU.CreateFFTPlan(header.Dimensions.Slice(), 1), GPUThreads);
                int[] PlanBack = Helper.ArrayOfFunction(i => GPU.CreateIFFTPlan(ScaledDims.Slice(), 1), GPUThreads);

                Image[] GPULayersInputFT  = Helper.ArrayOfFunction(i => new Image(IntPtr.Zero, header.Dimensions.Slice(), true, true), GPUThreads);
                Image[] GPULayersOutputFT = Helper.ArrayOfFunction(i => new Image(IntPtr.Zero, ScaledDims.Slice(), true, true), GPUThreads);

                Image[] GPULayersScaled = Helper.ArrayOfFunction(i => new Image(IntPtr.Zero, ScaledDims.Slice()), GPUThreads);

                object[] Locks = Helper.ArrayOfFunction(i => new object(), GPUThreads);

                Helper.ForCPU(0, ScaledDims.Z, NThreads, threadID => GPU.SetDevice(DeviceID), (z, threadID) =>
                {
                    if (IsTiff)
                    {
                        TiffNative.ReadTIFFPatient(50, 500, path, z, true, RawLayers[threadID]);
                    }
                    else if (IsEER)
                    {
                        EERNative.ReadEERPatient(50, 500, path, z * 10, (z + 1) * 10, EERSupersample, RawLayers[threadID]);
                    }
                    else
                    {
                        IOHelper.ReadMapFloatPatient(50, 500,
                                                     path,
                                                     HeaderlessDims,
                                                     (int)HeaderlessOffset,
                                                     ImageFormatsHelper.StringToType(HeaderlessType),
                                                     new[] { z },
                                                     null,
                                                     new[] { RawLayers[threadID] });
                    }

                    int GPUThreadID = threadID % GPUThreads;

                    lock (Locks[GPUThreadID])
                    {
                        GPU.CopyHostToDevice(RawLayers[threadID], GPULayers[GPUThreadID].GetDevice(Intent.Write), RawLayers[threadID].Length);

                        if (GainRef != null)
                        {
                            if (IsEER)
                            {
                                GPULayers[GPUThreadID].DivideSlices(GainRef);
                            }
                            else
                            {
                                GPULayers[GPUThreadID].MultiplySlices(GainRef);
                            }
                        }

                        if (DefectMap != null)
                        {
                            GPU.CopyDeviceToDevice(GPULayers[GPUThreadID].GetDevice(Intent.Read),
                                                   GPULayers2[GPUThreadID].GetDevice(Intent.Write),
                                                   header.Dimensions.Elements());
                            DefectMap.Correct(GPULayers2[GPUThreadID], GPULayers[GPUThreadID]);
                        }

                        GPU.Xray(GPULayers[GPUThreadID].GetDevice(Intent.Read),
                                 GPULayers2[GPUThreadID].GetDevice(Intent.Write),
                                 20f,
                                 new int2(header.Dimensions),
                                 1);

                        GPU.Scale(GPULayers2[GPUThreadID].GetDevice(Intent.Read),
                                  GPULayersScaled[GPUThreadID].GetDevice(Intent.Write),
                                  header.Dimensions.Slice(),
                                  ScaledDims.Slice(),
                                  1,
                                  PlanForw[GPUThreadID],
                                  PlanBack[GPUThreadID],
                                  GPULayersInputFT[GPUThreadID].GetDevice(Intent.Write),
                                  GPULayersOutputFT[GPUThreadID].GetDevice(Intent.Write));

                        GPU.CopyDeviceToHost(GPULayersScaled[GPUThreadID].GetDevice(Intent.Read),
                                             OriginalStackData[z],
                                             ScaledDims.ElementsSlice());
                    }
                }, null);

                for (int i = 0; i < GPUThreads; i++)
                {
                    GPU.DestroyFFTPlan(PlanForw[i]);
                    GPU.DestroyFFTPlan(PlanBack[i]);
                    GPULayersInputFT[i].Dispose();
                    GPULayersOutputFT[i].Dispose();
                    GPULayersScaled[i].Dispose();
                }
            }

            foreach (var layer in GPULayers)
            {
                layer.Dispose();
            }
            foreach (var layer in GPULayers2)
            {
                layer.Dispose();
            }

            return(stack);
        }
예제 #2
0
        static Image LoadAndPrepareStack(string path, Image imageGain, decimal scaleFactor, int maxThreads = 8)
        {
            Image stack = null;

            MapHeader header = MapHeader.ReadFromFilePatient(50, 500,
                                                             path,
                                                             HeaderlessDims,
                                                             (int)HeaderlessOffset,
                                                             ImageFormatsHelper.StringToType(HeaderlessType));

            if (imageGain != null)
            {
                if (header.Dimensions.X != imageGain.Dims.X || header.Dimensions.Y != imageGain.Dims.Y)
                {
                    throw new Exception("Gain reference dimensions do not match image.");
                }
            }

            bool IsTiff = header.GetType() == typeof(HeaderTiff);

            int NThreads   = IsTiff ? 6 : 2;
            int GPUThreads = 2;

            int CurrentDevice = GPU.GetDevice();

            if (RawLayers == null || RawLayers.Length != NThreads || RawLayers[0].Length != header.Dimensions.ElementsSlice())
            {
                RawLayers = Helper.ArrayOfFunction(i => new float[header.Dimensions.ElementsSlice()], NThreads);
            }

            Image[] GPULayers  = Helper.ArrayOfFunction(i => new Image(IntPtr.Zero, header.Dimensions.Slice()), GPUThreads);
            Image[] GPULayers2 = Helper.ArrayOfFunction(i => new Image(IntPtr.Zero, header.Dimensions.Slice()), GPUThreads);

            if (scaleFactor == 1M)
            {
                stack = new Image(header.Dimensions);
                float[][] OriginalStackData = stack.GetHost(Intent.Write);

                object[] Locks = Helper.ArrayOfFunction(i => new object(), GPUThreads);

                Helper.ForCPU(0, header.Dimensions.Z, NThreads, threadID => GPU.SetDevice(DeviceID), (z, threadID) =>
                {
                    if (IsTiff)
                    {
                        TiffNative.ReadTIFFPatient(50, 500, path, z, true, RawLayers[threadID]);
                    }
                    else
                    {
                        IOHelper.ReadMapFloatPatient(50, 500,
                                                     path,
                                                     HeaderlessDims,
                                                     (int)HeaderlessOffset,
                                                     ImageFormatsHelper.StringToType(HeaderlessType),
                                                     z,
                                                     null,
                                                     new[] { RawLayers[threadID] });
                    }

                    int GPUThreadID = threadID % GPUThreads;

                    lock (Locks[GPUThreadID])
                    {
                        GPU.CopyHostToDevice(RawLayers[threadID], GPULayers[GPUThreadID].GetDevice(Intent.Write), RawLayers[threadID].Length);

                        if (imageGain != null)
                        {
                            GPULayers[GPUThreadID].MultiplySlices(imageGain);
                        }

                        GPU.Xray(GPULayers[GPUThreadID].GetDevice(Intent.Read),
                                 GPULayers2[GPUThreadID].GetDevice(Intent.Write),
                                 20f,
                                 new int2(header.Dimensions),
                                 1);

                        GPU.CopyDeviceToHost(GPULayers2[GPUThreadID].GetDevice(Intent.Read),
                                             OriginalStackData[z],
                                             header.Dimensions.ElementsSlice());
                    }
                }, null);
            }
            else
            {
                int3 ScaledDims = new int3((int)Math.Round(header.Dimensions.X * scaleFactor) / 2 * 2,
                                           (int)Math.Round(header.Dimensions.Y * scaleFactor) / 2 * 2,
                                           header.Dimensions.Z);

                stack = new Image(ScaledDims);
                float[][] OriginalStackData = stack.GetHost(Intent.Write);

                int[] PlanForw = Helper.ArrayOfFunction(i => GPU.CreateFFTPlan(header.Dimensions.Slice(), 1), GPUThreads);
                int[] PlanBack = Helper.ArrayOfFunction(i => GPU.CreateIFFTPlan(ScaledDims.Slice(), 1), GPUThreads);

                Image[] GPULayersInputFT  = Helper.ArrayOfFunction(i => new Image(IntPtr.Zero, header.Dimensions.Slice(), true, true), GPUThreads);
                Image[] GPULayersOutputFT = Helper.ArrayOfFunction(i => new Image(IntPtr.Zero, ScaledDims.Slice(), true, true), GPUThreads);

                Image[] GPULayersScaled = Helper.ArrayOfFunction(i => new Image(IntPtr.Zero, ScaledDims.Slice()), GPUThreads);

                object[] Locks = Helper.ArrayOfFunction(i => new object(), GPUThreads);

                Helper.ForCPU(0, ScaledDims.Z, NThreads, threadID => GPU.SetDevice(DeviceID), (z, threadID) =>
                {
                    if (IsTiff)
                    {
                        TiffNative.ReadTIFFPatient(50, 500, path, z, true, RawLayers[threadID]);
                    }
                    else
                    {
                        IOHelper.ReadMapFloatPatient(50, 500,
                                                     path,
                                                     HeaderlessDims,
                                                     (int)HeaderlessOffset,
                                                     ImageFormatsHelper.StringToType(HeaderlessType),
                                                     z,
                                                     null,
                                                     new[] { RawLayers[threadID] });
                    }

                    int GPUThreadID = threadID % GPUThreads;

                    lock (Locks[GPUThreadID])
                    {
                        GPU.CopyHostToDevice(RawLayers[threadID], GPULayers[GPUThreadID].GetDevice(Intent.Write), RawLayers[threadID].Length);

                        if (imageGain != null)
                        {
                            GPULayers[GPUThreadID].MultiplySlices(imageGain);
                        }

                        GPU.Xray(GPULayers[GPUThreadID].GetDevice(Intent.Read),
                                 GPULayers2[GPUThreadID].GetDevice(Intent.Write),
                                 20f,
                                 new int2(header.Dimensions),
                                 1);

                        GPU.Scale(GPULayers2[GPUThreadID].GetDevice(Intent.Read),
                                  GPULayersScaled[GPUThreadID].GetDevice(Intent.Write),
                                  header.Dimensions.Slice(),
                                  ScaledDims.Slice(),
                                  1,
                                  PlanForw[GPUThreadID],
                                  PlanBack[GPUThreadID],
                                  GPULayersInputFT[GPUThreadID].GetDevice(Intent.Write),
                                  GPULayersOutputFT[GPUThreadID].GetDevice(Intent.Write));

                        GPU.CopyDeviceToHost(GPULayersScaled[GPUThreadID].GetDevice(Intent.Read),
                                             OriginalStackData[z],
                                             ScaledDims.ElementsSlice());
                    }
                }, null);

                for (int i = 0; i < GPUThreads; i++)
                {
                    GPU.DestroyFFTPlan(PlanForw[i]);
                    GPU.DestroyFFTPlan(PlanBack[i]);
                    GPULayersInputFT[i].Dispose();
                    GPULayersOutputFT[i].Dispose();
                    GPULayersScaled[i].Dispose();
                }
            }

            foreach (var layer in GPULayers)
            {
                layer.Dispose();
            }
            foreach (var layer in GPULayers2)
            {
                layer.Dispose();
            }

            return(stack);
        }