private void Extrapolate(ColorMap map, int[] srcHist, int minColor, int maxColor) { var min = srcHist.TakeWhile(p => p == 0).Count(); var max = srcHist.Length - srcHist.Reverse().TakeWhile(p => p == 0).Count() - 1; var first = map.First(); var last = map.Last(); var sampleCount = last - first + 1; var mappedColors = Enumerable.Range(first, sampleCount).Where(map.Contains);//.Where(p => srcHist[p] > 50); var mappedCount = mappedColors.Count(); var limit = Math.Max(mappedCount / 5, Math.Min(mappedCount, 10)); if (min < first) { var avgDiff = mappedColors.Take(limit).Sum(p => map.Average(p) - p) / limit; var mapped = min + avgDiff; map.AddReal(min, Math.Max(minColor, mapped)); Log(() => $"Min: {min} -> {mapped:F3}"); } if (max > last) { var avgDiff = mappedColors.Reverse().Take(limit).Sum(p => map.Average(p) - p) / limit; var mapped = max + avgDiff; map.AddReal(max, Math.Min(maxColor, mapped)); Log(() => $"Max: {max} -> {mapped:F3}"); } }
private void Interpolate(ColorMap map, int min, int max, int srcBits, int refBits) { var mult = Math.Pow(2, refBits - srcBits); var interpolator = GetInterpolator(map, mult); if (interpolator == null) { return; } var firstOldColor = map.First(); var lastOldColor = map.Last(); for (var oldColor = 0; oldColor < map.FixedMap.Length; oldColor++) { if (oldColor < firstOldColor || oldColor > lastOldColor) { map.AddReal(oldColor, oldColor * mult); } else if (!map.Contains(oldColor)) { var interpolated = interpolator.Interpolate(oldColor); interpolated = Math.Min(max, Math.Max(min, interpolated)); map.AddReal(oldColor, interpolated); } else if (map.FixedMap[oldColor] < 0) { var m = map.DynamicMap[oldColor]; var weights = m.Values.Sum(); if (weights < 1 - double.Epsilon) { var interpolated = interpolator.Interpolate(oldColor); interpolated = Math.Min(max, Math.Max(min, interpolated)); map.AddReal(oldColor, interpolated, 1 - weights); continue; var coef = 1 / weights; foreach (var color in m.Keys.ToArray()) { m[color] *= coef; } } } } }
public void TestColorMap() { var map = new ColorMap(8, 0, 1); map.AddReal(2, 3.2); var tuples = map.GetColorsAndWeights(); Assert.AreEqual(tuples.Item1[2][0], 3); Assert.AreEqual(tuples.Item1[2][1], 4); Assert.AreEqual(tuples.Item2[2][0], 0.8, 0.0001); Assert.AreEqual(tuples.Item2[2][1], 0.2, 0.0001); }
protected override VideoFrame GetFrame(int n) { var input = Child.GetFrame(n, StaticEnv); if (Intensity <= double.Epsilon) { return(input); } var writable = GetVideoInfo().pixel_type == Child.GetVideoInfo().pixel_type&& StaticEnv.MakeWritable(input); var output = writable ? input : NewVideoFrame(StaticEnv); var pixelSize = Sample.GetVideoInfo().IsRGB() ? 3 : 1; var firstFrame = Math.Max(0, n - AdjacentFramesCount); var lastFrame = Math.Min(Child.GetVideoInfo().num_frames - 1, n + AdjacentFramesCount); var dimensions = new[] { Enumerable.Range(n, lastFrame - n + 1), Enumerable.Range(firstFrame, n - firstFrame) }.SelectMany(range => range.Select(frame => { using (new VideoFrameCollector()) return(string.IsNullOrEmpty(CacheId) || frame == n ? histogramCache.GetFrame(frame, () => Extrapolation ? (frame == n ? input : Child.GetFrame(frame, StaticEnv)) : null, () => Sample.GetFrame(frame, StaticEnv), () => Reference.GetFrame(frame, StaticEnv), () => SampleMask?.GetFrame(frame, StaticEnv), () => ReferenceMask?.GetFrame(frame, StaticEnv)) : histogramCache[frame]); }).TakeWhile(dims => { var current = histogramCache[n]; return(dims != null && current.All(pair => current == dims || !dims[pair.Key].Empty && CompareHist(dims[pair.Key].DiffHist, pair.Value.DiffHist) < AdjacentFramesDiff)); }).SelectMany(p => p)).ToList(); Parallel.ForEach(planes, parallelOptions, plane => { Parallel.ForEach(realChannels, parallelOptions, channel => { var currentDimensions = dimensions .Where(p => p.Key.Equal(plane, channel)) .Select(p => p.Value).ToArray(); var sampleHist = AverageHist(sampleBits, currentDimensions.Select(p => p.SampleHist).ToArray()); var referenceHist = AverageHist(referenceBits, currentDimensions.Select(p => p.ReferenceHist).ToArray()); if (sampleHist == null || referenceHist == null) { return; } var map = GetTransitionMap(sampleHist, referenceHist, n, plane); if (Extrapolation) { var srcHist = AverageHist(referenceBits, currentDimensions.Select(p => p.InputHist).ToArray()); Extrapolate(map, srcHist, GetLowColor(referenceBits), GetHighColor(referenceBits, plane)); } Interpolate(map, GetLowColor(referenceBits), GetHighColor(referenceBits, plane), sampleBits, referenceBits); if (Intensity < 1) { var decreased = new ColorMap(sampleBits, n, Dither); for (var color = 0; color < 1 << sampleBits; color++) { decreased.AddReal(color, map.Average(color) * Intensity + color * (1 - Intensity)); } map = decreased; } var tuple = map.GetColorsAndWeights(); NativeUtils.ApplyColorMap(DynamicNoise ? Seed ^ n : 0, input.GetReadPtr(plane), input.GetPitch(plane), sampleBits > 8, output.GetWritePtr(plane), output.GetPitch(plane), referenceBits > 8, input.GetRowSize(plane), input.GetHeight(plane), pixelSize, channel, map.FixedMap, tuple.Item1, tuple.Item2); }); }); if (!writable) { input.Dispose(); } return(output); }