Created
April 25, 2015 04:16
-
-
Save richardsawyer/62596e14d1ec4d148b28 to your computer and use it in GitHub Desktop.
Using openCvSharp to locate barcodes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// optimized to find a vertical barcode in an image | |
// inspired by http://www.pyimagesearch.com/2014/11/24/detecting-barcodes-images-python-opencv/ | |
using System; | |
using System.Drawing; | |
using System.Windows.Forms; | |
using OpenCvSharp; | |
using OpenCvSharp.Extensions; | |
namespace LocateBarcode | |
{ | |
internal class Program | |
{ | |
private static int _displayPosition = 0; | |
private const int _displayWidth = 400; | |
private static void Main(string[] args) | |
{ | |
var imagePath = args[0]; | |
using (var ipl = new IplImage(imagePath, LoadMode.Color)) | |
{ | |
var gray = new IplImage(ipl.Size, BitDepth.U8, 1); | |
Cv.CvtColor(ipl, gray, ColorConversion.BgrToGray); | |
var gradX = new IplImage(ipl.Size, BitDepth.U8, 1); | |
Cv.Sobel(gray, gradX, 1, 0, ApertureSize.Scharr); | |
var gradY = new IplImage(ipl.Size, BitDepth.U8, 1); | |
Cv.Sobel(gray, gradY, 0, 1, ApertureSize.Scharr); | |
var gradient = new IplImage(ipl.Size, BitDepth.U8, 1); | |
Cv.Sub(gradY, gradX, gradient); | |
Cv.ConvertScaleAbs(gradient, gradient); | |
var blurred = new IplImage(ipl.Size, BitDepth.U8, 1); | |
Cv.Smooth(gradient, blurred, SmoothType.Blur, 9, 9); | |
var thresh = new IplImage(ipl.Size, BitDepth.U8, 1); | |
Cv.Threshold(blurred, thresh, 80, 255, ThresholdType.Binary); | |
ShowBitmap(thresh.ToBitmap()); | |
var kernel = Cv.CreateStructuringElementEx(7, 30, 3, 15, ElementShape.Rect); | |
var closed = new IplImage(ipl.Size, BitDepth.U8, 1); | |
var temp = new IplImage(ipl.Size, BitDepth.U8, 1); | |
Cv.MorphologyEx(thresh, closed, temp, kernel, MorphologyOperation.Close); | |
ShowBitmap(closed.ToBitmap()); | |
Cv.Erode(closed, closed, null, 4); | |
Cv.Dilate(closed, closed, null, 4); | |
CvSeq<CvPoint> firstContour; | |
var storage = new CvMemStorage(); | |
var n = Cv.FindContours(closed, storage, out firstContour, CvContour.SizeOf, ContourRetrieval.External, | |
ContourChain.ApproxSimple, Cv.Point(0, 0)); | |
var currentContour = firstContour; | |
var biggestContour = firstContour; | |
for (var i = 1; i < n; i++) | |
{ | |
currentContour = currentContour.HNext; | |
if (currentContour.ContourArea() < biggestContour.ContourArea()) | |
{ | |
biggestContour = currentContour; | |
} | |
} | |
var cvRect = Cv.MinAreaRect2(biggestContour, storage); | |
CvPoint2D32f[] box; | |
Cv.BoxPoints(cvRect, out box); | |
var origHeight = Math.Abs(box[2].Y - box[0].Y); | |
var padding = origHeight*0.05F; | |
var x = (int) Math.Min(box[0].X, box[2].X); | |
var y = (int) (Math.Min(box[0].Y, box[2].Y) - padding); | |
var width = (int) Math.Abs(box[0].X - box[2].X); | |
var height = (int) (Math.Abs(box[0].Y - box[2].Y) + padding*2); | |
var roi = new CvRect(x, y, width, height); | |
Cv.SetImageROI(ipl, roi); | |
var barcode = ipl.ToBitmap(); | |
Cv.ResetImageROI(ipl); | |
Cv.DrawRect(ipl, roi, CvColor.Green, 5); | |
var taggedOrig = ipl.ToBitmap(); | |
ShowBitmap(taggedOrig); | |
ShowBitmap(barcode); | |
Application.Run(); | |
} | |
} | |
private static void ShowBitmap(Bitmap bitmap) | |
{ | |
var bmp = new Bitmap(bitmap); | |
var form = new Form | |
{ | |
Text = "Display IplImage in PictureBox", | |
ClientSize = new Size(_displayWidth, 700), | |
StartPosition = FormStartPosition.Manual, | |
Location = new Point(_displayPosition, 0) | |
}; | |
_displayPosition += _displayWidth; | |
var pictureBox = new PictureBox | |
{ | |
Dock = DockStyle.Fill, | |
SizeMode = PictureBoxSizeMode.Zoom, | |
Image = bmp, | |
}; | |
form.Controls.Add(pictureBox); | |
form.Show(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment