欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

c#实现识别图片上的验证码数字

程序员文章站 2022-11-22 11:34:16
public void imgdo(bitmap img) { //去色 bitmap btp = img;...

c#实现识别图片上的验证码数字

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("\n", "\r\n").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#有所帮助。