Skip to content

Instantly share code, notes, and snippets.

@richardsawyer
Created April 25, 2015 04:16
Show Gist options
  • Save richardsawyer/62596e14d1ec4d148b28 to your computer and use it in GitHub Desktop.
Save richardsawyer/62596e14d1ec4d148b28 to your computer and use it in GitHub Desktop.
Using openCvSharp to locate barcodes
// 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