c# EmguCv定位二维码
2015-08-14 16:18
806 查看
c# EmguCv定位二维码
/article/10364101.htmlEmgu 和opencv一样,用opencv写的程序当然也可以“翻译”为Emgu版,这里展示一个demo,使用Emgu定位图片中的二维码。
1.载入图像
System.Drawing.Image img = System.Drawing.Image.FromFile("E:\\code.jpg"); Bitmap barcodeBitmap = new Bitmap(img); Image<Bgr, byte> img_src = new Image<Bgr, byte>(barcodeBitmap );
2.转为灰度图
Image<Gray, byte> imput_gray = new Image<Gray, byte>(img_src.Size); CvInvoke.cvCvtColor(img_src, imput_gray, COLOR_CONVERSION.BGR2GRAY);
3.计算x,y方向梯度,相加
Image<Gray, byte> grad_x1 = new Image<Gray, byte>(img_src.Size); Image<Gray, byte> grad_y1 = new Image<Gray, byte>(img_src.Size); Image<Gray, byte> grad_all = new Image<Gray, byte>(img_src.Size); CvInvoke.cvSobel(imput_gray, grad_x1, 0, 1,3); CvInvoke.cvSobel(imput_gray, grad_y1, 1, 0, 3); CvInvoke.cvAdd(grad_x1, grad_y1, grad_all, IntPtr.Zero);
梯度图:
4.平均模糊
//平均模糊(9*9内核大小) CvInvoke.cvSmooth(grad_all, grad_all, SMOOTH_TYPE.CV_BLUR, 9, 9,0,0); CvInvoke.cvShowImage("平均模糊", grad_all);
平均模糊结果:
5.二值化
CvInvoke.cvThreshold(grad_all, grad_all, 100, 255, THRESH.CV_THRESH_BINARY); CvInvoke.cvShowImage("二值化", grad_all);
二值化图片:
6.消除裂缝
StructuringElementEx element = new StructuringElementEx( 21, 21,0, 0, Emgu.CV.CvEnum.CV_ELEMENT_SHAPE.CV_SHAPE_RECT ); CvInvoke.cvMorphologyEx( grad_all, grad_all, IntPtr.Zero, element, CV_MORPH_OP.CV_MOP_CLOSE, 1 ); CvInvoke.cvShowImage("消除裂缝", grad_all);
图片结果:
7.膨胀与腐蚀(消除杂点)
StructuringElementEx element1 = new StructuringElementEx(5, 5, 0, 0, Emgu.CV.CvEnum.CV_ELEMENT_SHAPE.CV_SHAPE_RECT); CvInvoke.cvErode(grad_all, grad_all, element1, 4); CvInvoke.cvDilate(grad_all, grad_all, element1, 4); CvInvoke.cvShowImage("膨胀与腐蚀", grad_all);
结果:
8.查找轮廓,绘制轮廓
IntPtr mem_storage = CvInvoke.cvCreateMemStorage(0); MCvSeq first_contour = new MCvSeq(); IntPtr Dyncontour = new IntPtr();//存放检测到的图像块的首地址 CvInvoke.cvFindContours(grad_all, mem_storage, ref Dyncontour, StructSize.MCvContour, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_EXTERNAL, Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_NONE, new Point(0, 0)); IntPtr temp = first_contour.ptr; Seq<Point> DyncontourTemp1 = new Seq<Point>(Dyncontour, null);//方便对IntPtr类型进行操作 Seq<Point> DyncontourTemp = DyncontourTemp1; for (; DyncontourTemp1 != null && DyncontourTemp1.Ptr.ToInt32() != 0; DyncontourTemp1 = DyncontourTemp1.HNext) { Rectangle rect = CvInvoke.cvBoundingRect(DyncontourTemp1, true); if (rect.Width > 20 && rect.Height > 20) { rect.Width += 50; rect.Height += 50; Point p1 = new Point(rect.X, rect.Y); Point p2 = new Point(rect.X + rect.Width, rect.Y + rect.Height); CvInvoke.cvRectangle(img_src, p1, p2, new MCvScalar(0, 0, 255), 2, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, 0); } }
最后的结果:
9.最后
从上图可以看出找到了其中两个二维码,但是多了一个轮廓,不过定位二维码的主要功能就是用于识别,识别不出来的定位块自然也就没有用了。如果定位一维码(水平或垂直方向),即两个方向梯度相减,效果也不错。当然,这种定位方法会出现这样一些不必要的小框,是不是可以通过大小再过滤一次呢?相关文章推荐
- C#基数样条曲线的模拟实现(对应Graphics的DrawCurve)
- C# WinForm判断Win7下是否是管理员身份运行
- C#使用 System.Net.Mail发送邮件功能
- C#实现基于XML配置MenuStrip菜单的方法
- C#实现自定义Dictionary类实例
- C# 数字转ASCII码
- C#在VS2013中类型图标
- 一个空循环的问题
- c#语法糖代码——继承中构造函数的问题,this&base比较
- C#实现将数组内元素打乱顺序的方法
- C#基础——Func和Action的介绍及其用法
- 编写高质量代码改善C#程序的157个建议——建议21:选择正确的集合
- C#中Image , Bitmap 和 BitmapData
- .net 中,使用c# 语言 ,执行exe程序。
- C#中Math.Round()实现中国式四舍五入
- C#写csv文件
- C#多媒体编程
- C#发送邮件
- C#开发COM组件供其他开发环境或工具调用介绍(转)
- Visual C#2010学习笔记七之for语句的使用