public BasicStats GetStats(BitmapAdapter bitmap, ImageManipulationInfo manipulationInfo) { // Console.WriteLine(manipulationInfo.ToString()); var fast = new FastBitmap.FastBitmap(bitmap.GetSegment(manipulationInfo)); return(GetBasicStats(fast, new Rectangle(0, 0, fast.Width, fast.Height))); }
private BasicStats GetBasicStats(FastBitmap.FastBitmap bitmap, Rectangle sourceRectangle) { List <int> lowResRPoints = new List <int>(12); List <int> lowResGPoints = new List <int>(12); List <int> lowResBPoints = new List <int>(12); List <int> lowResIntensityPoints = new List <int>(12); foreach (var lowResRect in GetLowResRectangles(sourceRectangle)) { var segment = bitmap.GetColors(lowResRect).ToArray(); lowResRPoints.Add(ApplyFilter(segment, c => c.R, LowResSingleIntFilter)); lowResGPoints.Add(ApplyFilter(segment, c => c.G, LowResSingleIntFilter)); lowResBPoints.Add(ApplyFilter(segment, c => c.B, LowResSingleIntFilter)); lowResIntensityPoints.Add(ApplyFilter(segment, c => (int)((c.R + c.G + c.B) / 3.0), LowResSingleIntFilter)); } return(new BasicStats() { LowResR = new ConvolutionResult(lowResRPoints), LowResG = new ConvolutionResult(lowResGPoints), LowResB = new ConvolutionResult(lowResBPoints), LowResIntensity = new ConvolutionResult(lowResIntensityPoints), }); }
public IEnumerable <Bitmap> GetRefinedMatches2(FastBitmap.FastBitmap bitmap, ImageManipulationInfo manipulationInfo) { ImageSegments[] matches = _matchFinder.Value.GetMatches(_statsGenerator.GetStats(bitmap, manipulationInfo)); return(_matchFinder.Value.RefineMatches2(_statsGenerator.GetAdvancedStats(bitmap, manipulationInfo.Rectangle), matches, _loader, _statsGenerator) .Select(m => new { Image = new BitmapAdapter(m.Image.ToBitmap()), Segments = m.ManipulationInfos }) .SelectMany(m => m.Segments.Select(m.Image.GetSegment))); }
private FlatArray2DArray <int>[] GetMidResConvolution2(PhysicalImage physicalImage) { int GetConvolution(IEnumerable <int> convolutionPixels, double[] filter) { int value = (int)convolutionPixels .Zip(filter, (a, b) => a * b) .Sum(); value = value < 0 ? 0 : value; value = value > 255 ? 255 : value; return(value); } FastBitmap.FastBitmap bitmap = _loader.LoadImage(physicalImage.ImagePath); var bitmapAsIntensity = new FastBitmapToIntensity2DArrayAdapter(bitmap); var convolution135Result = new FlatArray2DArray <int>(new int[bitmap.Width * bitmap.Height], bitmap.Width, bitmap.Height); var convolution45Result = new FlatArray2DArray <int>(new int[bitmap.Width * bitmap.Height], bitmap.Width, bitmap.Height); var convolutionHorizontalResult = new FlatArray2DArray <int>(new int[bitmap.Width * bitmap.Height], bitmap.Width, bitmap.Height); var convolutionVerticalResult = new FlatArray2DArray <int>(new int[bitmap.Width * bitmap.Height], bitmap.Width, bitmap.Height); var convolutionEdgeResult = new FlatArray2DArray <int>(new int[bitmap.Width * bitmap.Height], bitmap.Width, bitmap.Height); bitmap.Lock(); for (int y = 0; y < bitmap.Height; y++) { for (int x = 0; x < bitmap.Width; x++) { var convolutionPixels = GetConvolutionPixels(bitmapAsIntensity, new Rectangle(x - 1, y - 1, 3, 3)).ToArray(); convolution135Result[x, y] = GetConvolution(convolutionPixels, StatsGenerator.MidRes135Filter); convolution45Result[x, y] = GetConvolution(convolutionPixels, StatsGenerator.MidRes45Filter); convolutionHorizontalResult[x, y] = GetConvolution(convolutionPixels, StatsGenerator.MidResHorizontalFilter); convolutionVerticalResult[x, y] = GetConvolution(convolutionPixels, StatsGenerator.MidResVerticalFilter); convolutionEdgeResult[x, y] = GetConvolution(convolutionPixels, StatsGenerator.MidResEdgeFilter); } } bitmap.Unlock(); var convolutionResults = new[] { convolution135Result, convolution45Result, convolutionHorizontalResult, convolutionVerticalResult, convolutionEdgeResult, }; return(convolutionResults); }
public Bitmap GetSegment(ImageManipulationInfo manipulationInfo) { var targetBitmap = new Bitmap(manipulationInfo.Width, manipulationInfo.Height); FastBitmap.FastBitmap segment = new FastBitmap.FastBitmap(targetBitmap); segment.Lock(); segment.CopyRegion(_bitmap, manipulationInfo.Rectangle, manipulationInfo.AsZeroBasedRectangleOfSameSize()); segment.Unlock(); return(targetBitmap); }
/* * public void DumpStats() * { * var img = _class1.GetSourceImage(); * * var randomSourceSegment = img.Segments.Random().First().ManipulationInfo; * SourceImage = _class1.GetBitmap(img.Image, randomSourceSegment).ToBitmapImage(); * OnPropertyChanged(nameof(SourceImage)); * * // StatsGenerator statsGenerator = new StatsGenerator(Loader); * // var convolutionImages = statsGenerator.GetMidResConvolutionAsBitmap(img.Image).Select(bm => bm.ToBitmapImage()); * // var convolutionReducedImages = statsGenerator.GetMidResConvolutionReducedAsBitmap(img.Image).Select(bm => bm.ToBitmapImage()); * * ConvolutionObservableCollection.Clear(); * ConvolutionReducedObservableCollection.Clear(); * * /* * foreach (var convolutionImage in convolutionImages) * { * ConvolutionObservableCollection.Add(convolutionImage); * } * * foreach (var convolutionImage in convolutionReducedImages) * { * ConvolutionReducedObservableCollection.Add(convolutionImage); * } #1# * * /* * var matchedImages = class1.CompareImageToAlphabet(img.Image, firstSegment) * .Select(i => i.ToBitmapImage()); * MatchesObservableCollection.Clear(); * foreach (var matchedImage in matchedImages) * { * MatchesObservableCollection.Add(matchedImage); * } #1# * * * var refinedMatchedImages = _class1.GetRefinedMatches(img.Image, randomSourceSegment) * .Select(i => i.ToBitmapImage()); * RefinedMatchesObservableCollection.Clear(); * foreach (var matchedImage in refinedMatchedImages) * { * RefinedMatchesObservableCollection.Add(matchedImage); * } * * var refinedMatchedImages2 = _class1.GetRefinedMatches2(img.Image, randomSourceSegment) * .Select(i => i.ToBitmapImage()); * RefinedMatches2ObservableCollection.Clear(); * foreach (var matchedImage in refinedMatchedImages2) * { * RefinedMatches2ObservableCollection.Add(matchedImage); * } * * OnPropertyChanged(nameof(MatchingImages)); * OnPropertyChanged(nameof(RefinedMatchingImages)); * OnPropertyChanged(nameof(RefinedMatchingImages2)); * } */ public void ProduceImage() { var openFileDialog1 = new OpenFileDialog(); var dialogResult = openFileDialog1.ShowDialog(); if (!dialogResult.HasValue || !dialogResult.Value) { return; } var sourceBmp = _class1.LoadSourceImage(openFileDialog1.FileName); SourceImage = sourceBmp.ToBitmapImage(); var img = _class1.GetSourceImage(); FastBitmap.FastBitmap originalImage = Loader.LoadImage(img.Image.ImagePath); ConvolutionObservableCollection.Clear(); ConvolutionReducedObservableCollection.Clear(); var matches = new List <SourceAndMatch>(); foreach (var segmentAndStatse in img.Segments) { // Get matches var refinedMatchedImages = _class1.GetRefinedMatches2(originalImage, segmentAndStatse.ManipulationInfo); // Select a match // TODO: Do better var bestMatch = refinedMatchedImages.SelectRandom(); // var bestMatch = refinedMatchedImages.First(); var match = new SourceAndMatch(segmentAndStatse.ManipulationInfo, bestMatch); matches.Add(match); } var newImageBuilder = new ReconstructedImageBuilder(originalImage, 0.75); newImageBuilder.ApplyMatches(matches); newImageBuilder.SaveAs(@"c:\src\MosaicMaker2\result.bmp"); ResultImage = newImageBuilder.NewImage.ToBitmapImage(); }
public AdvancedStats GetAdvancedStats(FastBitmap.FastBitmap bitmap, Rectangle sourceRectangle) { List <int> midResAngle45Points = new List <int>(48); List <int> midResAngle135Points = new List <int>(48); List <int> midResVerticalPoints = new List <int>(48); List <int> midResHorizontalPoints = new List <int>(48); List <int> midResEdgePoints = new List <int>(48); List <int> midResRPoints = new List <int>(48); List <int> midResGPoints = new List <int>(48); List <int> midResBPoints = new List <int>(48); List <int> midResIntensityPoints = new List <int>(48); foreach (var midResRect in GetMidResRectangles(sourceRectangle)) { Color[] segment = bitmap.GetColors(midResRect).ToArray(); int[] greyScaleSegment = segment.Select(c => (int)((c.R + c.G + c.B) / 3.0)).ToArray(); midResAngle45Points.Add(ApplyFilter(greyScaleSegment, MidRes45Filter)); midResAngle135Points.Add(ApplyFilter(greyScaleSegment, MidRes135Filter)); midResVerticalPoints.Add(ApplyFilter(greyScaleSegment, MidResVerticalFilter)); midResHorizontalPoints.Add(ApplyFilter(greyScaleSegment, MidResHorizontalFilter)); midResEdgePoints.Add(ApplyFilter(greyScaleSegment, MidResEdgeFilter)); midResRPoints.Add(ApplyFilter(segment, c => c.R, ReduceIdentityFilter)); midResGPoints.Add(ApplyFilter(segment, c => c.G, ReduceIdentityFilter)); midResBPoints.Add(ApplyFilter(segment, c => c.B, ReduceIdentityFilter)); midResIntensityPoints.Add(ApplyFilter(greyScaleSegment, ReduceIdentityFilter)); } return(new AdvancedStats() { MidRes45 = new ConvolutionResult(midResAngle45Points), MidRes135 = new ConvolutionResult(midResAngle135Points), MidResVertical = new ConvolutionResult(midResVerticalPoints), MidResHorizontal = new ConvolutionResult(midResHorizontalPoints), MidResEdge = new ConvolutionResult(midResEdgePoints), MidResR = new ConvolutionResult(midResRPoints), MidResG = new ConvolutionResult(midResGPoints), MidResB = new ConvolutionResult(midResBPoints), MidResIntensity = new ConvolutionResult(midResIntensityPoints), }); }
/// <summary> /// Initializes a new instance of the FastBitmapLocker struct with an initial fast bitmap object. /// The fast bitmap object passed will be unlocked after calling Dispose() on this struct /// </summary> /// <param name="fastBitmap">A fast bitmap to attach to this locker which will be released after a call to Dispose</param> public FastBitmapLocker(FastBitmap fastBitmap) { _fastBitmap = fastBitmap; }
/// <summary> /// Copies a region of the source bitmap into this fast bitmap /// </summary> /// <param name="source">The source image to copy</param> /// <param name="srcRect">The region on the source bitmap that will be copied over</param> /// <param name="destRect">The region on this fast bitmap that will be changed</param> /// <exception cref="ArgumentException">The provided source bitmap is the same bitmap locked in this FastBitmap</exception> public void CopyRegion(Bitmap source, Rectangle srcRect, Rectangle destRect) { // Throw exception when trying to copy same bitmap over if (source == _bitmap) { throw new ArgumentException("Copying regions across the same bitmap is not supported", nameof(source)); } Rectangle srcBitmapRect = new Rectangle(0, 0, source.Width, source.Height); Rectangle destBitmapRect = new Rectangle(0, 0, _width, _height); // Check if the rectangle configuration doesn't generate invalid states or does not affect the target image if (srcRect.Width <= 0 || srcRect.Height <= 0 || destRect.Width <= 0 || destRect.Height <= 0 || !srcBitmapRect.IntersectsWith(srcRect) || !destRect.IntersectsWith(destBitmapRect)) { return; } // Find the areas of the first and second bitmaps that are going to be affected srcBitmapRect = Rectangle.Intersect(srcRect, srcBitmapRect); // Clip the source rectangle on top of the destination rectangle in a way that clips out the regions of the original bitmap // that will not be drawn on the destination bitmap for being out of bounds srcBitmapRect = Rectangle.Intersect(srcBitmapRect, new Rectangle(srcRect.X, srcRect.Y, destRect.Width, destRect.Height)); destBitmapRect = Rectangle.Intersect(destRect, destBitmapRect); // Clipt the source bitmap region yet again here srcBitmapRect = Rectangle.Intersect(srcBitmapRect, new Rectangle(-destRect.X + srcRect.X, -destRect.Y + srcRect.Y, _width, _height)); // Calculate the rectangle containing the maximum possible area that is supposed to be affected by the copy region operation int copyWidth = Math.Min(srcBitmapRect.Width, destBitmapRect.Width); int copyHeight = Math.Min(srcBitmapRect.Height, destBitmapRect.Height); if (copyWidth == 0 || copyHeight == 0) { return; } int srcStartX = srcBitmapRect.Left; int srcStartY = srcBitmapRect.Top; int destStartX = destBitmapRect.Left; int destStartY = destBitmapRect.Top; using (FastBitmap fastSource = source.FastLock()) { ulong strideWidth = (ulong)copyWidth * BytesPerPixel; for (int y = 0; y < copyHeight; y++) { int destX = destStartX; int destY = destStartY + y; int srcX = srcStartX; int srcY = srcStartY + y; long offsetSrc = (srcX + srcY * fastSource._strideWidth); long offsetDest = (destX + destY * _strideWidth); memcpy(_scan0 + offsetDest, fastSource._scan0 + offsetSrc, strideWidth); } } }
public BasicStats GetStats(FastBitmap.FastBitmap bitmap, ImageManipulationInfo manipulationInfo) { return(GetBasicStats(bitmap, manipulationInfo.Rectangle)); }