2017-09-25 110 views
-1

我有一些包含3-4条形码的图像。我想标记所有条形码,而不考虑位置。我试图使用下面的代码获取图像中的所有矩形,但它们会返回空白或不标记条形码。我错过了什么吗?任何指针将不胜感激。在图像c中查找条形码的坐标#

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; 
      } 



     } 
} 
} 
+0

你真的认为所有注释掉的代码都增加了对这个问题有用的东西吗? [mcve]中的“minimal”是有原因的。 –

回答

0

I find myself referring you to, for example

公共静态无效索贝尔(IInputArray SRC,IOutputArray DST, DepthType ddepth,INT xorder,INT yorder,INT kSize = 3,双标度= 1,双Δ= 0, BorderType borderType = BorderType.Reflect101)

下面有详细的参数列表以及它们的含义。如果你没有真正理解这个,那么我会建议你need to read the tutorials彻底,否则你将需要在Emgu CV的专家告诉你如何编写你的程序,这不完全是本网站的要点。

我不想听起来不仁慈,但你至少需要刺激你试图做的任何事情。

+0

当然!谢谢凯文。 – Sri