public OneRowCol(int RowNum, int ColNum, RowColRelative RowColRelative = RowColRelative.Parent, CharPoint ContentStart = null) : base(RowNum, ColNum, LocationFrame.OneBased, new ScreenDim(24, 80), RowColRelative, ContentStart) { }
protected RowColBase( int RowNum, int ColNum, LocationFrame LocationFrame, RowColRelative RowColRelative, CharPoint ContentStart) : this(RowNum, ColNum, LocationFrame, new ScreenDim(24, 80), RowColRelative, ContentStart) { }
public ZeroRowCol( int RowNum, int ColNum, ScreenDim Dim, RowColRelative RowColRelative = RowColRelative.Parent, CharPoint ContentStart = null) : base(RowNum, ColNum, LocationFrame.ZeroBased, Dim, RowColRelative, ContentStart) { }
/// <summary> /// convert the dot based position to a character based location. /// </summary> /// <param name="Pos"></param> /// <param name="CharDim"></param> /// <returns></returns> public static IRowCol CanvasPosToRowCol( this Point Pos, Size CharDim, CharPoint ContentStart) { double x = Pos.X / CharDim.Width; double y = Pos.Y / CharDim.Height; int colNum = (int)x; int rowNum = (int)y; if (ContentStart == null) { return(new ZeroRowCol(rowNum, colNum)); } else { return(new ZeroRowCol( rowNum, colNum, RowColRelative.Local, ContentStart)); } }
protected RowColBase( int RowNum, int ColNum, LocationFrame LocationFrame, ScreenDim Dim, RowColRelative RowColRelative, CharPoint ContentStart) { this.RowNum = RowNum; this.ColNum = ColNum; this.Dim = Dim; this.LocationFrame = LocationFrame; this.RowColRelative = RowColRelative; this.ContentStart = ContentStart; if (LocationFrame == LocationFrame.OneBased) { this.HorzBounds = new IntPair(1, this.Dim.Width); this.VertBounds = new IntPair(1, this.Dim.Height); } else { this.HorzBounds = new IntPair(0, this.Dim.Width - 1); this.VertBounds = new IntPair(0, this.Dim.Height - 1); } }
float CharInfoCompare_3x3_Weight(CharInfo charInfo, CharInfo target, CharPoint item, bool add = true) { CharPoint itemTarget = target.Points.FindPoint(item.X, item.Y); if (itemTarget != null)//中 { return(add ? _weight3x3[4] : 0F); } float result = 0F; for (int i = 0; i < _weight3x3_finds.Length; i++) { if (i == 4) { continue; } int[] pos = _weight3x3_finds[i]; CharPoint item1 = charInfo.Points.FindPoint(item.X + pos[0], item.Y + pos[1]); CharPoint itemTarget1 = target.Points.FindPoint(item.X + pos[0], item.Y + pos[1]); if (item1 != null && itemTarget1 != null) { if (result < _weight3x3[i]) { result = _weight3x3[i]; } } } if (add) { return(result); } else { return(result > 0F ? 0F : 0.2F); } }
/// <summary> /// 矩阵旋转 /// </summary> public void TiltCorrect() { if (Points.Count == 0) { return; } int minX = LinqHelper.Min(Points, p1 => p1.X); int minY = LinqHelper.Min(Points, p1 => p1.Y); CharPoint leftPoint = LinqHelper.FirstOrDefault(LinqHelper.OrderBy(LinqHelper.Where(Points, p1 => p1.X == minX), p1 => p1.Y)); CharPoint topPoint = LinqHelper.FirstOrDefault(LinqHelper.ThenByDescending(LinqHelper.OrderBy(Points, p1 => p1.Y), p1 => p1.X)); if (leftPoint.Y == topPoint.Y || leftPoint.X == topPoint.X) { return; } System.Drawing.Point centerPoint = new System.Drawing.Point(leftPoint.X, leftPoint.Y); double l = System.Drawing.PointHelper.Distance(leftPoint.X, leftPoint.Y, topPoint.X, topPoint.Y); double angle; if (leftPoint.Y < topPoint.Y) { //顺时针旋转 int x = leftPoint.X + (int)l; int y = leftPoint.Y; angle = -System.Drawing.PointHelper.ClipAngle( centerPoint, new System.Drawing.Point(topPoint.X, topPoint.Y), new System.Drawing.Point(x, y)); } else { //逆时针旋转 //int x = leftPoint.X + (int)l; //int y = leftPoint.Y; //angle = Symbol.Drawing.BitmapHelper.Angle_3Point( // centerPoint, // new System.Drawing.Point(x, y), // new System.Drawing.Point(topPoint.X, topPoint.Y)); return; } foreach (CharPoint item in Points) { if (item == leftPoint) { continue; } System.Drawing.Point pointX = System.Drawing.PointHelper.Rotate2(centerPoint, new System.Drawing.Point(item.X, item.Y), angle); item.X = pointX.X; item.Y = pointX.Y; } CharPoint leftPoint2 = LinqHelper.FirstOrDefault(LinqHelper.ThenBy(LinqHelper.OrderBy(Points, p1 => p1.X), p1 => p1.Y)); CharPoint topPoint2 = LinqHelper.FirstOrDefault(LinqHelper.ThenByDescending(LinqHelper.OrderBy(Points, p1 => p1.Y), p1 => p1.X)); int offsetX = 0; if (leftPoint2.X < 0) { offsetX = System.Math.Abs(leftPoint2.X); } int offsetY = 0; if (topPoint2.Y < 0) { offsetY = System.Math.Abs(topPoint2.Y); } if (offsetX == 0 && offsetY == 0) { return; } foreach (CharPoint item in Points) { item.X += offsetX; item.Y += offsetY; } }
/// <summary> /// 执行处理 /// </summary> /// <param name="image">需要处理的图像。</param> /// <param name="library">字库设置</param> /// <returns>返回提取的字符列表,若字库中有数据,会有识别结果。</returns> public unsafe System.Collections.Generic.List <CharInfo> Execute(System.Drawing.Bitmap image, CharLibrary library) { int width = image.Width; int height = image.Height; byte emptyColorR = library.EmptyColorR; int charMaxWidth = library.CharMaxWidth; int charWidth = library.CharWidth; int charHeight = library.CharHeight; bool needCenterMiddle = library.NeedCenterMiddle; float zool = library.Zool; if (zool != 1.0F && zool > 0F) { charWidth = (int)(charWidth * zool); charHeight = (int)(charHeight * zool); charMaxWidth = (int)(charMaxWidth * zool); } System.Collections.Generic.List <CharInfo> result = new System.Collections.Generic.List <CharInfo>(); CharInfo currentChar = null; //对图像进行加锁 System.Drawing.Imaging.BitmapData originalData = null; try { originalData = image.LockBits(new System.Drawing.Rectangle(0, 0, width, height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb); byte *originalDataScanX = (byte *)originalData.Scan0; //这行代码需要unsafe byte *originalDataScan0 = originalDataScanX; //这行代码需要unsafe int offset = originalData.Stride - width * 3; int currentCharWidth = 0; //横向扫描 for (int x = 0; x < width; x++) { bool spaceY = true; //纵向扫描 for (int y = 0; y < height; y++) { originalDataScan0 = originalDataScanX + x * 3 + y * width * 3 + y * offset; if (originalDataScan0[0] == emptyColorR) { continue; } spaceY = false; CharPoint charPoint = new CharPoint() { OriginalX = x, OriginalY = y, R = originalDataScan0[0], G = originalDataScan0[1], B = originalDataScan0[2], }; if (currentChar == null) { currentChar = new CharInfo(); result.Add(currentChar); } currentChar.Points.Add(charPoint); } if (!spaceY) { currentCharWidth++; if (currentCharWidth == charMaxWidth) { spaceY = true;//超出了,就结束吧 } } if (spaceY && currentChar != null) { if (currentChar.Points.Count < 8) { result.Remove(currentChar); } else { currentChar.Points.YZeroOffset(); currentChar.Points.XZeroOffset(); currentChar.TiltCorrect(); if (needCenterMiddle) { currentChar.CenterMiddle(charWidth, charHeight); } //char? c = library.CharRecognition(currentChar); } currentChar = null; currentCharWidth = 0; } } } finally { if (originalData != null) { image.UnlockBits(originalData); } //image.Dispose(); //image = null; } return(result); }
// --- Application Methods --- #region DrawLetter(CharPoint[] letter) /// <summary> /// <para> /// Interprets the instructions from the array for that letter and renders /// the letter with line segments. /// </para> /// </summary> private static void DrawLetter(CharPoint[] letter) { int i = 0; Gl.glBegin(Gl.GL_LINE_STRIP); while(i < letter.Length) { switch(letter[i].Type) { case PT: Gl.glVertex2f(letter[i].X, letter[i].Y); break; case STROKE: Gl.glVertex2f(letter[i].X, letter[i].Y); Gl.glEnd(); Gl.glBegin(Gl.GL_LINE_STRIP); break; case END: Gl.glVertex2f(letter[i].X, letter[i].Y); Gl.glEnd(); Gl.glTranslatef(8.0f, 0.0f, 0.0f); return; } i++; } }
public DisplayLocation(CharPoint InCharLoc) { mRow = InCharLoc.Y + 1; mColumn = InCharLoc.X + 1; }