2017-09-25 111 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