public static ZsImage ScaleTo(this ZsImage image, int width, int height) { while (image.Width < width || image.Height < height) { image = image.ScaleUp2x(); } return(image); }
public static ZsImage PyramidDownLab(this ZsImage labImage, bool blur) { return(labImage .FromLabToRgb() .FromRgbToArgb(Area2D.Create(0, 0, labImage.Width, labImage.Height)) .PyramidDownArgb(blur) .FromArgbToRgb(new[] { 1.0, 1.0, 1.0 }) .FromRgbToLab()); }
public ZsImage Clone() { var pixels = new double[_pixelsData.Length]; _pixelsData.CopyTo(pixels, 0); var clone = new ZsImage(pixels, Width, Height, NumberOfComponents); return(clone); }
public static ZsImage PyramidDownArgb(this ZsImage argbImage, Area2D filterArea, bool blur = true) { if (blur) { argbImage = argbImage.Filter(filterArea, GaussianFilter, 5, 5, 1.0 / 16.0); } argbImage = argbImage.ScaleDown2x(); return(argbImage); }
private static unsafe ZsImage MergeAlphaWithBackground(this ZsImage argbImage, double[] background) { if (argbImage == null) { throw new ArgumentNullException(); } const int NotDividableMinAmountElements = 80; int pointsAmount = argbImage.Width * argbImage.Height; double[] pixelsData = argbImage.PixelsData; // Decide on how many partitions we should divade the processing // of the elements. var partsCount = pointsAmount > NotDividableMinAmountElements ? Environment.ProcessorCount : 1; var partSize = (int)(pointsAmount / partsCount); Parallel.For(0, partsCount, partIndex => { var firstPointIndex = partIndex * partSize; var lastPointIndex = firstPointIndex + partSize - 1; if (partIndex == partsCount - 1) { lastPointIndex = pointsAmount - 1; } if (lastPointIndex > pointsAmount) { lastPointIndex = pointsAmount - 1; } fixed(double *pixelsDataP = pixelsData) { double alpha = 0.0; double nalpha = 1.0; for (int pointIndex = lastPointIndex; pointIndex >= firstPointIndex; pointIndex--) { int i = pointIndex * 4; // components should be in the range [0.0 , 1.0] alpha = *(pixelsDataP + i); nalpha = 1.0 - alpha; *(pixelsDataP + i + 1) = alpha * *(pixelsDataP + i + 1) + nalpha * background[0]; *(pixelsDataP + i + 2) = alpha * *(pixelsDataP + i + 2) + nalpha * background[1]; *(pixelsDataP + i + 3) = alpha * *(pixelsDataP + i + 3) + nalpha * background[2]; } } }); return(argbImage); }
public static unsafe ZsImage ToRgbImage(this Nnf nnf) { const int NotDividableMinAmountElements = 80; var nnfItems = nnf.GetNnfItems(); var width = nnf.DstWidth; var height = nnf.DstHeight; var pointsAmount = width * height; var rgb = new double[pointsAmount * 3]; // Decide on how many partitions we should divade the processing // of the elements. var partsCount = pointsAmount > NotDividableMinAmountElements ? Environment.ProcessorCount : 1; var partSize = (int)(pointsAmount / partsCount); Parallel.For(0, partsCount, partIndex => { var firstPointIndex = partIndex * partSize; var lastPointIndex = firstPointIndex + partSize - 1; if (partIndex == partsCount - 1) { lastPointIndex = pointsAmount - 1; } if (lastPointIndex > pointsAmount) { lastPointIndex = pointsAmount - 1; } fixed(double *nnfItemsP = nnfItems) fixed(double *rgbP = rgb) { var maxY = nnf.SourceHeight; var maxX = nnf.SourceWidth; var maxD = nnf.PatchSize * 100; for (var pointIndex = firstPointIndex; pointIndex <= lastPointIndex; pointIndex++) { var nnfindex = (pointIndex / width) * width * 2 + (pointIndex % width) * 2; var index = *(nnfItemsP + nnfindex + 0); var distance = nnfItems[nnfindex + 1]; *(rgbP + pointIndex * 3 + 0) = (double)(((int)index) % maxX) / maxX; *(rgbP + pointIndex * 3 + 1) = (double)(((int)index) / maxX) / maxY; *(rgbP + pointIndex * 3 + 2) = distance / maxD; } } }); var result = new ZsImage(rgb, width, height, 3); return(result); }
private static unsafe void GrayToRgb(ZsImage grayImage) { if (grayImage == null) { throw new ArgumentNullException(); } grayImage.InsertComponents(new[] { 0.0, 0.0 }, 1); const int NotDividableMinAmountElements = 80; double[] pixelsData = grayImage.PixelsData; int pointsAmount = grayImage.Width * grayImage.Height; // Decide on how many partitions we should divade the processing // of the elements. var partsCount = pointsAmount > NotDividableMinAmountElements ? Environment.ProcessorCount : 1; var partSize = (int)(pointsAmount / partsCount); Parallel.For(0, partsCount, partIndex => { var firstPointIndex = partIndex * partSize; var lastPointIndex = firstPointIndex + partSize - 1; if (partIndex == partsCount - 1) { lastPointIndex = pointsAmount - 1; } if (lastPointIndex > pointsAmount) { lastPointIndex = pointsAmount - 1; } fixed(double *pixelsDataP = pixelsData) { for (int pointIndex = lastPointIndex; pointIndex >= firstPointIndex; pointIndex--) { // Step 1. Inverse Companding int i = pointIndex * 3; // components should be in the range [0.0 , 1.0] double gray = *(pixelsDataP + i + 0); //*(pixelsDataP + i + 0) = gray; *(pixelsDataP + i + 1) = gray; *(pixelsDataP + i + 2) = gray; } } }); }
public static Area2D FromArgbToArea2D(this ZsImage argbImage) { //TODO: check the ColorSpace not the components amount if (argbImage.NumberOfComponents < 4) { throw new ArgumentException("Image in ARGB color space is required."); } var width = argbImage.Width; var height = argbImage.Height; var pixelsToFilterAmout = width * height; var componentsAmount = argbImage.NumberOfComponents; var pixelsData = argbImage.PixelsData; var pixelsArea = new byte[height][]; for (int y = 0; y < height; y++) { pixelsArea[y] = new byte[width]; } var partsCount = pixelsToFilterAmout > NotDividableMinAmountElements ? ThreadsCount : 1; var partSize = pixelsToFilterAmout / partsCount; //Parallel.For(0, partsCount, partIndex => for (int partIndex = 0; partIndex < partsCount; partIndex++) { var firstPointIndex = partIndex * partSize; var lastPointIndex = firstPointIndex + partSize - 1; if (partIndex == partsCount - 1) { lastPointIndex = pixelsToFilterAmout - 1; } if (lastPointIndex > pixelsData.Length) { lastPointIndex = pixelsToFilterAmout - 1; } for (int ii = firstPointIndex; ii <= lastPointIndex; ii++) { if (pixelsData[ii * componentsAmount] > 0) { pixelsArea[ii / width][ii % width] = 1; } } } //); return(Area2D.Create(0, 0, pixelsArea)); }
private static unsafe void RgbToGray(ZsImage rgbImage) { if (rgbImage == null) { throw new ArgumentNullException(); } const int NotDividableMinAmountElements = 80; double[] pixelsData = rgbImage.PixelsData; int pointsAmount = rgbImage.Width * rgbImage.Height; // Decide on how many partitions we should divade the processing // of the elements. var partsCount = pointsAmount > NotDividableMinAmountElements ? Environment.ProcessorCount : 1; var partSize = (int)(pointsAmount / partsCount); Parallel.For(0, partsCount, partIndex => { var firstPointIndex = partIndex * partSize; var lastPointIndex = firstPointIndex + partSize - 1; if (partIndex == partsCount - 1) { lastPointIndex = pointsAmount - 1; } if (lastPointIndex > pointsAmount) { lastPointIndex = pointsAmount - 1; } fixed(double *pixelsDataP = pixelsData) { for (int pointIndex = lastPointIndex; pointIndex >= firstPointIndex; pointIndex--) { int i = pointIndex * 3; // components should be in the range [0.0 , 1.0] double R = *(pixelsDataP + i + 0); double G = *(pixelsDataP + i + 1); double B = *(pixelsDataP + i + 2); *(pixelsDataP + i + 0) = R * 0.2989 + G * 0.5870 + B * 0.1140; } } }); rgbImage.RemoveComponents(1, 2); }
public static ZsImage PyramidUpLab(this ZsImage labImage) { labImage = labImage .FromLabToRgb() //.FromRgbToArgb() .ScaleUp2x() .Filter(GaussianFilter, 5, 5, 4.0 / 16.0) //.Filter(GaussianFilter3x3, 3, 3) //.FromArgbToRgb() .FromRgbToLab(); return(labImage); }
public static ZsImage CopyFromImage(this ZsImage destImage, Area2D destArea, ZsImage srcImage, Area2D srcArea) { if (destImage.NumberOfComponents != srcImage.NumberOfComponents) { throw new DifferentImageFormatException(); } var destImageArea = Area2D.Create(0, 0, destImage.Width, destImage.Height); var srcImageArea = Area2D.Create(0, 0, srcImage.Width, srcImage.Height); // move areas to origin and intersect them var oDestArea = destArea .Intersect(destImageArea) .Translate(-destArea.Bound.X, -destArea.Bound.Y); var oSrcArea = srcArea .Intersect(srcImageArea) .Translate(-srcArea.Bound.X, -srcArea.Bound.Y); var intersection = oDestArea.Intersect(oSrcArea); // move 2 intersected areas back destArea = intersection.Translate(destArea.Bound.X, destArea.Bound.Y); srcArea = intersection.Translate(srcArea.Bound.X, srcArea.Bound.Y); // copy pixels from intersection to intersection var destPixelIndecies = new int[destArea.ElementsCount]; var srcPixelIndecies = new int[srcArea.ElementsCount]; destArea.FillMappedPointsIndexes(destPixelIndecies, destImage.Width); srcArea.FillMappedPointsIndexes(srcPixelIndecies, srcImage.Width); var dstPixelsData = destImage.PixelsData; var srcPixelsData = srcImage.PixelsData; //TODO: Speedup using multiple threads and pointers for (int i = 0; i < destPixelIndecies.Length; i++) { var dstPixelIndex = destPixelIndecies[i]; var srcPixelIndex = srcPixelIndecies[i]; for (int j = 0; j < destImage.NumberOfComponents; j++) { dstPixelsData[dstPixelIndex * destImage.NumberOfComponents + j] = srcPixelsData[srcPixelIndex * destImage.NumberOfComponents + j]; } } return(destImage); }
public static ZsImage Filter(this ZsImage argbImage, Area2D filterArea, double[] filter, byte filterWidth, byte filterHeight, double multiplicator = 1.0) { if (filterWidth * filterHeight != filter.Length) { throw new ArgumentOutOfRangeException("The passed size of the filter doesn't match the filter size."); } var imageBoundArea = Area2D.Create(0, 0, argbImage.Width, argbImage.Height); filterArea = filterArea .Intersect(imageBoundArea); // The filter should be applied to the specified area of interest argbImage.FilterArea(filterArea, filter, filterWidth, filterHeight, multiplicator); return(argbImage); }
public static ZsImage PyramidDownLab(this ZsImage labImage) { return(labImage.PyramidDownLab(true)); }
private static void FilterArea(this ZsImage image, Area2D area, double[] filter, byte filterWidth, byte filterHeight, double multiplicator = 1.0) { if (filterWidth * filterHeight != filter.Length) { throw new ArgumentOutOfRangeException("The passed size of the filter doesn't match the filter size."); } var componentsAmount = image.NumberOfComponents; var imageWidth = image.Width; var imageHeight = image.Height; var pixelsToFilterAmout = area.ElementsCount; var resultPixelsData = image.PixelsData; var pixelsToFilterIndices = new int[pixelsToFilterAmout]; area.FillMappedPointsIndexes(pixelsToFilterIndices, imageWidth); var pixelsData = new double[resultPixelsData.Length]; resultPixelsData.CopyTo(pixelsData, 0); byte offs = (byte)(filterWidth / 2); var partsCount = pixelsToFilterAmout > NotDividableMinAmountElements ? ThreadsCount : 1; var partSize = pixelsToFilterAmout / partsCount; //Parallel.For(0, partsCount, partIndex => for (int partIndex = 0; partIndex < partsCount; partIndex++) { var pixelsToFilterIndicesSet = new HashSet <int>(pixelsToFilterIndices); var pixel = new double[componentsAmount]; var firstPointIndex = partIndex * partSize; var lastPointIndex = firstPointIndex + partSize - 1; if (partIndex == partsCount - 1) { lastPointIndex = pixelsToFilterAmout - 1; } if (lastPointIndex > pixelsData.Length) { lastPointIndex = pixelsToFilterAmout - 1; } for (int ii = firstPointIndex; ii <= lastPointIndex; ii++) { int pixelIndex = pixelsToFilterIndices[ii]; int ix = pixelIndex % imageWidth; int iy = pixelIndex / imageWidth; var sum = 0.0; for (int fy = -offs; fy <= offs; fy++) { for (int fx = -offs; fx <= offs; fx++) { int x = ix + fx; int y = iy + fy; if (x < 0 || imageWidth <= x || y < 0 || imageHeight <= y) { continue; } int neighbourIndex = x + y * imageWidth; if (!pixelsToFilterIndicesSet.Contains(neighbourIndex)) { continue; } var filterVal = filter[(fx + offs) + (fy + offs) * filterWidth] * multiplicator; sum += filterVal; var pi = y * imageWidth + x; var j = pi * componentsAmount; for (int c = 0; c < componentsAmount; c++) { pixel[c] += pixelsData[j + c] * filterVal; } } } if (sum <= 0) { sum = 1.0; } var pixelPosition = pixelIndex * componentsAmount; for (int c = 0; c < componentsAmount; c++) { resultPixelsData[pixelPosition + c] = pixel[c] / sum; if (resultPixelsData[pixelPosition + c] > 1) { resultPixelsData[pixelPosition + c] = 1.0; } if (resultPixelsData[pixelPosition + c] < 0) { resultPixelsData[pixelPosition + c] = 0.0; } pixel[c] = 0; } } } //); }
public static unsafe ZsImage SetComponentsValues(this ZsImage image, Area2D opaqueArea, double[] values, byte index) { if (image == null) { throw new ArgumentNullException(); } if (values == null) { throw new ArgumentNullException(nameof(values)); } if (values.Length == 0) { throw new ArgumentException("values can not be empty", nameof(values)); } if (index >= image.NumberOfComponents) { throw new ArgumentOutOfRangeException(nameof(index)); } if (opaqueArea == null) { throw new ArgumentNullException(nameof(opaqueArea)); } const int NotDividableMinAmountElements = 80; var imageArea = Area2D.Create(0, 0, image.Width, image.Height); opaqueArea = opaqueArea.Intersect(imageArea); if (!opaqueArea.IsEmpty) { byte componentsAmount = image.NumberOfComponents; int pointsAmount = opaqueArea.ElementsCount; int valuesAmount = componentsAmount >= index + values.Length ? values.Length : values.Length - ((index + values.Length) - componentsAmount); double[] pixelsData = image.PixelsData; var pointIndices = new int[opaqueArea.ElementsCount]; opaqueArea.FillMappedPointsIndexes(pointIndices, image.Width); // Decide on how many partitions we should divade the processing // of the elements. var partsCount = pointsAmount > NotDividableMinAmountElements ? Environment.ProcessorCount : 1; var partSize = (int)(pointsAmount / partsCount); Parallel.For(0, partsCount, partIndex => { var firstPointIndex = partIndex * partSize; var lastPointIndex = firstPointIndex + partSize - 1; if (partIndex == partsCount - 1) { lastPointIndex = pointsAmount - 1; } if (lastPointIndex > pointsAmount) { lastPointIndex = pointsAmount - 1; } fixed(double *pixelsDataP = pixelsData) { for (int pointIndex = lastPointIndex; pointIndex >= firstPointIndex; pointIndex--) { int i = pointIndices[pointIndex] * componentsAmount; for (int j = 0; j < valuesAmount; j++) { *(pixelsDataP + i + j + index) = values[j]; } } } }); } return(image); }
private static unsafe void RgbToLab(ZsImage rgbImage) { if (rgbImage == null) { throw new ArgumentNullException(); } const double K1 = 1.0 / 1.055; const double K2 = 1.0 / 12.92; const double Xr = 1.0 / 95.047; const double Yr = 1.0 / 100.0; const double Zr = 1.0 / 108.883; const int NotDividableMinAmountElements = 80; double[] pixelsData = rgbImage.PixelsData; int pointsAmount = rgbImage.Width * rgbImage.Height; // Decide on how many partitions we should divade the processing // of the elements. var partsCount = pointsAmount > NotDividableMinAmountElements ? Environment.ProcessorCount : 1; var partSize = (int)(pointsAmount / partsCount); Parallel.For(0, partsCount, partIndex => { var firstPointIndex = partIndex * partSize; var lastPointIndex = firstPointIndex + partSize - 1; if (partIndex == partsCount - 1) { lastPointIndex = pointsAmount - 1; } if (lastPointIndex > pointsAmount) { lastPointIndex = pointsAmount - 1; } fixed(double *pixelsDataP = pixelsData) { for (int pointIndex = lastPointIndex; pointIndex >= firstPointIndex; pointIndex--) { // Step 1. Inverse Companding int i = pointIndex * 3; // components should be in the range [0.0 , 1.0] double R = *(pixelsDataP + i + 0); double G = *(pixelsDataP + i + 1); double B = *(pixelsDataP + i + 2); // Inverse sRBG Companding http://www.brucelindbloom.com/index.html?Math.html var r = R > 0.04045 ? SMath.Pow((R + 0.055) * K1, 2.4) * 100.0 : R * K2 * 100.0; var g = G > 0.04045 ? SMath.Pow((G + 0.055) * K1, 2.4) * 100.0 : G * K2 * 100.0; var b = B > 0.04045 ? SMath.Pow((B + 0.055) * K1, 2.4) * 100.0 : B * K2 * 100.0; // Step 2. Linear RGB to XYZ double xr = (r * 0.4124 + g * 0.3576 + b * 0.1805) * Xr; double yr = (r * 0.2126 + g * 0.7152 + b * 0.0722) * Yr; double zr = (r * 0.0193 + g * 0.1192 + b * 0.9505) * Zr; double fx = xr > e ? SMath.Pow(xr, OneThird) : (k * xr) + S; double fy = yr > e ? SMath.Pow(yr, OneThird) : (k * yr) + S; double fz = zr > e ? SMath.Pow(zr, OneThird) : (k * zr) + S; *(pixelsDataP + i + 0) = 116.0 * fy - 16.0; *(pixelsDataP + i + 1) = 500.0 * (fx - fy); *(pixelsDataP + i + 2) = 200.0 * (fy - fz); } } }); }
/// <summary> /// Converts Bitmap to the ZsImage in ARGB format. /// </summary> /// <param name="bitmap">The bitmap.</param> /// <returns></returns> public static unsafe ZsImage ToArgbImage(this Bitmap bitmap) { var width = bitmap.Width; var height = bitmap.Height; var components = new double[4 * width * height]; const double N = 1.0 / 255.0; BitmapData bd = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); fixed(double *componentsP = components) { try { byte *curpos = (byte *)bd.Scan0; //TODO: invert and paralelize for (int i = 0; i < components.Length; i += 4) { // components should be in the range [0.0 , 1.0] // but we currently have them in the [0, 255] range double B = (*(curpos++)) * N; double G = (*(curpos++)) * N; double R = (*(curpos++)) * N; double A = (*(curpos++)) * N; if (A < 0) { A = 0; } else if (A > 1) { A = 1; } if (R < 0) { R = 0; } else if (R > 1) { R = 1; } if (G < 0) { G = 0; } else if (G > 1) { G = 1; } if (B < 0) { B = 0; } else if (B > 1) { B = 1; } *(componentsP + i + 0) = A; *(componentsP + i + 1) = R; *(componentsP + i + 2) = G; *(componentsP + i + 3) = B; } } finally { bitmap.UnlockBits(bd); } } var result = new ZsImage(components, width, height, 4); return(result); }
private static unsafe void LabToRgb(ZsImage labImage) { //LabToXyz(ref labImage); if (labImage == null) { throw new ArgumentNullException(); } double[] pixelsData = labImage.PixelsData; const int NotDividableMinAmountElements = 80; const double Xr = 95.047; const double Yr = 100.000; const double Zr = 108.883; const double K1 = 1.0 / 116.0; const double K2 = 1.0 / 500.0; const double K3 = 1.0 / 200.0; const double K4 = 1.0 / k; const double W = 0.0031308; const double Xr2 = 1.0 / 100.0; const double Yr2 = 1.0 / 100.0; const double Zr2 = 1.0 / 100.0; int pointsAmount = labImage.Width * labImage.Height; // Decide on how many partitions we should divade the processing // of the elements. var partsCount = pointsAmount > NotDividableMinAmountElements ? Environment.ProcessorCount : 1; var partSize = (int)(pointsAmount / partsCount); Parallel.For(0, partsCount, partIndex => { var firstPointIndex = partIndex * partSize; var lastPointIndex = firstPointIndex + partSize - 1; if (partIndex == partsCount - 1) { lastPointIndex = pointsAmount - 1; } if (lastPointIndex > pointsAmount) { lastPointIndex = pointsAmount - 1; } fixed(double *pixelsDataP = pixelsData) { for (int pointIndex = lastPointIndex; pointIndex >= firstPointIndex; pointIndex--) { // Step 1. Inverse Companding int i = pointIndex * 3; double L = *(pixelsDataP + i + 0); double fy = (L + 16.0) * K1; double fx = (*(pixelsDataP + i + 1) * K2) + fy; double fz = fy - (*(pixelsDataP + i + 2) * K3); var yr = fy * fy * fy; if (yr <= e) { yr = (fy - S) * K4; } var xr = fx * fx * fx; if (xr <= e) { xr = (fx - S) * K4; } var zr = fz * fz * fz; if (zr <= e) { zr = (fz - S) * K4; } double X = xr * Xr * Xr2; double Y = yr * Yr * Yr2; double Z = zr * Zr * Zr2; // Step 1. XYZ to Linear RGB double r = X * 3.2406 + Y * -1.5372 + Z * -0.4986; double g = X * -0.9689 + Y * 1.8758 + Z * 0.0415; double b = X * 0.0557 + Y * -0.2040 + Z * 1.0570; // Step 2. Companding // sRGB Companding *(pixelsDataP + i + 0) = r > W ? 1.055 * SMath.Pow(r, S2) - 0.055 : 12.92 * r; *(pixelsDataP + i + 1) = g > W ? 1.055 * SMath.Pow(g, S2) - 0.055 : 12.92 * g; *(pixelsDataP + i + 2) = b > W ? 1.055 * SMath.Pow(b, S2) - 0.055 : 12.92 * b; } } }); }
public static ZsImage FromArgbToRgb(this ZsImage argbImage, double[] background) { return(argbImage .MergeAlphaWithBackground(background) .RemoveComponents(0)); }
public static unsafe ZsImage RestoreImage(this Nnf nnf, ZsImage image, byte componentsCount, byte patchSize) { const int NotDividableMinAmountElements = 80; var width = nnf.DstWidth; var height = nnf.DstHeight; var nnfItems = nnf.GetNnfItems(); double destWidth = width; double destHeight = height; double sourceWidth = image.Width; double sourceHeight = image.Height; int patchOffs = (patchSize - 1) / 2; var result = new double[width * height * componentsCount]; var srcPixelsData = image.PixelsData; var pointsAmount = width * height; // Decide on how many partitions we should divade the processing // of the elements. var partsCount = pointsAmount > NotDividableMinAmountElements ? Environment.ProcessorCount : 1; var partSize = (int)(pointsAmount / partsCount); Parallel.For(0, partsCount, partIndex => { var firstPointIndex = partIndex * partSize; var lastPointIndex = firstPointIndex + partSize - 1; if (partIndex == partsCount - 1) { lastPointIndex = pointsAmount - 1; } if (lastPointIndex > pointsAmount) { lastPointIndex = pointsAmount - 1; } var color = new double[componentsCount]; fixed(double *resultP = result) fixed(double *srcPixelsP = srcPixelsData) fixed(double *colorP = color) fixed(double *nnfItemsP = nnfItems) { for (var pointIndex = firstPointIndex; pointIndex <= lastPointIndex; pointIndex++) { int count = 0; int y = pointIndex / width; int x = pointIndex % width; //go thru the patch for (int py = y - patchOffs, yi = 0; yi < patchSize; py++, yi++) { for (int px = x - patchOffs, xi = 0; xi < patchSize; px++, xi++) { if ((0 <= py && py < destHeight && 0 <= px && px < destWidth)) { var deltaX = xi - patchOffs; var deltaY = yi - patchOffs; var index = (int)*(nnfItemsP + py * width * 2 + px * 2); var sourcePixelPosX = index % nnf.SourceWidth - deltaX; var sourcePixelPosY = index / nnf.SourceWidth - deltaY; if ((0 <= sourcePixelPosY && sourcePixelPosY < sourceHeight && 0 <= sourcePixelPosX && sourcePixelPosX < sourceWidth)) { var ppos = (sourcePixelPosY * (int)sourceWidth + sourcePixelPosX) * componentsCount; for (int j = 0; j < componentsCount; j++) { *(colorP + j) += *(srcPixelsP + ppos + j); } count++; } } } } var pos = (y * width + x) * componentsCount; for (int j = 0; j < componentsCount; j++) { *(resultP + pos + j) = *(colorP + j) / count; *(colorP + j) = 0; } } } }); return(new ZsImage(result, width, height, componentsCount)); }
public static ZsImage RestoreRgbImage(this Nnf nnf, ZsImage image, byte componentsCount, byte patchSize) { var lab = nnf.RestoreImage(image, componentsCount, patchSize); return(lab.FromLabToRgb()); }
public static ZsImage FromGrayToRgb(this ZsImage grayImage) { GrayToRgb(grayImage); return(grayImage); }
public static ZsImage FromRgbToLab(this ZsImage image) { RgbToLab(image); return(image); }
/// <summary> /// Converts Bitmap into ZsImage in the RGB format. /// </summary> /// <param name="bitmap">The bitmap.</param> /// <returns></returns> public static unsafe ZsImage ToRgbImage(this Bitmap bitmap) { var width = bitmap.Width; var height = bitmap.Height; var components = new double[3 * width * height]; /* * var pixelsArea = new byte[height][]; * for (int y = 0; y < height; y++) * { * pixelsArea[y] = new byte[width]; * } * * var isSemiTransparent = false; */ const double N = 1.0 / 255.0; BitmapData bd = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); fixed(double *componentsP = components) { try { byte *curpos = (byte *)bd.Scan0; //TODO: invert and paralelize for (int i = 0; i < components.Length; i += 3) { // components should be in the range [0.0 , 1.0] // but we currently have them in the [0, 255] range double B = (*(curpos++)) * N; double G = (*(curpos++)) * N; double R = (*(curpos++)) * N; curpos++; /* * double A = (*(curpos++)) * N; * * if (A != 0) * { * pixelsArea[(i / 3) / width][(i / 3) % width] = 1; * } * else isSemiTransparent = true; */ if (R < 0) { R = 0; } else if (R > 1) { R = 1; } if (G < 0) { G = 0; } else if (G > 1) { G = 1; } if (B < 0) { B = 0; } else if (B > 1) { B = 1; } *(componentsP + i + 0) = R; *(componentsP + i + 1) = G; *(componentsP + i + 2) = B; } } finally { bitmap.UnlockBits(bd); } } //if (isSemiTransparent) //{ // var area = Area2D.Create(0, 0, pixelsArea); // result = new ImageProcessing.ZsImage(components, area, width, height, 3); //} //else var result = new ZsImage(components, width, height, 3); return(result); }
public static ZsImage PyramidDownArgb(this ZsImage argbImage, bool blur = true) { var filterArea = Area2D.Create(0, 0, argbImage.Width, argbImage.Height); return(argbImage.PyramidDownArgb(filterArea, blur)); }
/// <summary> /// Converts ZsImage in ARGB format into the Bitmap. /// </summary> /// <param name="argbImage">The ARGB image.</param> /// <returns></returns> public static unsafe Bitmap FromArgbToBitmap(this ZsImage argbImage) { var width = argbImage.Width; var height = argbImage.Height; double[] pixelsData = argbImage.PixelsData; var componentsAmount = argbImage.NumberOfComponents; Bitmap result = new Bitmap(width, height, PixelFormat.Format32bppArgb); BitmapData bd = result.LockBits(new System.Drawing.Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); fixed(double *componentsP = pixelsData) { try { byte *curpos = (byte *)bd.Scan0; for (int i = 0; i < pixelsData.Length; i += componentsAmount) { byte A = (byte)(*(componentsP + i + 0) * 255); byte R = (byte)(*(componentsP + i + 1) * 255); byte G = (byte)(*(componentsP + i + 2) * 255); byte B = (byte)(*(componentsP + i + 3) * 255); if (A < 0) { A = 0; } else if (A > 255) { A = 255; } if (R < 0) { R = 0; } else if (R > 255) { R = 255; } if (G < 0) { G = 0; } else if (G > 255) { G = 255; } if (B < 0) { B = 0; } else if (B > 255) { B = 255; } *(curpos++) = B; *(curpos++) = G; *(curpos++) = R; *(curpos++) = A; } } finally { result.UnlockBits(bd); } } return(result); }
public static ZsImage FromLabToRgb(this ZsImage image) { LabToRgb(image); return(image); }
public static ZsImage Filter(this ZsImage argbImage, double[] filter, byte filterWidth, byte filterHeight, double multiplicator = 1.0) { var area = Area2D.Create(0, 0, argbImage.Width, argbImage.Height); return(argbImage.Filter(area, filter, filterWidth, filterHeight, multiplicator)); }
/// <summary> /// Converts ZsImage in RGB format to the Bitmap image. /// </summary> /// <param name="rgbImage">The RGB image.</param> /// <returns></returns> public static unsafe Bitmap FromRgbToBitmap(this ZsImage rgbImage) { var width = rgbImage.Width; var height = rgbImage.Height; double[] pixelsData = rgbImage.PixelsData; Bitmap result = new Bitmap(width, height, PixelFormat.Format32bppArgb); BitmapData bd = result.LockBits(new System.Drawing.Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); fixed(double *pixelsDataP = pixelsData) { try { byte *curpos = (byte *)bd.Scan0; for (int i = 0; i < pixelsData.Length; i += 3) //for (int ii = 0; ii < pixelIndices.Length; ii++) { //int i = pixelIndices[ii]*3; byte A = 255; byte R = (byte)(*(pixelsDataP + i + 0) * 255); byte G = (byte)(*(pixelsDataP + i + 1) * 255); byte B = (byte)(*(pixelsDataP + i + 2) * 255); if (R < 0) { R = 0; } else if (R > 255) { R = 255; } if (G < 0) { G = 0; } else if (G > 255) { G = 255; } if (B < 0) { B = 0; } else if (B > 255) { B = 255; } *(curpos++) = B; *(curpos++) = G; *(curpos++) = R; *(curpos++) = A; } } finally { result.UnlockBits(bd); } } return(result); }
public static ZsImage FromRgbToArgb(this ZsImage rgbImage, Area2D opaqueArea) { return(rgbImage.InsertComponents(new[] { 0.0 }, 0) .SetComponentsValues(opaqueArea, new[] { 1.0 }, 0)); }