模式识别开发之项目---身份证上面的数字识别

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Text;
using System.Collections;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

namespace ReadNum_DividedByZeros_
{
    class CBitmap
    {
        /**/
        /// <summary>
        /// 生成缩略图
        /// </summary>
        /// <param name="originalImagePath">源图路径(物理路径)</param>
        /// <param name="width">缩略图宽度</param>
        /// <param name="height">缩略图高度</param>

public static Bitmap MakeThumbnail(string originalImagePath, int width, int height, int potx, int poty)
        {
            System.Drawing.Image originalImage = System.Drawing.Image.FromFile(originalImagePath);

int towidth = width;
            int toheight = height;

int x = potx;
            int y = poty;
            int ow = width;
            int oh = height;

System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(towidth, toheight); //Image=>Bitmap

//新建一个画板
            System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap);

//设置高质量插值法
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;

//设置高质量,低速度呈现平滑程度
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

//清空画布并以透明背景色填充
            g.Clear(Color.Transparent);

//在指定位置并且按指定大小绘制原图片的指定部分
            g.DrawImage(originalImage, new Rectangle(0, 0, towidth, toheight), new Rectangle(x, y, ow, oh), GraphicsUnit.Pixel);

return bitmap;  // creative class Bitmap is here _Jiana
        }
    }

/// <summary>
    /// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// </summary>

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[i]));
                pixels[i] = (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 posx = 0; posx < singlepic.Width; posx++)
                for (int posy = 0; posy < singlepic.Height; posy++)
                {
                    piexl = singlepic.GetPixel(posx, posy);
                    if (piexl.R < dgGrayValue)    // Color.Black )
                        code = code + "1";
                    else
                        code = code + "0";
                }
            return code;
        }

/* The function is used to divide picture by analysing zeros of pixel _Jiana */
        public string[] dividePic(string picPixel, int zerosLength)
        {
            string zeros = "";
            for (int i = 0; i < zerosLength; i++)
            {
                zeros+=‘0‘;
            }
            string[] array = System.Text.RegularExpressions.Regex.Split(picPixel, zeros);
            return array;
        }

/* The function is used to analyze the pixel‘s codes and conver them to number _Jiana*/
        public string analyzePixelC(string[] code,int drow)
        {
            long[] sum = new long[drow];
            for (int i = 0; i < drow; i++)
            {
                for (int j = 0; j < code[i].Length; j++)
                {
                    char num = code[i][j];
                    int a = (int)num - 48;
                    sum[i] += a;
                }
            }

char[] result = new char[drow];

for (int i = 0; i < drow; i++)
            {
                // Judge the number _Jiana
                if (sum[i] >= 63 && sum[i] <= 69) { sum[i] = 66; } // 0
                if (sum[i] >= 36 && sum[i] <= 38) { sum[i] = 37; } // 1
                if (sum[i] >= 56 && sum[i] <= 58) { sum[i] = 57; } // 2
                if (sum[i] >= 57 && sum[i] <= 59) { sum[i] = 58; } // 3
                if (sum[i] >= 43 && sum[i] <= 45) { sum[i] = 44; } // 4
                if (sum[i] >= 49 && sum[i] <= 51) { sum[i] = 50; } // 5
                if (sum[i] >= 58 && sum[i] <= 60) { sum[i] = 59; } // 6
                if (sum[i] >= 44 && sum[i] <= 46) { sum[i] = 45; } // 7
                if (sum[i] >= 72 && sum[i] <= 78) { sum[i] = 75; } // 8 
                if (sum[i] >= 63 && sum[i] <= 65) { sum[i] = 64; } // 9
            }

for (int i = 0; i < drow; i++)
            {
                switch (sum[i])
                {
                    case 66: result[i] = ‘0‘; break;
                    case 37: result[i] = ‘1‘; break;
                    case 57: result[i] = ‘2‘; break;
                    case 58: result[i] = ‘3‘; break;
                    case 44: result[i] = ‘4‘; break;
                    case 50: result[i] = ‘5‘; break;
                    case 59: result[i] = ‘6‘; break;
                    case 45: result[i] = ‘7‘; break;
                    case 75: result[i] = ‘8‘; break;
                    case 64: result[i] = ‘9‘; break;
                    default: result[i] = ‘ ‘; break;
                }
            }

string returnResult = "";
            for (int i = 0; i < drow; i++)
            {
                returnResult += result[i];
            }
            return returnResult;
        }
    }

static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            //Application.EnableVisualStyles();
            //Application.SetCompatibleTextRenderingDefault(false);
            //Application.Run(new Form1());
            Bitmap mBitmap = CBitmap.MakeThumbnail("E://license2.jpg", 250, 22, 163, 242);
            UnCodebase rgb = new UnCodebase(mBitmap);
            rgb.GrayByPixels();
            int drow = 1, dcol = 1;
            Bitmap[] pics = rgb.GetSplitPics(drow, dcol);
            string[] code = new string[drow];
            for (int i = 0; i < drow; i++)
            {
                code[i] = rgb.GetSingleBmpCode(pics[i], 128);
            }

// test: divide by zeros _Jiana
            string piecePic = "";
            int lastOne = 0;
            int flag1=0;
            for (int i = code[0].Length-1; i > 0; i--)
            {
                if (code[0][i] != ‘0‘ && flag1 == 0)
                {
                    flag1 = 1;
                    lastOne = i;
                }
            }
            int flag2 = 0;
            for (int i = 0; i < lastOne; i++)
            {
                if (code[0][i] != ‘0‘ && flag2 == 0)
                {
                    flag2 = 1;
                }
                if (flag2 == 1)
                {
                    piecePic += code[0][i];
                }
            }

string[] div = rgb.dividePic(piecePic, 98);
            string number = rgb.analyzePixelC(div, 18);

System.Console.WriteLine("");
        }
    }
}

http://blog.csdn.net/liulina603/article/details/7945544

时间: 2024-08-05 07:51:49

模式识别开发之项目---身份证上面的数字识别的相关文章

模式识别开发之项目---计算机视觉目标检测的框架与过程

个人接触机器视觉的时间不长,对于机器学习在目标检测的大体的框架和过程有了一个初步的了解,不知道对不对,如有错误,请各位大牛不吝指点.   目标的检测大体框架: 目标检测分为以下几个步骤: 1.训练分类器所需训练样本的创建: 训练样本包括正样本和负样本:其中正例样本是指待检目标样本(例如人脸或汽车等),负样本指其它不包含目标的任意图片(如背景等),所有的样本图片都被归一化为同样的尺寸大小(例如,20x20). 2.特征提取: 由图像或波形所获得的数据量是相当大的.例如,一个文字图像可以有几千个数据

【iOS开发-UITabBarController】UITabBarController上面的UINavigationController的设置

自定义导航栏 为了保证项目的导航栏效果一直,一般都会设置导航栏的样式一样 ①自定义一个NavigationController类,继承与UINavigationController类 ②更改所有的UITabBarController下面的UINavigationController的class属性为自定义类形式 ③主要是取得导航栏的appearance对象,操作它就设置导航栏的主题 UINavigationBar *navBar = [UINavigationBar appearance]; ④

模式识别开发之项目---基于opencv的手势识别

我使用OpenCV2.4.4的windows版本+Qt4.8.3+VS2010的编译器做了一个手势识别的小程序. 本程序主要使到了Opencv的特征训练库和最基本的图像处理的知识,包括肤色检测等等. 废话不多,先看一下基本的界面设计,以及主要功能: 相信对于Qt有一些了解的人都不会对这个界面的设计感到陌生吧!(该死,该死!)我们向下走: 紧接着是Qt导入OPenCV2.4.4的库文件:(先看一下Qt的工程文件吧) [cpp] view plaincopyprint? #-------------

模式识别开发之项目---基于人头检测的人流量监测

最近在做基于Meanshift的人脸跟踪,效果一般.标准算法选择Hue分量作为特征,为了提高对背景的鲁棒性,有人提出了结合梯度.LBP等特征的多特征空间.但是直方图维数太少,而且丢失空间信息,使得特征分类价值退化严重.经测试,对于背景颜色与肤色类似(黄色)的情况,跟踪失效.因此看了看市面上的产品如何做流量统计. 人流量监测一般采用摄像头吊顶安装俯拍的方式,以避免客流量大时的遮挡.重叠等问题. 参考资料: 1:http://www.eccn.com/design_2011101810512969.

模式识别开发之项目---图像间的近似度计算

之前做幻觉脸的时候需要计算两幅人脸图像的近似度,想了好久没有想出来办法,也忘了在哪个论坛发了一封求助贴,n久之后没人回,一咬牙又凭着自己的想法解决了.虽然没人帮助解决,遇到同样苦难的童鞋们倒不少,现把我的解决方法置此,供需要的童鞋们参考: 两幅图像的近似度,说白了就是能够描述的图像的各种特征间的距离问题,可能不同类型的图像,能够描述图像的有效特征的类型差别较大,有的图像灰度信息就不错,有的则需要复杂的纹理.颜色.各种直方图之类的来描述,但是都具有一定的共性,我现在仅拿我使用过的特征作为参考,其他

身份证上的X到底代表什么?

生活中,无论你是坐火车,还是办理各种手续,都需要用到身份证,它现在已经俨然成为我们生活的非常重要的一部分,但是关于身份证本身,你了解多少呢? 有人会说了,为什么我的身份证上写的有效时间是10年,而一些人的时间是20年呢?下面大家一起来看一下! 一.有效期限 居民身份证的有效期限分为10年.20年.长期三种.16周岁至25周岁的,发给有效期为10年的居民身份证:26周岁至45周岁的,发给有效期为20年的居民身份证:46周岁以上的,发给长期有效的居民身份证.证件有效期限从签发之日起计算.如某人199

利用手写数字识别项目详细描述BP深度神经网络的权重学习

本篇文章是针对学习<深度学习入门>(由日本学者斋藤康毅所著陆羽杰所译)中关于神经网络的学习一章来总结归纳一些收获. 本书提出神经网络的学习分四步:1.mini-batch 2.计算梯度 3.更新参数 4.重复前面步骤 1.从识别手写数字项目学习神经网络 所谓“从数据中学习”是指 可以由数据#自动决定权重#.当解决较为简单的问题,使用简单的神经网络时,网络里的权重可以人为的手动设置,去提取输入信息中特定的特征.但是在实际的神经网络中,参数往往是成千上万,甚至可能上亿的权重,这个时候人为手动设置是

时间数字识别项目之大体完成

大框已经接近收尾.接下来剩下: 1)噪声添加 2)类标返回 3)汉字负样本添加 4)困难样本回收训练 5)...... 这些细节,更加提高准确率. 1 %{ 2 clear all; 3 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4 % 可调参数 5 6 %test_path='C:\Users\cong\Desktop\研一实战

自强队视觉组训练项目-3 | 20180107-印刷体数字识别

DEADLINE: 21st Jan, 2018 (Duration: 2 weeks) 项目需求 数字识别是机器视觉的一个经典话题,其中较为基础的是印刷体数字识别,这期项目要求实现印刷体数字识别,即给一张包含印刷体数字的图片,你的任务是将其中的数字以字符形式输出. 项目描述 项目需求描述了基本要求,具体难度可以自己调节,比如可以给一张只含一个数字的图片,然后通过计算灰度总值区分不同印刷体数字的特征.这是一种极其简单的思路,实现起来也许还是要花点功夫.当然你可以围绕"印刷体数字识别"这