/// <summary> /// Initializes a new instance of the <see cref="MicroLensCollection"/> from metadata. /// </summary> /// <param name="metadata">The metadata with microlens array parameters.</param> /// <exception cref="ArgumentNullException"><paramref name="metadata"/> is null.</exception> /// <exception cref="ArgumentException"><paramref name="metadata"/> contains invalid or no information about the microlens array.</exception> /// <exception cref="NotSupportedException">The microlens tiling specified by <paramref name="metadata"/> is not supported.</exception> public MicroLensCollection(Json.FrameMetadata metadata) { if (metadata == null) { throw new ArgumentNullException("metadata"); } if (metadata.Image == null || metadata.Devices == null) { throw new ArgumentException("Critical metadata missing."); } _metadata = metadata; Json.Mla mla = metadata.Devices.Mla; Json.Sensor sensor = metadata.Devices.Sensor; if (mla == null || sensor == null) { throw new ArgumentException("Critical metadata missing."); } switch (mla.Tiling) { case "squareUniform": Initialize(metadata, 0.0, 1.0, 1.0); _orthogonal = true; break; case "hexUniformRowMajor": Initialize(metadata, HexagonalSkew, 1.0, HexagonalMinorFactor / 2.0); break; default: throw new NotSupportedException("Unsupported MLA tiling."); } }
private void Initialize(Json.FrameMetadata metadata, double skewX, double deltaXfactor, double deltaYfactor) { global::System.Diagnostics.Debug.Assert(deltaXfactor != 0, "X factor cannot be zero."); global::System.Diagnostics.Debug.Assert(deltaYfactor != 0, "Y factor cannot be zero."); Json.Mla mla = metadata.Devices.Mla; Json.Sensor sensor = metadata.Devices.Sensor; Json.Lens lens = metadata.Devices.Lens; if (sensor.PixelPitch == 0) { throw new ArgumentException("Pixel pitch cannot be zero.", "metadata"); } else if (mla.LensPitch == 0) { throw new ArgumentException("Lens pitch cannot be zero.", "metadata"); } else if (mla.ScaleFactor.X == 0 || mla.ScaleFactor.Y == 0) { throw new ArgumentException("Lens scale factor cannot be zero.", "metadata"); } _width = (int)metadata.Image.Width; _height = (int)metadata.Image.Height; decimal projectedPitch = mla.LensPitch; if (lens != null && lens.ExitPupilOffset.Z != 0) { projectedPitch *= (lens.ExitPupilOffset.Z + mla.SensorOffset.Z) / lens.ExitPupilOffset.Z; } _rotation = (double)mla.Rotation; _startX = _width / 2 + (double)(mla.SensorOffset.X / sensor.PixelPitch); _startY = _height / 2 + (double)(mla.SensorOffset.Y / sensor.PixelPitch); _radius = (double)(projectedPitch / sensor.PixelPitch); _deltaX = (double)(projectedPitch / sensor.PixelPitch * mla.ScaleFactor.X) * deltaXfactor; _deltaY = (double)(projectedPitch / sensor.PixelPitch * mla.ScaleFactor.Y) * deltaYfactor; _skewX = skewX; double pX = _startY * Math.Cos(_rotation) - _startX * Math.Sin(_rotation); double pY = _startY * Math.Sin(_rotation) + _startX * Math.Cos(_rotation); double xMin, xMax, yMin, yMax; if (_rotation >= 0) { xMin = -pY; xMax = _height * Math.Sin(_rotation) + _width * Math.Cos(_rotation) - pY; yMin = -_width *Math.Sin(_rotation) - pX; yMax = _height * Math.Cos(_rotation) - pX; } else { yMin = -pX; yMax = -_width *Math.Sin(_rotation) + _height * Math.Cos(_rotation) - pX; xMin = _width * Math.Sin(_rotation) - pY; xMax = _height * Math.Cos(_rotation) - pY; } if (_skewX > 0) { xMin -= (_height - _startY) * _skewX; xMax += _startY * _skewX; } else if (_skewX < 0) { xMin += _startY * _skewX; xMax -= (_height - _startY) * _skewX; } _xMinStep = (int)Math.Floor(xMin / _deltaX); _xMaxStep = (int)Math.Ceiling(xMax / _deltaX); _yMinStep = (int)Math.Floor(yMin / _deltaY); _yMaxStep = (int)Math.Ceiling(yMax / _deltaY); }