zoukankan      html  css  js  c++  java
  • c#实现识别图片上的验证码数字

    这篇文章主要介绍了c#实现识别图片上的验证码数字的方法,本文给大家汇总了2种方法,有需要的小伙伴可以参考下。

    public void imgdo(Bitmap img)
        {
          //去色
          Bitmap btp = img;
          Color c = new Color();
          int rr, gg, bb;
          for (int i = 0; i < btp.Width; i++)
          {
            for (int j = 0; j < btp.Height; j++)
            {
              //取图片当前的像素点
              c = btp.GetPixel(i, j);
              rr = c.R; gg = c.G; bb = c.B;
              //改变颜色
              if (rr == 102 && gg == 0 && bb == 0)
              {
                //重新设置当前的像素点
                btp.SetPixel(i, j, Color.FromArgb(255, 255, 255, 255));
              }
              if (rr == 153 && gg == 0 && bb == 0)
              {
                //重新设置当前的像素点
                btp.SetPixel(i, j, Color.FromArgb(255, 255, 255, 255));
              } if (rr == 153 && gg == 0 && bb == 51)
              {
                //重新设置当前的像素点
                btp.SetPixel(i, j, Color.FromArgb(255, 255, 255, 255));
              } if (rr == 153 && gg == 43 && bb == 51)
              {
                //重新设置当前的像素点
                btp.SetPixel(i, j, Color.FromArgb(255, 255, 255, 255));
              }
              if (rr == 255 && gg == 255 && bb == 0)
              {
                //重新设置当前的像素点
                btp.SetPixel(i, j, Color.FromArgb(255, 255, 255, 255));
              }
              if (rr == 255 && gg == 255 && bb == 51)
              {
                //重新设置当前的像素点
                btp.SetPixel(i, j, Color.FromArgb(255, 255, 255, 255));
              }
            }
          }
          btp.Save("d:\去除相关颜色.png");
     
          pictureBox2.Image = Image.FromFile("d:\去除相关颜色.png");
     
     
          //灰度
          Bitmap bmphd = btp;
          for (int i = 0; i < bmphd.Width; i++)
          {
            for (int j = 0; j < bmphd.Height; j++)
            {
              //取图片当前的像素点
              var color = bmphd.GetPixel(i, j);
     
              var gray = (int)(color.R * 0.001 + color.G * 0.700 + color.B * 0.250);
     
              //重新设置当前的像素点
              bmphd.SetPixel(i, j, Color.FromArgb(gray, gray, gray));
            }
          }
          bmphd.Save("d:\灰度.png");
          pictureBox27.Image = Image.FromFile("d:\灰度.png");
     
     
          //二值化
          Bitmap erzhi = bmphd;
          Bitmap orcbmp;
          int nn = 3;
          int w = erzhi.Width;
          int h = erzhi.Height;
          BitmapData data = erzhi.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
          unsafe
          {
            byte* p = (byte*)data.Scan0;
            byte[,] vSource = new byte[w, h];
            int offset = data.Stride - w * nn;
     
            for (int y = 0; y < h; y++)
            {
              for (int x = 0; x < w; x++)
              {
                vSource[x, y] = (byte)(((int)p[0] + (int)p[1] + (int)p[2]) / 3);
                p += nn;
              }
              p += offset;
            }
            erzhi.UnlockBits(data);
     
            Bitmap bmpDest = new Bitmap(w, h, PixelFormat.Format24bppRgb);
            BitmapData dataDest = bmpDest.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
            p = (byte*)dataDest.Scan0;
            offset = dataDest.Stride - w * nn;
            for (int y = 0; y < h; y++)
            {
              for (int x = 0; x < w; x++)
              {
                p[0] = p[1] = p[2] = (int)vSource[x, y] > 161 ? (byte)255 : (byte)0;
                //p[0] = p[1] = p[2] = (int)GetAverageColor(vSource, x, y, w, h) > 50 ? (byte)255 : (byte)0;
                p += nn;
     
              }
              p += offset;
            }
            bmpDest.UnlockBits(dataDest);
             
            orcbmp = bmpDest;
            orcbmp.Save("d:\二值化.png");
            pictureBox29.Image = Image.FromFile("d:\二值化.png");
          }
     
          //OCR的值
          if (orcbmp != null)
          {
            string result = Ocr(orcbmp);
            label32.Text = result.Replace("
    ", "
    ").Replace(" ", "");
          }
     
        }

    C#识别验证码图片通用类

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Collections;
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.Runtime.InteropServices;
     
    namespace BallotAiying2
    {
      class UnCodebase
      {
        public Bitmap bmpobj;
        public UnCodebase(Bitmap pic)
        {
          bmpobj = new Bitmap(pic);  //转换为Format32bppRgb
        }
     
        /// <summary>
        /// 根据RGB,计算灰度值
        /// </summary>
        /// <param name="posClr">Color值</param>
        /// <returns>灰度值,整型</returns>
        private int GetGrayNumColor(System.Drawing.Color posClr)
        {
          return (posClr.R * 19595 + posClr.G * 38469 + posClr.B * 7472) >> 16;
        }
     
        /// <summary>
        /// 灰度转换,逐点方式
        /// </summary>
        public void GrayByPixels()
        {
          for (int i = 0; i < bmpobj.Height; i++)
          {
            for (int j = 0; j < bmpobj.Width; j++)
            {
              int tmpValue = GetGrayNumColor(bmpobj.GetPixel(j, i));
              bmpobj.SetPixel(j, i, Color.FromArgb(tmpValue, tmpValue, tmpValue));
            }
          }
        }
     
        /// <summary>
        /// 去图形边框
        /// </summary>
        /// <param name="borderWidth"></param>
        public void ClearPicBorder(int borderWidth)
        {
          for (int i = 0; i < bmpobj.Height; i++)
          {
            for (int j = 0; j < bmpobj.Width; j++)
            {
              if (i < borderWidth || j < borderWidth || j > bmpobj.Width - 1 - borderWidth || i > bmpobj.Height - 1 - borderWidth)
                bmpobj.SetPixel(j, i, Color.FromArgb(255, 255, 255));
            }
          }
        }
     
        /// <summary>
        /// 灰度转换,逐行方式
        /// </summary>
        public void GrayByLine()
        {
          Rectangle rec = new Rectangle(0, 0, bmpobj.Width, bmpobj.Height);
          BitmapData bmpData = bmpobj.LockBits(rec, ImageLockMode.ReadWrite, bmpobj.PixelFormat);// PixelFormat.Format32bppPArgb);
          //  bmpData.PixelFormat = PixelFormat.Format24bppRgb;
          IntPtr scan0 = bmpData.Scan0;
          int len = bmpobj.Width * bmpobj.Height;
          int[] pixels = new int[len];
          Marshal.Copy(scan0, pixels, 0, len);
     
          //对图片进行处理
          int GrayValue = 0;
          for (int i = 0; i < len; i++)
          {
            GrayValue = GetGrayNumColor(Color.FromArgb(pixels));
            pixels = (byte)(Color.FromArgb(GrayValue, GrayValue, GrayValue)).ToArgb();   //Color转byte
          }
     
          bmpobj.UnlockBits(bmpData);
        }
     
        /// <summary>
        /// 得到有效图形并调整为可平均分割的大小
        /// </summary>
        /// <param name="dgGrayValue">灰度背景分界值</param>
        /// <param name="CharsCount">有效字符数</param>
        /// <returns></returns>
        public void GetPicValidByValue(int dgGrayValue, int CharsCount)
        {
          int posx1 = bmpobj.Width; int posy1 = bmpobj.Height;
          int posx2 = 0; int posy2 = 0;
          for (int i = 0; i < bmpobj.Height; i++)   //找有效区
          {
            for (int j = 0; j < bmpobj.Width; j++)
            {
              int pixelValue = bmpobj.GetPixel(j, i).R;
              if (pixelValue < dgGrayValue)   //根据灰度值
              {
                if (posx1 > j) posx1 = j;
                if (posy1 > i) posy1 = i;
     
                if (posx2 < j) posx2 = j;
                if (posy2 < i) posy2 = i;
              };
            };
          };
          // 确保能整除
          int Span = CharsCount - (posx2 - posx1 + 1) % CharsCount;  //可整除的差额数
          if (Span < CharsCount)
          {
            int leftSpan = Span / 2;  //分配到左边的空列 ,如span为单数,则右边比左边大1
            if (posx1 > leftSpan)
              posx1 = posx1 - leftSpan;
            if (posx2 + Span - leftSpan < bmpobj.Width)
              posx2 = posx2 + Span - leftSpan;
          }
          //复制新图
          Rectangle cloneRect = new Rectangle(posx1, posy1, posx2 - posx1 + 1, posy2 - posy1 + 1);
          bmpobj = bmpobj.Clone(cloneRect, bmpobj.PixelFormat);
        }
         
        /// <summary>
        /// 得到有效图形,图形为类变量
        /// </summary>
        /// <param name="dgGrayValue">灰度背景分界值</param>
        /// <param name="CharsCount">有效字符数</param>
        /// <returns></returns>
        public void GetPicValidByValue(int dgGrayValue)
        {
          int posx1 = bmpobj.Width; int posy1 = bmpobj.Height;
          int posx2 = 0; int posy2 = 0;
          for (int i = 0; i < bmpobj.Height; i++)   //找有效区
          {
            for (int j = 0; j < bmpobj.Width; j++)
            {
              int pixelValue = bmpobj.GetPixel(j, i).R;
              if (pixelValue < dgGrayValue)   //根据灰度值
              {
                if (posx1 > j) posx1 = j;
                if (posy1 > i) posy1 = i;
     
                if (posx2 < j) posx2 = j;
                if (posy2 < i) posy2 = i;
              };
            };
          };
          //复制新图
          Rectangle cloneRect = new Rectangle(posx1, posy1, posx2 - posx1 + 1, posy2 - posy1 + 1);
          bmpobj = bmpobj.Clone(cloneRect, bmpobj.PixelFormat);
        }
     
        /// <summary>
        /// 得到有效图形,图形由外面传入
        /// </summary>
        /// <param name="dgGrayValue">灰度背景分界值</param>
        /// <param name="CharsCount">有效字符数</param>
        /// <returns></returns>
        public Bitmap GetPicValidByValue(Bitmap singlepic, int dgGrayValue)
        {
          int posx1 = singlepic.Width; int posy1 = singlepic.Height;
          int posx2 = 0; int posy2 = 0;
          for (int i = 0; i < singlepic.Height; i++)   //找有效区
          {
            for (int j = 0; j < singlepic.Width; j++)
            {
              int pixelValue = singlepic.GetPixel(j, i).R;
              if (pixelValue < dgGrayValue)   //根据灰度值
              {
                if (posx1 > j) posx1 = j;
                if (posy1 > i) posy1 = i;
     
                if (posx2 < j) posx2 = j;
                if (posy2 < i) posy2 = i;
              };
            };
          };
          //复制新图
          Rectangle cloneRect = new Rectangle(posx1, posy1, posx2 - posx1 + 1, posy2 - posy1 + 1);
          return singlepic.Clone(cloneRect, singlepic.PixelFormat);
        }
         
        /// <summary>
        /// 平均分割图片
        /// </summary>
        /// <param name="RowNum">水平上分割数</param>
        /// <param name="ColNum">垂直上分割数</param>
        /// <returns>分割好的图片数组</returns>
        public Bitmap [] GetSplitPics(int RowNum,int ColNum)
        {
          if (RowNum == 0 || ColNum == 0)
            return null;
          int singW = bmpobj.Width / RowNum;
          int singH = bmpobj.Height / ColNum;
          Bitmap [] PicArray=new Bitmap[RowNum*ColNum];
     
          Rectangle cloneRect;
          for (int i = 0; i < ColNum; i++)   //找有效区
          {
            for (int j = 0; j < RowNum; j++)
            {
              cloneRect = new Rectangle(j*singW, i*singH, singW , singH);
              PicArray[i*RowNum+j]=bmpobj.Clone(cloneRect, bmpobj.PixelFormat);//复制小块图
            }
          }
          return PicArray;
        }
     
        /// <summary>
        /// 返回灰度图片的点阵描述字串,1表示灰点,0表示背景
        /// </summary>
        /// <param name="singlepic">灰度图</param>
        /// <param name="dgGrayValue">背前景灰色界限</param>
        /// <returns></returns>
        public string GetSingleBmpCode(Bitmap singlepic, int dgGrayValue)
        {
          Color piexl;
          string code = "";
          for (int posy = 0; posy < singlepic.Height; posy++)
            for (int posx = 0; posx < singlepic.Width; posx++)
            {
              piexl = singlepic.GetPixel(posx, posy);
              if (piexl.R < dgGrayValue)  // Color.Black )
                code = code + "1";
              else
                code = code + "0";
            }
          return code;
        }
      }
    }

    以上2则都是使用C#实现的orc识别的代码,希望对大家学习C#有所帮助。

    ********转载:https://m.jb51.net/article/74533.htm

  • 相关阅读:
    Serverless Kubernetes入门:对kubernetes做减法
    Quick BI的宝藏工具——交叉表
    Quick BI的SQL传参建模可以用在什么场景
    Quick BI支持哪些数据源(配置操作篇)
    注册 asp.net IIS
    js Date 生成某年某月的天数
    IOC AOP 设计模式
    stuff for xml path
    使用Sencha Cmd创建脚本框架
    Extjs Ext.TreePanel
  • 原文地址:https://www.cnblogs.com/linybo/p/10126847.html
Copyright © 2011-2022 走看看