< Summary - ReFlex - Library

Information
Class: ReFlex.Core.Networking.Util.EmulatedPointCloud
Assembly: ReFlex.Core.Networking
File(s): D:\a\reflex\reflex\library\src\Core\Networking\Util\EmulatedPointCloud.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 146
Coverable lines: 146
Total lines: 245
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 56
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%210%
get_MaxDepthImageValue()100%210%
get_Points()100%210%
get_GenerateDepthImage()100%210%
.ctor(...)100%210%
InitializePointCloud(...)0%4260%
Reset()0%2040%
UpdateFromInteractions(...)0%506220%
UpdateFromGreyScaleImage(...)0%110100%
ComputeIndex(...)0%7280%
GetUpdatedDepthImage()0%620%
GetImageDefaultValue()100%210%
SetDepthImageValue(...)0%2040%
Combine(...)100%210%

File(s)

D:\a\reflex\reflex\library\src\Core\Networking\Util\EmulatedPointCloud.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using NLog;
 4using ReFlex.Core.Common.Components;
 5using ReFlex.Core.Common.Util;
 6using Math = System.Math;
 7
 8namespace ReFlex.Core.Networking.Util
 9{
 10    public class EmulatedPointCloud
 11    {
 012        private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
 13
 14        private StreamParameter _currentParams;
 15        private readonly EmulatorParameters _emulatorParameters;
 16        private readonly float _pushRange;
 17        private readonly float _pullRange;
 18
 19        private byte[] _image;
 20
 21        private uint _numChannels;
 22        private uint _bytesPerChannel;
 023        public uint MaxDepthImageValue { get => 255 * _bytesPerChannel; }
 24
 025        public Point3[] Points { get; private set; }
 26
 027        public bool GenerateDepthImage {get; set; } = true;
 28
 029        public EmulatedPointCloud(EmulatorParameters param)
 030        {
 031            _emulatorParameters = param;
 032            _pushRange = _emulatorParameters.PlaneDistanceInMeter - _emulatorParameters.MinDepthInMeter;
 033            _pullRange = _emulatorParameters.MaxDepthInMeter - _emulatorParameters.PlaneDistanceInMeter;
 034        }
 35
 36        public void InitializePointCloud(StreamParameter param)
 037        {
 038            if (param == null)
 039            {
 040                Logger.Error("Invalid parameter for intializatoin of point cloud.");
 041                return;
 42            }
 43
 044            _bytesPerChannel = DepthImageFormatTools.BytesPerChannel(param.Format);
 045            _numChannels = DepthImageFormatTools.NumChannels(param.Format);
 046            var defaultValue = GetImageDefaultValue();
 47
 048            _currentParams = param;
 49
 050            var result = new Point3[param.Width * param.Height].AsSpan<Point3>();
 051            _image = new byte[param.Width * param.Height * _bytesPerChannel * _numChannels];
 52
 053            var xOffset = _emulatorParameters.WidthInMeters / param.Width;
 054            var yOffset = _emulatorParameters.HeightInMeters / param.Height;
 55
 056            var xMin = 0 -_emulatorParameters.WidthInMeters * 0.5f;
 057            var yMin = 0 -_emulatorParameters.HeightInMeters * 0.5f;
 58
 059            for (var x = 0; x < param.Width; ++x)
 060            {
 061                var xPos = xMin + (xOffset * x);
 62
 063                for (var y = 0; y < param.Height; ++y)
 064                {
 065                    var yPos = yMin + (yOffset * y);
 66
 067                    var idx = ComputeIndex(x, y);
 68
 069                    result[idx] = new Point3(xPos, yPos, _emulatorParameters.PlaneDistanceInMeter);
 70
 071                    SetDepthImageValue(defaultValue, idx);
 072                }
 073            }
 74
 075            Points = result.ToArray();
 076        }
 77
 78        public void Reset()
 079        {
 080            var defaultValue = GetImageDefaultValue();
 81
 082            for (int i = 0; i < Points.Length; ++i)
 083            {
 084                Points[i].Z = _emulatorParameters.PlaneDistanceInMeter;
 85
 086                if (GenerateDepthImage)
 087                    SetDepthImageValue(defaultValue, i);
 088            }
 089        }
 90
 91        public void UpdateFromInteractions(List<Interaction> interactions)
 092        {
 093            var squaredRadius = _emulatorParameters.Radius * _emulatorParameters.Radius;
 094            var depthImageDefaultValue = GetImageDefaultValue();
 95
 096            for (var i = 0; i < interactions.Count; ++i)
 097            {
 098                var interaction = interactions[i];
 99
 0100                var centerX = (int)interaction.Position.X;
 0101                var centerY = (int)interaction.Position.Y;
 102
 0103                var offset = interaction.Position.Z < 0 ? interaction.Position.Z * _pushRange : interaction.Position.Z *
 104
 0105                var depthImageValuePeak = interaction.Position.Z < 0 ? 0 : MaxDepthImageValue;
 106
 0107                var radius = (int) Math.Abs(Math.Round(_emulatorParameters.Radius * offset));
 108
 0109                for (var x = -radius; x < radius; ++x)
 0110                {
 0111                    for (var y = -radius; y < radius; ++y)
 0112                    {
 0113                       var idx = ComputeIndex(centerX + x, centerY + y);
 114
 0115                        if (x == 0 && y == 0)
 0116                        {
 0117                            Points[idx].Z = _emulatorParameters.PlaneDistanceInMeter + offset;
 118
 0119                            if (GenerateDepthImage)
 0120                                SetDepthImageValue(depthImageValuePeak, idx);
 0121                            continue;
 122                        }
 123
 0124                        var dist = Math.Sqrt( x * x + y * y);
 125
 0126                        var maxDist = Math.Sqrt(2f * radius * radius);
 127
 0128                        var smooth = (float) Math.Sqrt(dist/maxDist);
 129
 0130                        if (dist < squaredRadius)
 0131                        {
 0132                            var factor = 1.0f - smooth;
 133
 0134                            var centerZ = _emulatorParameters.PlaneDistanceInMeter + (offset * factor);
 135
 0136                            Points[idx].Z = centerZ;
 137
 0138                            if (GenerateDepthImage) {
 0139                                var factorDepthImage = factor * depthImageDefaultValue;
 0140                                var depthImageValue = interaction.Position.Z < 0 ? (byte) (depthImageDefaultValue - fact
 0141                                SetDepthImageValue(depthImageValue, idx);
 0142                            }
 0143                        }
 0144                    }
 0145                }
 0146            }
 0147        }
 148
 149        public void UpdateFromGreyScaleImage(ImageByteArray imageData)
 0150        {
 0151            if (imageData.ImageData.Length < imageData.Width * imageData.Height * imageData.BytesPerChannel * _numChanne
 0152            {
 0153                Logger.Log(LogLevel.Error, $"Incorrect Size for image data: Size of Byte Array: {imageData.ImageData.Len
 0154                return;
 155            }
 156
 0157            var defaultDepth = GetImageDefaultValue();
 158
 159            // compute global offset - center of the plane is in the origin
 0160            var xMin = -_emulatorParameters.WidthInMeters * 0.5f;
 0161            var yMin = -_emulatorParameters.HeightInMeters * 0.5f;
 162
 163            // compute offset per pixel
 0164            var pxOffsetX = _emulatorParameters.WidthInMeters / _currentParams.Width;
 0165            var pxOffsetY = _emulatorParameters.HeightInMeters / _currentParams.Height;
 166
 0167            var iterationStep = _numChannels * _bytesPerChannel;
 168
 0169            for (uint i = 0; i < imageData.ImageData.Length; i+=iterationStep)
 0170            {
 0171                var zIdx = i + ((_numChannels - 1) * _bytesPerChannel);
 172
 0173                var dist = (int) imageData.ImageData[zIdx];
 174
 0175                if (_bytesPerChannel == 2)
 0176                {
 0177                    dist = Combine(imageData.ImageData[zIdx], imageData.ImageData[zIdx + 1]);
 0178                }
 179
 180                // skip all values that are on the normal plane (== 127)
 0181                if (dist == defaultDepth)
 0182                    continue;
 183
 184                // 3 channels --> divide
 0185                var pos = i / (iterationStep);
 186
 187                // compute pixel index
 0188                var xPx = pos % _currentParams.Width;
 0189                var yPx = pos / _currentParams.Width;
 190
 0191                var x = xMin + (xPx * pxOffsetX);
 0192                var y = yMin + (yPx * pxOffsetY);
 193
 0194                var valueRange = 127f * _bytesPerChannel;
 195
 0196                var z = dist < defaultDepth
 0197
 0198                    // push: normalized depth * push range + min depth
 0199                    ? (dist / (valueRange)) * _pushRange + _emulatorParameters.MinDepthInMeter
 0200
 0201                    // pull: subtract push range, normalize depth behind plane * pull range + plane distance
 0202                    : ((dist - valueRange) / valueRange) * _pullRange + _emulatorParameters.PlaneDistanceInMeter;
 203
 204
 0205                Points[pos] = new Point3(x, y, z);
 0206            }
 0207        }
 208
 209        public int ComputeIndex(int x, int y)
 0210        {
 0211            if (x < 0 || x >= _currentParams.Width || y < 0 || y >= _currentParams.Height)
 0212                return 0;
 213
 0214            return y * _currentParams.Width + x;
 0215        }
 216
 217        public ImageByteArray GetUpdatedDepthImage()
 0218        {
 0219            return _image == null
 0220                ? new ImageByteArray(new byte[1],1,1, 1, 1, DepthImageFormat.Greyscale8bpp)
 0221                : new ImageByteArray(_image, _currentParams.Width, _currentParams.Height, _bytesPerChannel, _numChannels
 0222        }
 223
 224        private uint GetImageDefaultValue()
 0225        {
 226            // divide by 2: shifting bytes to the right
 0227            return (MaxDepthImageValue >> 1) * _bytesPerChannel;
 0228        }
 229
 230        private void SetDepthImageValue(uint value, int index)
 0231        {
 0232            var bytes = BitConverter.GetBytes(value);
 233
 0234            for (var n = 0; n < _numChannels; n++)
 0235                for (var b = 0; b < _bytesPerChannel; b++)
 0236                    _image[index * _numChannels + n + b] = bytes[0];
 0237        }
 238
 239        private static int Combine(byte b1, byte b2)
 0240        {
 241            // return b1 << 8 | b2;
 0242            return b1 | (b2 << 8);
 0243        }
 244    }
 245}