BioLib  3.6.2
A GUI-less version of Bio .NET library for editing & annotating various microscopy image formats.
Loading...
Searching...
No Matches
BioLib.Stitch Class Reference

Classes

struct  TileData
 

Public Member Functions

bool HasTile (Extent ex)
 
bool HasTile (TileInfo t)
 
void AddTile (Tuple< TileInfo, byte[]> tile)
 
void Initialize ()
 
byte[] StitchImages (List< TileInfo > tiles, int pxwidth, int pxheight, double x, double y, double resolution)
 

Static Public Member Functions

static Bitmap ConvertCudaDeviceVariableToBitmap (CudaDeviceVariable< byte > deviceVar, int width, int height, PixelFormat pixelFormat)
 

Public Attributes

List< Tuple< TileInfo, CudaDeviceVariable< byte > > > gpuTiles = new List<Tuple<TileInfo, CudaDeviceVariable<byte>>>()
 

Detailed Description

Definition at line 18 of file Stitch.cs.

Constructor & Destructor Documentation

◆ Stitch()

BioLib.Stitch.Stitch ( )

Definition at line 38 of file Stitch.cs.

39 {
40 Initialize();
41 }

Member Function Documentation

◆ AddTile()

void BioLib.Stitch.AddTile ( Tuple< TileInfo, byte[]> tile)

Definition at line 61 of file Stitch.cs.

62 {
63 if (HasTile(tile.Item1))
64 return;
65 byte[] tileData = null;
66 if (tile.Item2.Length != 256 * 256 * 2)
67 tileData = Bitmap.Convert16BitGrayscaleTo24BitRGB(tile.Item2);
68 else
69 if (tile.Item2.Length != 256 * 256 * 4)
70 tileData = Bitmap.Convert32BitARGBTo24BitRGB(tile.Item2);
71 else
72 if (tile.Item2.Length != 256 * 256 * 6)
73 tileData = Bitmap.Convert48BitTo24BitRGB(tile.Item2);
74 else
75 if (tile.Item2.Length != 256 * 256 * 3)
76 tileData = tile.Item2;
77 else
78 throw new NotSupportedException("Current pixel format is not supported.");
79 if (gpuTiles.Count > maxTiles)
80 {
81 var ti = gpuTiles.First();
82 ti.Item2.Dispose();
83 gpuTiles.Remove(gpuTiles.First());
84 }
85 try
86 {
87 CudaDeviceVariable<byte> devTile = new CudaDeviceVariable<byte>(tileData.Length);
88 devTile.CopyToDevice(tileData);
89 gpuTiles.Add(new Tuple<TileInfo, CudaDeviceVariable<byte>>(tile.Item1, devTile));
90 }
91 catch (Exception e)
92 {
93 Initialize();
94 Console.WriteLine(e.Message);
95 }
96
97 }

◆ ConvertCudaDeviceVariableToBitmap()

static Bitmap BioLib.Stitch.ConvertCudaDeviceVariableToBitmap ( CudaDeviceVariable< byte > deviceVar,
int width,
int height,
PixelFormat pixelFormat )
static

Definition at line 118 of file Stitch.cs.

119 {
120 // Step 1: Allocate a byte array on the CPU (host)
121 byte[] hostArray = new byte[deviceVar.Size];
122
123 // Step 2: Copy the data from the GPU (device) to the CPU (host)
124 deviceVar.CopyToHost(hostArray);
125
126 // Step 3: Create a Bitmap object from the byte array
127 Bitmap bitmap = new Bitmap(width, height, pixelFormat);
128
129 // Step 4: Lock the bitmap's bits for writing
130 BitmapData bmpData = bitmap.LockBits(new AForge.Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, pixelFormat);
131
132 // Step 5: Copy the byte array to the bitmap's pixel buffer
133 System.Runtime.InteropServices.Marshal.Copy(hostArray, 0, bmpData.Scan0, hostArray.Length);
134
135 // Step 6: Unlock the bitmap's bits
136 bitmap.UnlockBits(bmpData);
137
138 // Return the Bitmap object
139 return bitmap;
140 }

◆ HasTile() [1/2]

bool BioLib.Stitch.HasTile ( Extent ex)

Definition at line 42 of file Stitch.cs.

43 {
44 foreach (var item in gpuTiles)
45 {
46 if (item.Item1.Extent == ex)
47 return true;
48 }
49 return false;
50 }

◆ HasTile() [2/2]

bool BioLib.Stitch.HasTile ( TileInfo t)

Definition at line 51 of file Stitch.cs.

52 {
53 foreach (var item in gpuTiles)
54 {
55 if (item.Item1.Index == t.Index)
56 return true;
57 }
58 return false;
59 }

◆ Initialize()

void BioLib.Stitch.Initialize ( )

Definition at line 98 of file Stitch.cs.

99 {
100
101 try
102 {
103 context = new CudaContext();
104 // Load the CUDA kernel
105 kernel = context.LoadKernelPTX(System.IO.Path.GetDirectoryName(Environment.ProcessPath) + "/tile_copy.ptx", "copyTileToCanvas");
106 initialized = true;
107 }
108 catch (Exception e)
109 {
110 Console.WriteLine(e);
111 OpenSlideBase.useGPU = false;
112 //SlideSourceBase.useGPU = false;
113 SlideBase.UseVips = true;
114 OpenSlideBase.UseVips = true;
115 }
116
117 }

◆ StitchImages()

byte[] BioLib.Stitch.StitchImages ( List< TileInfo > tiles,
int pxwidth,
int pxheight,
double x,
double y,
double resolution )

Definition at line 141 of file Stitch.cs.

142 {
143 try
144 {
145 // Convert world coordinates of tile extents to pixel space based on resolution
146 foreach (var item in tiles)
147 {
148 item.Extent = item.Extent.WorldToPixelInvertedY(resolution);
149 }
150
151 if (!initialized)
152 {
153 Initialize();
154 }
155
156 // Calculate the bounding box (min/max extents) of the stitched image
157 double maxX = tiles.Max(t => t.Extent.MaxX);
158 double maxY = tiles.Max(t => t.Extent.MaxY);
159 double minX = tiles.Min(t => t.Extent.MinX);
160 double minY = tiles.Min(t => t.Extent.MinY);
161
162 // Calculate canvas size in pixels
163 int canvasWidth = (int)(maxX - minX);
164 int canvasHeight = (int)(maxY - minY);
165
166 // Allocate memory for the output stitched image on the GPU
167 using (CudaDeviceVariable<byte> devCanvas = new CudaDeviceVariable<byte>(canvasWidth * canvasHeight * 3)) // 3 channels for RGB
168 {
169 // Set block and grid sizes for kernel launch
170 dim3 blockSize = new dim3(16, 16, 1);
171 dim3 gridSize = new dim3((uint)((canvasWidth + blockSize.x - 1) / blockSize.x), (uint)((canvasHeight + blockSize.y - 1) / blockSize.y), 1);
172
173 // Iterate through each tile and copy it to the GPU canvas
174 foreach (var tile in tiles)
175 {
176 Extent extent = tile.Extent;
177 // Find the corresponding GPU tile (already loaded into GPU memory)
178 CudaDeviceVariable<byte> devTile = null;
179 foreach (var t in gpuTiles)
180 {
181 if (t.Item1.Index == tile.Index)
182 {
183 devTile = t.Item2;
184 break;
185 }
186 }
187 if (devTile != null)
188 {
189 // Calculate the start position on the canvas and the dimensions of the tile
190 int startX = (int)Math.Ceiling(extent.MinX - minX);
191 int startY = (int)Math.Ceiling(extent.MinY - minY);
192
193 int tileWidth = (int)Math.Ceiling(extent.MaxX - extent.MinX);
194 int tileHeight = (int)Math.Ceiling(extent.MaxY - extent.MinY);
195
196 // canvasTileWidth and canvasTileHeight handle the scaling of the tile to the canvas
197 int canvasTileWidth = tileWidth;
198 int canvasTileHeight = tileHeight;
199
200 // Run the CUDA kernel to copy the tile to the canvas
201 kernel.BlockDimensions = blockSize;
202 kernel.GridDimensions = gridSize;
203
204 // Run the kernel, including scaling factors
205 kernel.Run(devCanvas.DevicePointer, canvasWidth, canvasHeight, devTile.DevicePointer, 256, 256, startX, startY, canvasTileWidth, canvasTileHeight);
206 }
207 }
208
209 // Download the stitched image from the GPU to the host (CPU)
210 byte[] stitchedImageData = new byte[canvasWidth * canvasHeight * 3]; // Assuming 3 channels (RGB)
211 devCanvas.CopyToHost(stitchedImageData);
212
213 // Clip (x, y) to the canvas bounds
214 int clippedX = Math.Max(0, (int)(x - minX));
215 int clippedY = Math.Max(0, (int)(y - minY));
216
217 // Make sure the viewport fits within the canvas bounds
218 int viewportWidth = pxwidth;
219 int viewportHeight = pxheight;
220
221 // Extract the viewport region from the stitched image
222 byte[] viewportImageData = new byte[viewportWidth * viewportHeight * 3]; // Assuming 3 channels
223 System.Threading.Tasks.Parallel.For(0, viewportHeight, row =>
224 {
225 try
226 {
227 int srcOffset = (clippedY + row) * canvasWidth * 3 + clippedX * 3;
228 int dstOffset = row * viewportWidth * 3;
229 Array.Copy(stitchedImageData, srcOffset, viewportImageData, dstOffset, viewportWidth * 3);
230 }
231 catch (Exception ex)
232 {
233 Console.WriteLine("An error occurred while extracting the viewport: " + ex.Message);
234 }
235 });
236
237 return viewportImageData; // Return the extracted viewport
238 }
239 }
240 catch (Exception ex)
241 {
242 Console.WriteLine("An error occurred: " + ex.Message);
243 Initialize(); // Reinitialize in case of errors
244 return null;
245 }
246 }

Member Data Documentation

◆ gpuTiles

List<Tuple<TileInfo, CudaDeviceVariable<byte> > > BioLib.Stitch.gpuTiles = new List<Tuple<TileInfo, CudaDeviceVariable<byte>>>()

Definition at line 35 of file Stitch.cs.


The documentation for this class was generated from the following file: