PCB Polar SI9000阻抗模型图片文字识别方法

用过Polar SI9000的都知道,阻抗模型图片可以进行用户鼠标交互,那么它的是如何实现的呢,下面就讲一下如何实现此功能的方法

  一.看看Polar SI9000阻抗模型图片交互效果

鼠标点击阻抗模型图片某个像素点, 它可以实现找到离它最近的阻抗参数的文字并用红色框选出来, 并且可以识别文字是哪一个阻抗参数.

 二.解决方法思路

解决方法一:

1.将每一种阻抗模型图片中的所有参数在图片中的位置区域信息与参数值记录到数据库中

2.鼠标点击阻抗模型的坐标位置后,再进与数据库中的参数坐标位置匹配

这样就可以实现与Polar阻抗软件相同的效果,但是Polar SI9000有阻抗计算模型93种,要实现的话工作量可不小,所以这种方法排除了。

解决方法二(采用此方法实现):

1.找最近邻----点击像素点位置,找出离它最近的一个黑色像素点位置

2.聚类----通过一个像素点查找周边相邻的黑色像素点进行聚类

3.识别---截取指定区域文字图片与图像Ocr识别

 三.找最近邻----点击像素点位置,找出离它最近的一个黑色像素点位置

1.【圈】的遍历方式按下图方式进行

以鼠标点击像素的位置,向像素四周搜索黑色像素点,依次遍历第1圈,第2圈,第3圈.....直到找到黑色像素则终止

2.【段】的遍历方式按下图方式进行

3.C#代码实现,鼠标点击像素点位置,找出离它最近的黑色像素点

        /// <summary>
        /// 通过鼠标点击像素点位置,找出离它最近的一个黑色像素点位置
        /// </summary>
        /// <param name="MousePoint"></param>
        /// <param name="ArrayBitmap"></param>
        /// <returns></returns>
        private Point ArrayLoop(Point MousePoint, Bitmap ArrayBitmap)
        {
            Point ClacBlackPoint = new Point();
            Color pixel = ArrayBitmap.GetPixel(MousePoint.X, MousePoint.Y);
            if (pixel.R <= 25 && pixel.G <= 40 && pixel.B <= 60)
            {
                return MousePoint;
            }
            Point ArraySum = new Point(ArrayBitmap.Size);
            int[,] ArrayLoopType = new int[,] { { 1, 1 }, { -1, 1 }, { -1, -1 }, { 1, -1 } }; //偏移位移矩阵数组
            int LoopLength = getArrayLoopMax(MousePoint, ArraySum);//遍历的圈数计算
            int ArayLength = ArrayLoopType.GetLength(0);//计算值为4
            for (int k = 1; k <= LoopLength; k++) //按圈遍历
            {
                Point LoopPoint = MousePoint;
                LoopPoint.Offset(0, -k);//更新圈的起点像素坐标
                for (int i = 0; i < ArayLength; i++)//每圈分为4段遍历
                {
                    for (int j = 0; j < k; j++)
                    {
                        LoopPoint.X += ArrayLoopType[i, 0];
                        LoopPoint.Y += ArrayLoopType[i, 1];
                        if (LoopPoint.X > 0 && LoopPoint.Y > 0 && LoopPoint.X <= ArraySum.X && LoopPoint.Y <= ArraySum.Y)//
                        {
                            pixel = ArrayBitmap.GetPixel(LoopPoint.X - 1, LoopPoint.Y - 1);
                            if (pixel.R <= 25 && pixel.G <= 40 && pixel.B <= 60)
                            {
                                ClacBlackPoint = LoopPoint;
                                goto L1;
                            }
                        }
                    }
                }
            }
            L1:
            return ClacBlackPoint;
        }
        /// <summary>
        /// 获取遍历圈数最大值
        /// </summary>
        /// <param name="MousePoint"></param>
        /// <param name="ArraySum"></param>
        /// <param name="LoopType"></param>
        /// <returns></returns>
        private int getArrayLoopMax(Point MousePoint, Point ArraySum, int LoopType = 1)
        {
            int LoopLength = 0;
            if (LoopType == 1)
            {
                int TopLeft = (MousePoint.X - 1 + MousePoint.Y - 1);
                int TopRight = (ArraySum.X - MousePoint.X + MousePoint.Y - 1);
                int TopMax = Math.Max(TopLeft, TopRight);
                int BootomLeft = (MousePoint.X - 1 + ArraySum.Y - MousePoint.Y);
                int BottomRight = (ArraySum.X - MousePoint.X + ArraySum.Y - MousePoint.Y);
                int BottomMax = Math.Max(BootomLeft, BottomRight);
                LoopLength = Math.Max(TopMax, BottomMax);
            }
            else
            {
                int MaxX = Math.Max(MousePoint.X - 1, ArraySum.X - MousePoint.X);
                int MaxY = Math.Max(MousePoint.Y - 1, ArraySum.Y - MousePoint.Y);
                LoopLength = Math.Max(MaxX, MaxY);
            }
            return LoopLength;
        }

  四.聚类----通过一个像素点查找周边相邻的黑色像素点进行聚类

1.聚类实现方法按下图进行

2.C#代码实现,通过一个像素点查找周边相邻的黑色像素点进行聚类为一个矩形区域

        /// <summary>
        /// 通过一个像素点查找周边相邻的黑色像素点进行聚类为一个矩形区域
        /// </summary>
        /// <param name="CalcPoint"></param>
        /// <param name="ArrayBitmap"></param>
        /// <returns></returns>
        private RangePoint RangeArea(Point CalcPoint, Bitmap ArrayBitmap)
        {
            int LoopLength = 10; //搜索周边相邻像素个数
            int[,] ArrayLoopType = new int[,] { { 1, 1 }, { -1, 1 }, { -1, -1 }, { 1, -1 } };
            Point ArraySum = new Point(ArrayBitmap.Size);
            RangePoint RangePointArea = new RangePoint(CalcPoint, CalcPoint);
            HashSet<Point> PointSet = new HashSet<Point>();
            HashSet<Point> LoopPointSet = new HashSet<Point>();
            Queue<Point> PointQueue = new Queue<Point>();
            PointQueue.Enqueue(CalcPoint);
            while (PointQueue.Count > 0)
            {
                var TopPoint = PointQueue.Dequeue();  //TopPoint 以这个点周边范围进行搜索像素
                for (int k = 1; k <= LoopLength; k++)
                {
                    Point LoopPoint = TopPoint;
                    LoopPoint.Offset(0, -k);
                    for (int i = 0; i < 4; i++)
                    {
                        for (int j = 0; j < k; j++)
                        {
                            LoopPoint.X += ArrayLoopType[i, 0];
                            LoopPoint.Y += ArrayLoopType[i, 1];
                            if (!LoopPointSet.Contains(LoopPoint))
                            {
                                LoopPointSet.Add(LoopPoint);
                                if (LoopPoint.X > 0 && LoopPoint.Y > 0 && LoopPoint.X <= ArraySum.X && LoopPoint.Y <= ArraySum.Y)
                                {
                                    Color pixel = ArrayBitmap.GetPixel(LoopPoint.X - 1, LoopPoint.Y - 1);
                                    if (pixel.R <= 25 && pixel.G <= 40 && pixel.B <= 60)
                                    {
                                        if (!PointSet.Contains(LoopPoint))
                                        {
                                            //找到相似的黑色像素加入队列
                                            PointQueue.Enqueue(LoopPoint);
                                            //将周边相似相素 进行扩大合并区域
                                            RangePointArea = RangePointArea.Union(LoopPoint);
                                            //加入字典
                                            PointSet.Add(TopPoint);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return RangePointArea;
        }

RangePoint  Mod类

    /// <summary>
    /// 范围区域点
    /// </summary>
    public class RangePoint
    {
        public RangePoint(Point MinPoint, Point MaxPoint)
        {
            RangeMinPoint = MinPoint;
            RangeMaxPoint = MaxPoint;
        }
        /// <summary>
        /// 最小点
        /// </summary>
        public Point RangeMinPoint { get; set; }
        /// <summary>
        /// 最大点
        /// </summary>
        public Point RangeMaxPoint { get; set; }
        /// <summary>
        /// 范围宽
        /// </summary>
        public int Width
        {
            get {  return this.RangeMaxPoint.X - this.RangeMinPoint.X + 1; }
        }
        /// <summary>
        /// 范围高
        /// </summary>
        public int Height
        {
            get { return this.RangeMaxPoint.Y - this.RangeMinPoint.Y + 1; }
        }
        /// <summary>
        /// 合拼区域
        /// </summary>
        /// <param name="point"></param>
        /// <returns></returns>
        public RangePoint Union(Point point)
        {
            Point minP = RangeMinPoint;
            Point MaxP = RangeMaxPoint;
            if (point.X < minP.X)
                minP.X = point.X;
            if (point.Y < minP.Y)
                minP.Y = point.Y;
            if (point.X > MaxP.X)
                MaxP.X = point.X;
            if (point.Y > MaxP.Y)
                MaxP.Y = point.Y;
            RangeMinPoint = minP;
            RangeMaxPoint = MaxP;
            return this;
        }
        /// <summary>
        /// 检测点是否在区域内
        /// </summary>
        /// <param name="point"></param>
        /// <returns></returns>
        public bool IsRangeInner(Point point)
        {
            return (RangeMinPoint.X <= point.X && RangeMinPoint.Y <= point.Y && RangeMaxPoint.X >= point.X && RangeMaxPoint.Y >= point.Y);
        }
        /// <summary>
        /// 获得区域中心点
        /// </summary>
        /// <param name="point"></param>
        /// <returns></returns>
        public Point getRangeCenterPoint()
        {
            return new Point((int)((this.RangeMinPoint.X + this.RangeMaxPoint.X) * 0.5), (int)((this.RangeMinPoint.Y + this.RangeMaxPoint.Y) * 0.5));
        }
        /// <summary>
        /// 区域偏移 扩大缩小
        /// </summary>
        /// <param name="point"></param>
        /// <returns></returns>
        public RangePoint RangeOffset(int OffsetVal)
        {
            this.RangeMinPoint = new Point(this.RangeMinPoint.X - OffsetVal, this.RangeMinPoint.Y - OffsetVal);
            this.RangeMaxPoint = new Point(this.RangeMaxPoint.X + OffsetVal, this.RangeMaxPoint.Y + OffsetVal);
            return this;
        }
    }

  五.识别---截取指定区域文字图片与图像识别

1.通过聚类识别出文本区域坐标进行图像截取,并将截取出来的图像进行图像识别转文字.

2.C#代码实现,截取指定区域文字图片与图像识别

此图像识别用Baidu它们家的Ocr API自己注册一下就能用了,另外一个Tesseract也不错的,可以自行对Ocr字体模型训练,最主要是可以实现本地不联网的情况下也可以Ocr识别

        /// <summary>
        /// 获取图片指定部分
        /// </summary>
        /// <param name="pPath">图片路径</param>
        /// <param name="pOrigStartPointX">原始图片开始截取处的坐标X值</param>
        /// <param name="pOrigStartPointY">原始图片开始截取处的坐标Y值</param>
        /// <param name="pPartWidth">目标图片的宽度</param>
        /// <param name="pPartHeight">目标图片的高度</param>
        static System.Drawing.Bitmap GetPart(Image originalImg, int pOrigStartPointX, int pOrigStartPointY, int pPartWidth, int pPartHeight)
        {
            System.Drawing.Bitmap partImg = new System.Drawing.Bitmap(pPartWidth, pPartHeight);
            System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(partImg);
            System.Drawing.Rectangle destRect = new System.Drawing.Rectangle(new System.Drawing.Point(0, 0), new System.Drawing.Size(pPartWidth, pPartHeight));//目标位置
            System.Drawing.Rectangle origRect = new System.Drawing.Rectangle(new System.Drawing.Point(pOrigStartPointX, pOrigStartPointY), new System.Drawing.Size(pPartWidth, pPartHeight));//原图位置(默认从原图中截取的图片大小等于目标图片的大小)
            graphics.DrawImage(originalImg, destRect, origRect, System.Drawing.GraphicsUnit.Pixel);
            return partImg;
        }
       /// <summary>
        /// Baidu Ocr识别
        /// </summary>
        /// <param name="img"></param>
        /// <returns></returns>
        private string OcrGeneralBasic(Image img)
        {
            StringBuilder OcrTxt = new StringBuilder();
            string baiduAPI_ID = "baiduAPI_ID";
            string baiduAPI_key = "baiduAPI_key";
            Baidu.Aip.Ocr.Ocr OcrClient = new Baidu.Aip.Ocr.Ocr(baiduAPI_ID, baiduAPI_key);
            var byteImg = Img2Byte(img);
            var OcrResult = OcrClient.GeneralBasic(byteImg);
            var words_result = OcrResult["words_result"];
            if (words_result == null) return "";
            foreach (var item in words_result)
            {
                OcrTxt.AppendLine(item["words"].ToString());
            }
            return OcrTxt.ToString();
        }
        /// <summary>
        /// 将Image转换成为byte[]
        /// </summary>
        /// <param name="img"></param>
        /// <returns></returns>
        public byte[] Img2Byte(System.Drawing.Image img)
        {
            MemoryStream mstream = new MemoryStream();
            img.Save(mstream, System.Drawing.Imaging.ImageFormat.Bmp);
            byte[] byData = new Byte[mstream.Length];
            mstream.Position = 0;
            mstream.Read(byData, 0, byData.Length); mstream.Close();
            return byData;
        }

  六.实现效果图

  七.其它问题解决方法

1.PictureBox控件显示图片尺寸与实际图片尺寸不一致,会造成PictureBox控件上的鼠标点击像素点位置,并不是实际图片像素点位置,这里给出2种解决方法

方法一.在读入Bitmap图片前提前转换(缩放)图片尺寸和PictureBox控件尺寸一致

        /// <summary>
        /// 图片缩放
        /// </summary>
        /// <param name="bmp"></param>
        /// <param name="newW"></param>
        /// <param name="newH"></param>
        /// <returns></returns>
        public static Bitmap KiResizeImage(Bitmap bmp, int newW, int newH)
        {
            try
            {
                Bitmap newBitmap = new Bitmap(newW, newH);
                Graphics g = Graphics.FromImage(newBitmap);
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g.DrawImage(bmp, new Rectangle(0, 0, newW, newH), new Rectangle(0, 0, bmp.Width, bmp.Height), GraphicsUnit.Pixel);
                g.Dispose();
                return newBitmap;
            }
            catch
            {
                return null;
            }
        }

方法二.计算PictureBox图像大小与真实图像大小的比值关系,通过鼠标点击像素位置与屏幕位置的关系,计算得鼠标真实点击的图像像素位置

        /// <summary>
        /// 鼠标移动  查看鼠标位置与实际图片和显示图片关系
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void picBox_MouseMove(object sender, MouseEventArgs e)
        {
            PictureBox  picBox = (PictureBox)sender;
            int originalWidth = picBox.Image.Width;
            int originalHeight = picBox.Image.Height;
            PropertyInfo rectangleProperty = picBox.GetType().GetProperty("ImageRectangle", BindingFlags.Instance | BindingFlags.NonPublic);
            Rectangle rectangle = (Rectangle)rectangleProperty.GetValue(picBox, null);
            int currentWidth = rectangle.Width;
            int currentHeight = rectangle.Height;
            double rate = (double)currentHeight / (double)originalHeight;
            int black_left_width = (currentWidth == picBox.Width) ? 0 : (picBox.Width - currentWidth) / 2;
            int black_top_height = (currentHeight == picBox.Height) ? 0 : (picBox.Height - currentHeight) / 2;
            int zoom_x = e.X - black_left_width;
            int zoom_y = e.Y - black_top_height;
            double original_x = (double)zoom_x / rate;
            double original_y = (double)zoom_y / rate;
            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("原始尺寸{0}/{1}(宽/高)\r\n", originalWidth, originalHeight);
            sb.AppendFormat("缩放状态图片尺寸{0}/{1}(宽/高)\r\n", currentWidth, currentHeight);
            sb.AppendFormat("缩放比率{0}\r\n", rate);
            sb.AppendFormat("左留白宽度{0}\r\n", black_left_width);
            sb.AppendFormat("上留白高度{0}\r\n", black_top_height);
            sb.AppendFormat("当前鼠标坐标{0}/{1}(X/Y)\r\n", e.X, e.Y);
            sb.AppendFormat("缩放图中鼠标坐标{0}/{1}(X/Y)\r\n", zoom_x, zoom_y);
            sb.AppendFormat("原始图中鼠标坐标{0}/{1}(X/Y)\r\n", original_x, original_y);
            string InfoTxt = sb.ToString();
        }

原文地址:https://www.cnblogs.com/pcbren/p/10346445.html

时间: 2024-11-05 16:31:51

PCB Polar SI9000阻抗模型图片文字识别方法的相关文章

职场专业图片文字识别的方法,你知道吗

在职场中又一个专业的图片文字识别方法,工作不是经常整理图片文字的员工不知道,那就是使用一下专业的OCR文字识别软件,在加上专业的操作方法,就可以快速的把图片上的文字识别出来了.在平时生活中实现图片文字识别的方法不是很好用,而且操作步骤很繁琐,下面小编就分享一个专业的图片文字识别方法.工具和原料:1:带有文字的图片:2:OCR文字识别工具.操作方法:第一步:[打开OCR软件]:在电脑上打开文字识别软件,大家可以通过浏览器搜索关键词"迅捷OCR文字识别软件"找到OCR软件.第二步:[极速识

斯坦福第十八课:应用实例:图片文字识别(Application Example: Photo OCR)

18.1  问题描述和流程图 18.2  滑动窗口 18.3  获取大量数据和人工数据 18.4  上限分析:哪部分管道的接下去做 18.1  问题描述和流程图 图像文字识别应用所作的事是,从一张给定的图片中识别文字.这比从一份扫描文档中 识别文字要复杂的多. 为了完成这样的工作,需要采取如下步骤: 为了完成这样的工作,需要采取如下步骤: 1. 文字侦测(Text detection)——将图片上的文字与其他环境对象分离开来 2. 字符切分(Character segmentation)——将文

[C13]应用实例:图片文字识别(待整理)

十八.应用实例:图片文字识别(Application Example: Photo OCR) 18.1 问题描述和流程图 参考视频: 18 - 1 - Problem Description and Pipeline (7 min).mkv 图像文字识别应用所作的事是,从一张给定的图片中识别文字.这比从一份扫描文档中识别文字要复杂的多. 为了完成这样的工作,需要采取如下步骤: 文字侦测(Text detection)--将图片上的文字与其他环境对象分离开来 字符切分(Character segm

手机图片转换文字识别方法

手机图片转换文字识别方法 iPhone6这款设计图出自设计师卡萨巴-纳吉之手,而在他眼中的iPhone6应该朝着透明的方向靠拢.因而,他将该设备打造成了一款极薄.透明,且内置有可互动玻璃外观的"神机".据悉,设计图中的iPhone6拥有一个内置有LED灯的HOME键,只有在用户按下时才会亮起.而且,该手机还具备有全息投影功能,可以将手机画面投射到一块相对更宽的背景中.最炫酷的就是拍照技术,FaceTime 摄像头提供与 iSight 摄像头相同的曝光控制功能,想要调节照片或视频的明暗,

『方案』《女友十年精华》 ORC 图片 文字识别 详解

目的需求: 2008年,遇到一本电子书 <女友十年精华> 觉得很美,想 私藏 这些文章: >网络搜索文章 —— 没有找到: >反编译程序 —— 所有文字 都是图片格式(部分文章的 非规律乱码 即为证明,且试用  Adobe Director 反编译 确是图片无疑) >总计 310篇文章 —— 如何降低 工作复杂度 得到 文本格式的文章? 最后方案: >写区域截屏软件,将一篇文章 截成多图 (图片文字行 有重复): >过滤 文章多图 的背景图片(背景图片 会干扰 O

Python人工智能之图片识别,Python3一行代码实现图片文字识别

1.Python人工智能之图片识别,Python3一行代码实现图片文字识别 2.tesseract-ocr安装包和中文语言包 注意: 原文地址:https://www.cnblogs.com/jycjy/p/8799295.html

PDF图片文字识别的实现方法

怎么识别PDF图片中的文字呢?相信很多人都在为这个问题而困扰吧.那么,下面我就来给大家讲解一下如何实现PDF图片文字识别吧. 步骤一:打开电脑浏览器,下载并运行捷速OCR文字识别软件. 步骤二:打开捷速0CR文字识别软件,点击退出按钮,退出该选项. 步骤三:点击软件正上方"高级识别"按钮. 步骤四:随后选择软件左上方"添加"按钮,将自己需要编辑的PDF文件添加进来. 步骤五:文件添加后点击软件上方的"内容解析"按钮,那么软件就会自动对文件进行内容

用图片文字识别软件 复制微信小助手的开票信息

微信目前有开票小助手的功能,可以保存开票信息,客户经常会发微信开票小助手里的截图,附带有个二维码,这边可以扫描二维码获取抬头,虽然听说有用二维码极速开票的,对于这个不清楚,也不打算了解,本人还是用的传统方式,开票信息也不算多,最多也就四条.刚开始的时候,如果客户发这种图,我会直接对照着手打,因为数据不是很多,如果不是很忙,没有其他事情,下单的时候还没给快递打电话,手打之后在一个个对照一下,确认后打出来,再对照一下,也没什么问题.后来,客户由于有时候下午下单,时间有时候比较晚,已经给顺丰打电话了,

如何简单的实现图片文字识别

不知道有没有人和小编一样,经常需要文字识别,那这个时候有什么简单的方法可以帮助解决这个问题呢? 辅助工具:电脑 迅捷OCR文字识别软件 实用系数:☆☆☆☆☆ 推荐理由:该软件是一款智能化的OCR图片文字识别软件,支持PDF识别.扫描件识别.图片文字识别.CAJ识别.票证识别.图片局部识别等功能,快速解析.精准识别. 操作步骤: 1:将电脑中的文字识别软件打开,在上方导航栏选择图片局部识别板块. 2:接着点击添加文件按钮将所需识别的图片添加进来. 3:在界面左下角这里更改一下文件的保存位置,方便识