在图像c#中查找条形码的坐标

时间:2017-09-25 14:59:34

标签: c# .net opencv emgucv

我有一些包含3-4个条形码的图像。我想标记所有条形码而不管位置如何。我试图使用下面的代码获取图像中的所有矩形,但它们返回空或不标记条形码。我错过了什么吗?任何指针都将非常感激。

I also tried to follow this tutorial并尝试将其移植到EmguCV并且不确定要通过哪些函数的缺失参数。评论部分是我不确定的部分。请指导我改正方向。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Emgu.CV;
using Emgu.CV.Structure;
using System.IO;
using static System.Net.Mime.MediaTypeNames;
using Emgu.CV.CvEnum;
using Emgu.CV.Util;
using System.Windows.Forms;

namespace ConsoleApplication4
{
    class Program
    {

       //public static Mat mat = new Mat();
       // public static Mat kernel = new Mat();

       // private static Image<Bgr, byte> gradX = mat.ToImage<Bgr,byte>();
       // private static Image<Bgr, byte> gradY = mat.ToImage<Bgr, byte>();
       // private static Image<Bgr, byte> gradient = mat.ToImage<Bgr, byte>();
       // private static Image<Bgr, byte> blur = mat.ToImage<Bgr, byte>();
       // private static Image<Bgr, byte> thresh = mat.ToImage<Bgr, byte>();
       // private static Image<Bgr, byte> closed = mat.ToImage<Bgr, byte>();


        static void Main(string[] args)
        {

                    Image<Bgr, byte> gambar = new Image<Bgr, byte>("source.jpg");
                    Image<Bgr, byte> kotak = detectBarcode(gambar);
                    kotak.ToBitmap().Save("destination.jpg");

            Console.ReadKey();

        }


        private static Image<Bgr, byte> detectBarcode(Image<Bgr, byte> image)
        {

            try
            {
                Image<Gray, byte> imageGrey = image.Convert<Gray, byte>();



                //CvInvoke.Sobel(imageGrey, gradX, DepthType.Cv32F, 1, 0, -1);
                //CvInvoke.Sobel(imageGrey, gradY, DepthType.Cv32F, 0, 1, -1);

                //CvInvoke.Subtract(gradX, gradY, gradient);
                //CvInvoke.ConvertScaleAbs(gradient, gradient, 0, 0);

                //CvInvoke.Blur(gradient, blur, new System.Drawing.Size(new System.Drawing.Point(9, 9)), new System.Drawing.Point(9, 9));
                //CvInvoke.Threshold(blur, thresh, 255, 255, ThresholdType.Binary);

                //kernel = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new System.Drawing.Size(new System.Drawing.Point(9, 9)), new System.Drawing.Point(9, 9));

                //CvInvoke.MorphologyEx(thresh,closed,MorphOp.Close,kernel,);

                //CvInvoke.Erode(closed,closed, new System.Drawing.Point(0, 0),4,BorderType.Default,);
                //CvInvoke.Dilate(closed, closed, new System.Drawing.Point(0, 0), 4, BorderType.Default,);

                List<RotatedRect> boxList = new List<RotatedRect>();

                UMat cannyEdges = new UMat();
                double cannyThreshold = 180.0;
                double cannyThresholdLinking = 120.0;
                CvInvoke.Canny(imageGrey, cannyEdges, cannyThreshold, cannyThresholdLinking);


                using (VectorOfVectorOfPoint countours = new VectorOfVectorOfPoint())
                {

                    CvInvoke.FindContours(cannyEdges, countours, null, RetrType.List,
                    ChainApproxMethod.ChainApproxSimple);
                    int count = countours.Size;
                    for (int i = 0; i < count; i++)
                    {
                        using (VectorOfPoint kontur = countours[i])
                        using (VectorOfPoint approxContour = new VectorOfPoint())
                        {
                            CvInvoke.ApproxPolyDP(kontur, approxContour, CvInvoke.ArcLength(kontur, true) * 0.05, true);
                            if (CvInvoke.ContourArea(approxContour, false) > 250) //only consider contours with area greater than 250
                            {
                                if (approxContour.Size == 4) //rectangle
                                {
                                    //determine if allthe angles in the contour are within [80,100] degree
                                    bool isRectangle = true;
                                    System.Drawing.Point[] pts = approxContour.ToArray();
                                    LineSegment2D[] edges = Emgu.CV.PointCollection.PolyLine(pts, true);

                                    for (int j = 0; j < edges.Length; j++)
                                    {
                                        double angle = Math.Abs(
                                        edges[(j + i) % edges.Length].GetExteriorAngleDegree(edges[j]));
                                        if (angle < 80 || angle > 100)
                                        {
                                            isRectangle = false;
                                            break;
                                        }

                                    }
                                    if (isRectangle) boxList.Add(CvInvoke.MinAreaRect(approxContour));
                                }
                            }
                        }
                    }
                }

                Image<Bgr, byte> triRectImage = image.Copy();

                foreach (RotatedRect box in boxList)
                    triRectImage.Draw(box, new Bgr(0, 0, 0), 5);
                return triRectImage;

            }
            catch (Exception e) {

                Console.WriteLine(e.StackTrace);

                return null;
            }



        }
}
}

1 个答案:

答案 0 :(得分:0)

I find myself referring you to, for example

  

public static void Sobel(IInputArray src,IOutputArray dst,   DepthType ddepth,int xorder,int yorder,int kSize = 3,double scale = 1,double delta = 0,BorderType borderType =   BorderType.Reflect101)

下面是详细的参数列表及其含义。如果你真的不了解这一点,那么我会建议你need to read the tutorials,否则你需要Emgu CV的专家来告诉你如何编写你的程序,这不完全是这个网站的意思。

我不希望听起来不友好,但你至少需要捅一下你想做的事情。