zoukankan      html  css  js  c++  java
  • OpenCvSharp+ZXing实现多个DataMatrix解析

    最近公司需要开发一个DataMatrix码识别的小软件,由于DataMatrix码实在太小了网上找了很多案例都不能一下子就识别多个二维码。所以就只能通过OpenCvSharp来完成一系列的操作。

    下面直接上代码,功能代码都写好注释,不明白的地方可以@我

    OpenFileDialog openFileDialog = new OpenFileDialog();
    if (openFileDialog.ShowDialog() == DialogResult.OK)
    {
    Mat srcImage = new Mat(openFileDialog.FileName);
    //转化为灰度图
    Mat src_gray = new Mat();
    //滤波
    Cv2.Blur(srcImage, src_gray, new OpenCvSharp.Size(3, 3));
    // Cv2.ImShow("滤波", src_gray);
    Mat src_gray1 = new Mat();
    //二值化 130 具体指可以根据DataMatrix码的白色的RGB值来调整
    Cv2.Threshold(src_gray, src_gray1, 130, 255, ThresholdTypes.Binary);
    //Cv2.ImShow("二值化", src_gray1);
    //Canny边缘检测
    Mat canny_Image = new Mat();
    Cv2.Canny(src_gray1, canny_Image, 100, 200);
    //Cv2.ImShow("Canny边缘检测", canny_Image);
    //消除裂缝2 Size(11, 12) Size的值可以调整,结果出来为DataMatrix码 区域全白就ok啦。
    OpenCvSharp.Size size2 = new OpenCvSharp.Size(11, 12);
    Mat kernel = Cv2.GetStructuringElement(MorphShapes.Rect, size2);
    Cv2.MorphologyEx(canny_Image, canny_Image, MorphTypes.Close, kernel);
    // Cv2.MorphologyEx(canny_Image, canny_Image, MorphTypes.Close, canny_Image1, null,6 , BorderTypes.Constant,1);
    //Cv2.ImShow("消除裂缝", canny_Image);
    //canny_Image.SaveImage("10.bmp");
    //获得轮廓
    Mat[] contours = new Mat[10000];
    contours = Cv2.FindContoursAsMat(canny_Image, RetrievalModes.CComp, ContourApproximationModes.ApproxNone, null);
    // Cv2.FindContours(canny_Image, out contours, out hierarchly, RetrievalModes.Tree, ContourApproximationModes.ApproxSimple, new Point(0, 0));


    //将结果画出并返回结果
    Mat dst_Image = Mat.Zeros(canny_Image.Size(), srcImage.Type());


    int z = 0;
    for (int i = 0; i < contours.Length; i++)
    {
    Rect rect = Cv2.BoundingRect(contours[i]);
    //只判断DataMatrix码的宽度才进入解析
    if (rect.Width > 60 && rect.Height > 88 && rect.Width < 100 && rect.Height < 110)
    {
    //将DataMatrix码范围的框框裁剪出图片
    Rect rect1 = new Rect(rect.X, rect.Y, rect.Width, rect.Height);
    //srcImage 为原图像 rect1 裁剪的范围。
    Mat RectMat = new Mat(srcImage, rect1);
    Bitmap bitmap = BitmapConverter.ToBitmap(RectMat);
    //将裁剪出来的图片进行放大,如果不放大ZXing解析的结果就不理想。(会漏了好多DataMatrix码)
    OpenCvSharp.Size size = new OpenCvSharp.Size(bitmap.Width * 5, bitmap.Height * 5);
    Mat SizeMat = new Mat();
    Cv2.Resize(RectMat, SizeMat, size);
    bitmap.Dispose();
    Bitmap bitmap1 = BitmapConverter.ToBitmap(SizeMat);
    //bitmap.Save(i + ".png");
    for (int y = 0; y < 4; y++)
    {
    //解析DataMatrix码
    BarcodeReader reader = new BarcodeReader();
    Result result = reader.Decode(bitmap1);
    if (result == null)
    {
    //翻转图片让ZXing重新解析,防止DataMatrix码因为位置识别不出来
    bitmap1.RotateFlip(RotateFlipType.Rotate90FlipNone);
    continue;
    }
    else
    {
    z++;
    bitmap1.Save(z + ".jpg");
    textBox1.Text += "第" + z + "个码:" + result.ToString() + Environment.NewLine;
    break;
    }
    }

    bitmap1.Dispose();
    RectMat.Dispose();
    SizeMat.Dispose();
    Scalar color = Scalar.Red;
    Cv2.DrawContours(dst_Image, contours, i, color, 2, LineTypes.Link8, null);

    }

    }

    srcImage.Dispose();
    // Cv2.ImShow("结果", dst_Image);
    dst_Image.SaveImage("1.bmp");
    }

    //**我也是一个站在巨人肩旁写程序的搬运工(前人种树后人乘凉)**//

  • 相关阅读:
    Response 文件下载
    Tomcat Servlet
    Junit 反射 注解
    Stream流 方法引用
    函数式接口
    网络编程
    缓冲流、转换流、序列化流、打印流
    字节流 字符流
    File类 递归
    线程池 Lambda表达式
  • 原文地址:https://www.cnblogs.com/jobyym/p/13706173.html
Copyright © 2011-2022 走看看