extern alias CoreDrawing; using System; using ZeroLevel.ML.DNN.Models; namespace ZeroLevel.ML.Services { internal sealed class ImageRegionReader { private readonly CoreDrawing.System.Drawing.Imaging.BitmapData _bitmapData; private readonly RegionInfo _regionInfo; public int TensorIndex => _regionInfo.Index; public int X => _regionInfo.X; public int Y => _regionInfo.Y; public ImageRegionReader(CoreDrawing.System.Drawing.Imaging.BitmapData bitmapData, RegionInfo regionInfo) { _bitmapData = bitmapData; _regionInfo = regionInfo; } /// /// dx, dy, r, g, b /// /// public void Read(Action handler) { throw new NotImplementedException(); unsafe { var cropSizeX = _regionInfo.CropSizeX; var cropSizeY = _regionInfo.CropSizeY; var right = _regionInfo.X + _regionInfo.CropSizeX; if (right > _bitmapData.Width) { cropSizeX = _bitmapData.Width - _regionInfo.X; } var bottom = _regionInfo.Y + _regionInfo.CropSizeY; if (bottom > _bitmapData.Height) { cropSizeY = _bitmapData.Height - _regionInfo.Y; } byte* scan0 = (byte*)_bitmapData.Scan0.ToPointer(); for (var dy = 0; dy < cropSizeY; dy++) { byte* row = scan0 + (_regionInfo.Y + dy + 0) * _regionInfo.Stride; for (var dx = 0; dx < cropSizeX; dx++) { int bIndex = (dx + _regionInfo.X) * _regionInfo.BytesPerPixel; int gIndex = bIndex + 1; int rIndex = bIndex + 2; int b = row[rIndex]; int g = row[gIndex]; int r = row[bIndex]; handler.Invoke(dx, dy, r, g, b); } } } } public void FillTensor(TensorPoolItem tensor) { unsafe { var cropSizeX = _regionInfo.CropSizeX; var cropSizeY = _regionInfo.CropSizeY; var right = _regionInfo.X + _regionInfo.CropSizeX; if (right > _bitmapData.Width) { cropSizeX = _bitmapData.Width - _regionInfo.X; } var bottom = _regionInfo.Y + _regionInfo.CropSizeY; if (bottom > _bitmapData.Height) { cropSizeY = _bitmapData.Height - _regionInfo.Y; } byte* scan0 = (byte*)_bitmapData.Scan0.ToPointer(); var x_l = ((int)Math.Ceiling((double)(cropSizeX / 8))) * 8; var y_l = ((int)Math.Ceiling((double)(cropSizeY / 8))) * 8; int idx; for (var dy = 0; dy < cropSizeY; dy++) { byte* row = scan0 + (_regionInfo.Y + dy + 0) * _regionInfo.Stride; for (var dx = 0; dx < x_l; dx += 8) { idx = (0 + dx + _regionInfo.X) * _regionInfo.BytesPerPixel; tensor.Tensor[tensor.TensorIndex, 0, dx + 0, dy] = row[idx + 0]; tensor.Tensor[tensor.TensorIndex, 1, dx + 0, dy] = row[idx + 1]; tensor.Tensor[tensor.TensorIndex, 2, dx + 0, dy] = row[idx + 2]; idx = (1 + dx + _regionInfo.X) * _regionInfo.BytesPerPixel; tensor.Tensor[tensor.TensorIndex, 0, dx + 1, dy] = row[idx + 0]; tensor.Tensor[tensor.TensorIndex, 1, dx + 1, dy] = row[idx + 1]; tensor.Tensor[tensor.TensorIndex, 2, dx + 1, dy] = row[idx + 2]; idx = (2 + dx + _regionInfo.X) * _regionInfo.BytesPerPixel; tensor.Tensor[tensor.TensorIndex, 0, dx + 2, dy] = row[idx + 0]; tensor.Tensor[tensor.TensorIndex, 1, dx + 2, dy] = row[idx + 1]; tensor.Tensor[tensor.TensorIndex, 2, dx + 2, dy] = row[idx + 2]; idx = (3 + dx + _regionInfo.X) * _regionInfo.BytesPerPixel; tensor.Tensor[tensor.TensorIndex, 0, dx + 3, dy] = row[idx + 0]; tensor.Tensor[tensor.TensorIndex, 1, dx + 3, dy] = row[idx + 1]; tensor.Tensor[tensor.TensorIndex, 2, dx + 3, dy] = row[idx + 2]; idx = (4 + dx + _regionInfo.X) * _regionInfo.BytesPerPixel; tensor.Tensor[tensor.TensorIndex, 0, dx + 4, dy] = row[idx + 0]; tensor.Tensor[tensor.TensorIndex, 1, dx + 4, dy] = row[idx + 1]; tensor.Tensor[tensor.TensorIndex, 2, dx + 4, dy] = row[idx + 2]; idx = (5 + dx + _regionInfo.X) * _regionInfo.BytesPerPixel; tensor.Tensor[tensor.TensorIndex, 0, dx + 5, dy] = row[idx + 0]; tensor.Tensor[tensor.TensorIndex, 1, dx + 5, dy] = row[idx + 1]; tensor.Tensor[tensor.TensorIndex, 2, dx + 5, dy] = row[idx + 2]; idx = (6 + dx + _regionInfo.X) * _regionInfo.BytesPerPixel; tensor.Tensor[tensor.TensorIndex, 0, dx + 6, dy] = row[idx + 0]; tensor.Tensor[tensor.TensorIndex, 1, dx + 6, dy] = row[idx + 1]; tensor.Tensor[tensor.TensorIndex, 2, dx + 6, dy] = row[idx + 2]; idx = (7 + dx + _regionInfo.X) * _regionInfo.BytesPerPixel; tensor.Tensor[tensor.TensorIndex, 0, dx + 7, dy] = row[idx + 0]; tensor.Tensor[tensor.TensorIndex, 1, dx + 7, dy] = row[idx + 1]; tensor.Tensor[tensor.TensorIndex, 2, dx + 7, dy] = row[idx + 2]; } if (x_l < cropSizeX) { for(var dx = x_l; dx <= cropSizeX; dx++) { idx = (dx + _regionInfo.X) * _regionInfo.BytesPerPixel; tensor.Tensor[tensor.TensorIndex, 0, dx, dy] = row[idx + 0]; tensor.Tensor[tensor.TensorIndex, 1, dx, dy] = row[idx + 1]; tensor.Tensor[tensor.TensorIndex, 2, dx, dy] = row[idx + 2]; } } } } } } }