public static Bitmap[,] ExtractAll(Bitmap[,] charsIn) { Bitmap[,] toRet = new Bitmap[charsIn.GetLength(0), charsIn.GetLength(1)]; for(int i = 0; i < charsIn.GetLength(0); i++) { for(int j = 0; j < charsIn.GetLength(1); j++) { toRet[i, j] = Extract(charsIn[i, j]); } } return toRet; }
//Perform classification on a 2D array of images (returns probabilities for each possible class for each image) public double[][][] Classify(Bitmap[,] charImgs) { double[][][] toRet = new double[charImgs.GetLength(0)][][]; for (int i = 0; i < toRet.Length; i++) //Col { toRet[i] = new double[charImgs.GetLength(1)][]; for (int j = 0; j < toRet[i].Length; j++) //Row { toRet[i][j] = this.Classify(charImgs[i, j]); } } return toRet; }
private static Bitmap MergeResult(Bitmap[,] results, int sx, int sy, int n) { var ix = results.GetLength(0); var iy = results.GetLength(1); int stx = 9999; int sty = 9999; for (int x = 0; x < ix; x++) { for (int y = 0; y < iy; y++) { if (results[x, y] != null) { stx = Math.Min(x, stx); sty = Math.Min(y, sty); } } } var result = new Bitmap(n * sx, n * sy); using (var g = Graphics.FromImage(result)) { for (int x = 0; x < n; x++) { for (int y = 0; y < n; y++) { g.DrawImage(results[stx + x, sty + y], x * sx, y * sy); } } } return result; }
/// <summary> /// Takes a 2-dimensional array of tiles and stitches it into a single Bitmap for display on the Map /// </summary> /// <param name="tiles">2-dimensional array of tiles, [x by y]</param> /// <param name="opacity">Opacity of final image</param> /// <returns>Bitmap of the tiles stitched together</returns> public static Bitmap StitchTiles(Bitmap[,] tiles, short opacity) { var width = tiles.GetLength(0) * 256; var height = tiles.GetLength(1) * 256; //create a bitmap to hold the combined image var finalImage = new Bitmap(width, height); //get a graphics object from the image so we can draw on it using (var g = Graphics.FromImage(finalImage)) { //set background color g.Clear(Color.Transparent); using (var iaPic = new ImageAttributes()) { var cmxPic = new ColorMatrix {Matrix33 = opacity/100f}; iaPic.SetColorMatrix(cmxPic, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); //go through each image and "draw" it on the final image for (var y = 0; y < tiles.GetLength(1); y++) { for (var x = 0; x < tiles.GetLength(0); x++) { if (tiles[x, y] != null) { var tile = tiles[x, y]; g.DrawImage(tile, new Rectangle(x*256, y*256, tile.Width, tile.Height), 0, 0, tile.Width, tile.Height, GraphicsUnit.Pixel, iaPic); } } } } } return finalImage; }
//Takes a 2D array of Bitmaps and makes them into a single Bitmap by putting them together in a grid pattern public static Bitmap Grid(Bitmap[,] charImgs) { //Validation: Check that there is at least one image if(charImgs.Length == 0) { throw new ArgumentException("Collection \"charImgs\" must have at least one element"); } //Validation: Check that all images are in the same PixelFormat PixelFormat pixelFormat = charImgs[0, 0].PixelFormat; foreach(Bitmap charImg in charImgs) { if(charImg.PixelFormat != pixelFormat) { throw new UnexpectedPixelFormatException("All images must have the same PixelFormat"); } } //Validation: Check that all images in each column have the same width for(int i = 0; i < charImgs.GetLength(0); i++) //Cols { int colWidth = charImgs[i, 0].Width; for(int j = 1; j < charImgs.GetLength(1); j++) //Rows { if(charImgs[i, j].Width != colWidth) { throw new InvalidImageDimensionsException("All images in each column must have the same Width in order to form a grid"); } } } //Validation: Check that all images in each row have the same height for(int i = 0; i < charImgs.GetLength(1); i++) //Row { int rowHeight = charImgs[0, i].Height; for(int j = 1; j < charImgs.GetLength(0); j++) //Col { if(charImgs[j, i].Height != rowHeight) { throw new InvalidImageDimensionsException("All images in each row must have the same Height in order to form a grid"); } } } //Determine the number of bytes per pixel int bytesPerPixel = charImgs[0, 0].GetBitsPerPixel() / 8; //Calculate the total image Width & Height int imgWidth = 0; for(int i = 0; i < charImgs.GetLength(0); i++) //Cols { imgWidth += charImgs[i, 0].Width; } int imgHeight = 0; for(int i = 0; i < charImgs.GetLength(1); i++) //Rows { imgHeight += charImgs[0, i].Height; } Bitmap img = new Bitmap(imgWidth, imgHeight, pixelFormat); //Lock image for write so we can access it with pointers BitmapData imgData = img.LockBits(new Rectangle(0, 0, img.Width, img.Height), ImageLockMode.WriteOnly, img.PixelFormat); unsafe { byte* ptrImgData = (byte*)imgData.Scan0; //Keep track of how many pixels in from the left we are to the left of this col int colLeftIdx = 0; for(int col = 0; col < charImgs.GetLength(0); col++) { //Keep track of how many pixels in from the top we are to the top of this row int rowTopIdx = 0; for(int row = 0; row < charImgs.GetLength(1); row++) { //Lock this char for read so we can copy it across to the new image BitmapData charData = charImgs[col, row].LockBits(new Rectangle(0, 0, charImgs[col, row].Width, charImgs[col, row].Height), ImageLockMode.ReadOnly, pixelFormat); byte* ptrCharData = (byte*)charData.Scan0; //Loop over each pixel in this char img to be copied across for (int i = 0; i < charImgs[col, row].Width; i++) //Cols { for(int j = 0; j < charImgs[col, row].Height; j++) //Rows { int imgOffset = (((rowTopIdx) + j) * imgData.Stride) + ((colLeftIdx + i) * bytesPerPixel); int charImgOffset = (j * charData.Stride) + (i * bytesPerPixel); //Copy the bytes for this pixel for(int k = 0; k < bytesPerPixel; k++) { ptrImgData[imgOffset + k] = ptrCharData[charImgOffset + k]; } } } charImgs[col, row].UnlockBits(charData); //Update the rowLeftIdx for the next iter rowTopIdx += charImgs[col, row].Height; } //Update the colLeftIdx for the next iter colLeftIdx += charImgs[col, 0].Width; } } img.UnlockBits(imgData); return img; }
public void DisplayCommodityResults(string[,] s, Bitmap[,] originalBitmaps, float[,] originalBitmapConfidences, string[] rowIds, string screenshotName) { if (InvokeRequired) { Invoke(new DisplayCommodityResultsDelegate(DisplayCommodityResults), s, originalBitmaps, originalBitmapConfidences, rowIds, screenshotName); return; } if (_commodityTexts != null && _correctionColumn < _commodityTexts.GetLength(1)) // there is an existingClassification screenshot being processed... { _screenshotResultsBuffer.Add(new ScreeenshotResults { originalBitmapConfidences = originalBitmapConfidences, originalBitmaps = originalBitmaps, s = s, rowIds = rowIds, screenshotName = screenshotName }); ScreenshotsQueued("(" + (_screenshotResultsBuffer.Count + ocr.ScreenshotBuffer.Count + _preOcrBuffer.Count) + " queued)"); return; } if (originalBitmaps.GetLength(0) != 0) BeginCorrectingScreenshot(s, originalBitmaps, originalBitmapConfidences, rowIds, screenshotName); else tbCommoditiesOcrOutput.Text = "No rows found..."; }
public static Bitmap[,] Grid(Bitmap img, uint rows, uint cols) { //Height must be divisible by rows & width must be divisible by cols, otherwise will require interpolation and will be much slower if (img.Height % rows != 0 || img.Width % cols != 0) { throw new UnexpectedImageSizeException("Image height must be divisible by num rows and Image width must be divisible by num cols"); } //Determine the number of Bytes Per pixel in this image int bytesPerPixel = img.GetBitsPerPixel() / 8; Bitmap[,] chars = new Bitmap[cols, rows]; //Lock image for read so we can access it with pointers BitmapData imgData = img.LockBits(new Rectangle(0, 0, img.Width, img.Height), ImageLockMode.ReadOnly, img.PixelFormat); int colWidth = img.Width / (int)cols; int rowHeight = img.Height / (int)rows; unsafe { byte* ptrImgData = (byte*)imgData.Scan0; for (int col = 0; col < chars.GetLength(0); col++) { for (int row = 0; row < chars.GetLength(1); row++) { //Make a new Bitmap to hold the char Bitmap charBitmap = new Bitmap(colWidth, rowHeight, img.PixelFormat); //Lock image for write so we can write to it BitmapData charData = charBitmap.LockBits(new Rectangle(0, 0, charBitmap.Width, charBitmap.Height), ImageLockMode.WriteOnly, charBitmap.PixelFormat); byte* ptrCharData = (byte*)charData.Scan0; //Loop over each pixel in this char to be extracted for (int i = 0; i < colWidth; i++) { for(int j = 0; j < rowHeight; j++) { int imgOffset = ((row * rowHeight) + j) * imgData.Stride + (((col * colWidth) + i) * bytesPerPixel); int charOffset = (j * charData.Stride) + (i * bytesPerPixel); //Copy the bytes for this pixel for(int k = 0; k < bytesPerPixel; k++) { ptrCharData[charOffset + k] = ptrImgData[imgOffset + k]; } } } charBitmap.UnlockBits(charData); chars[col, row] = charBitmap; } } } img.UnlockBits(imgData); return chars; }
public static Bitmap[,] Segment(Bitmap img, Segmentation segmentation) { //Validation: Check that the Bitmap has the dimensions listed in the Segmentation if(img.Width != segmentation.Width || img.Height != segmentation.Height) { throw new ArgumentException("Bitmap dimensions must match Segmentation dimensions"); } //Determine the number of Bytes Per pixel in this image int bytesPerPixel = img.GetBitsPerPixel() / 8; Bitmap[,] chars = new Bitmap[segmentation.NumCols, segmentation.NumRows]; //Lock the image for read so we can access it with pointers BitmapData imgData = img.LockBits(new Rectangle(0, 0, img.Width, img.Height), ImageLockMode.ReadOnly, img.PixelFormat); unsafe { byte* ptrImageData = (byte*)imgData.Scan0; for (int col = 0; col < chars.GetLength(0); col++) { for(int row = 0; row < chars.GetLength(1); row++) { //Get the start & end indices of this char based on the segmentation points int colStart = col == 0 ? 0 : segmentation.Cols[col - 1]; //If this is the first col, it starts at zero. Otherwise where the previous col ended int colEnd = col == chars.GetLength(0) - 1 ? segmentation.Width - 1 : segmentation.Cols[col]; //If this is the last col, ends at width. Otherwise at the segmentation index int rowStart = row == 0 ? 0 : segmentation.Rows[row - 1]; //If this is the first row, it starts at zero. Otherwise where the previous row ended int rowEnd = row == chars.GetLength(1) - 1 ? segmentation.Height - 1 : segmentation.Rows[row]; //If this is the last row, ends at height. Otherwise at the segmentation index //Make a new Bitmap to hold the char Bitmap charBitmap = new Bitmap(colEnd + 1 - colStart, rowEnd + 1 - rowStart, img.PixelFormat); //Lock image for write so we can write to it BitmapData charData = charBitmap.LockBits(new Rectangle(0, 0, charBitmap.Width, charBitmap.Height), ImageLockMode.WriteOnly, charBitmap.PixelFormat); byte* ptrCharData = (byte*)charData.Scan0; //Loop over each pixel in this char to be extracted for(int pxCol = colStart; pxCol <= colEnd; pxCol++) { for(int pxRow = rowStart; pxRow <= rowEnd; pxRow++) { int imgOffset = (pxRow * imgData.Stride) + (pxCol * bytesPerPixel); int charOffset = ((pxRow - rowStart) * charData.Stride) + ((pxCol - colStart) * bytesPerPixel); //Copy the bytes for this pixel for(int i = 0; i < bytesPerPixel; i++) { ptrCharData[charOffset + i] = ptrImageData[imgOffset + i]; } } } charBitmap.UnlockBits(charData); chars[col, row] = charBitmap; } } } img.UnlockBits(imgData); return chars; }
private static string[,] Recognize(Bitmap[,] bitmaps) { Indicator.SetNcellImages(bitmaps.Length); string[,] result = new string[bitmaps.GetLength(0), bitmaps.GetLength(1)]; for (int i = 0; i < bitmaps.GetLength(0); i++) { for (int j = 0; j < bitmaps.GetLength(1); j++) { if (i == 24 & j == 4) { } result[i, j] = Recognizer.Recognize(bitmaps[i, j], 10); Indicator.IncRecognizeCellImage(); } } return result; }