身份证识别

一.图像处理

  • 灰度化图像。
  • 二值化图像。 利用 AdaptiveThresholdType 全局化阈值,blockSize = 55时,效果最好。
public static Image BinImg(Image  img)
        {
            return img.Convert().ThresholdAdaptive(new Gray(255),
                AdaptiveThresholdType.GaussianC,
                ThresholdType.Binary,
                55,
                new Gray(55)).Erode(9);
        }

二、身份证号区域提取

  • 扩选图像黑色像素区域,形成连通区域。 
img.Erode(9)
  • 提取轮廓
/// 
        /// 获取轮廓
        /// 
        /// 
        /// 
        private static  VectorOfVectorOfPoint GetContours(Image pic)
        {
            Image p1 = new Image(pic.Size);
            Image p2 = pic.Canny(60, 255);
            VectorOfVectorOfPoint contours = contours = new VectorOfVectorOfPoint();
            CvInvoke.FindContours(p2, contours, p1, RetrType.Ccomp, ChainApproxMethod.ChainApproxSimple);
            return contours;
        }
  • 轮廓筛选,提取身份证矩形区域。身份证号的宽高比约为8,将比值为7~9的轮廓保留,并绘制矩形
//筛选矩形
 public static RotatedRect RotatedRect( Image img)
        {
            Image a = new Image(img.Size);
            VectorOfVectorOfPoint con = GetContours(BinImg(img));
            Point[][] con1 = con.ToArrayOfArray();
            PointF[][] con2 = Array.ConvertAll(con1, new Converter(PointToPointF));
            for (int i = 0; i < con.Size; i++)
            {
                RotatedRect rrec = CvInvoke.MinAreaRect(con2[i]); 
                float w = rrec.Size.Width;
                float h = rrec.Size.Height;  
                if (w / h > 6  &&  w / h < 10 && h > 20)
                {

                    PointF[] pointfs = rrec.GetVertices();
                    for (int j = 0; j < pointfs.Length; j++)
                        CvInvoke.Line(a, new Point((int)pointfs[j].X, (int)pointfs[j].Y), new Point((int)pointfs[(j + 1) % 4].X, (int)pointfs[(j + 1) % 4].Y), new MCvScalar(0, 0, 255, 255), 4);
                    return rrec;
                }

            }
            return new RotatedRect();
        }

//绘制矩形
 public static void DrawRotatedRect(RotatedRect rrec, Image img)
        {
            PointF[] pointfs = rrec.GetVertices();
            for (int j = 0; j < pointfs.Length; j++)
                CvInvoke.Line(img, new Point((int)pointfs[j].X, (int)pointfs[j].Y), new Point((int)pointfs[(j + 1) % 4].X, (int)pointfs[(j + 1) % 4].Y), new MCvScalar(0, 0, 255, 255), 4);
        }

你可能感兴趣的:(身份证识别)