Emgu-WPF学习使用-识别二维码的位置

原文:Emgu-WPF学习使用-识别二维码的位置

? ?参考链接:http://blog.csdn.net/gaobobo138968/article/details/47663607

? ?我完全参照该链接实现了二维码的位置锁定,向原作者致敬。

? ?由于我使用的为最新版本的Emgu,很多封装函数调用方法有所变化,新手接触Emgu,尝试做了调整,部分参数也做了微调!

? ?我使用的Emgu版本:emgucv-windesktop 3.2.0.2682

? ?最终我实现的效果图如下:

前台xaml:?

?<Grid>
? ? ? ? <Grid.ColumnDefinitions>
? ? ? ? ? ? <ColumnDefinition/>
? ? ? ? ? ? <ColumnDefinition/>
? ? ? ? ? ? <ColumnDefinition/>
? ? ? ? ? ? <ColumnDefinition/>
? ? ? ? </Grid.ColumnDefinitions>
? ? ? ? <Grid.RowDefinitions>
? ? ? ? ? ? <RowDefinition/>
? ? ? ? ? ? <RowDefinition/>
? ? ? ? </Grid.RowDefinitions>
? ? ? ? <Image x:Name="Img1" Grid.Column="0" />
? ? ? ? <Image x:Name="Img2" Grid.Column="1" />
? ? ? ? <Image x:Name="Img3" Grid.Column="2" />
? ? ? ? <Image x:Name="Img4" Grid.Column="3" />
? ? ? ? <Image x:Name="Img5" Grid.Column="0" Grid.Row="1"/>
? ? ? ? <Image x:Name="Img6" Grid.Column="1" Grid.Row="1"/>
? ? ? ? <Image x:Name="Img7" Grid.Column="2" Grid.Row="1"/>
? ? ? ? <Viewbox Stretch="Fill" Grid.Column="3" Grid.Row="1">
? ? ? ? ? ? <Grid Width="1134" Height="850" Background="Silver">
? ? ? ? ? ? ? ? <Image x:Name="Img8"/>
? ? ? ? ? ? ? ? <Canvas x:Name="CvMainZm"/>
? ? ? ? ? ? </Grid>
? ? ? ? </Viewbox>
? ? ? ?
? ? </Grid>

后台源码:

? ? ? ? private void ShowImage(System.Windows.Controls.Image oImage, UMat src)
? ? ? ? {
? ? ? ? ? ? this.Dispatcher.Invoke(() => {
? ? ? ? ? ? ? ? oImage.Source = BitmapSourceConvert.ToBitmapSource(src);
? ? ? ? ? ? });
? ? ? ? }

? ? ? ? private void ShowBgrImage(System.Windows.Controls.Image oImage, Image<Bgr, byte> src)
? ? ? ? {
? ? ? ? ? ? this.Dispatcher.Invoke(() => {
? ? ? ? ? ? ? ? oImage.Source = BitmapSourceConvert.ToBitmapSource(src);
? ? ? ? ? ? });
? ? ? ? }

? ? ? ? private void ShowGrayImage(System.Windows.Controls.Image oImage, Image<Gray, byte> src)
? ? ? ? {
? ? ? ? ? ? this.Dispatcher.Invoke(() => {
? ? ? ? ? ? ? ? oImage.Source = BitmapSourceConvert.ToBitmapSource(src);
? ? ? ? ? ? });
? ? ? ? }

? ? ? ? public MainWindow()
? ? ? ? {
? ? ? ? ? ? InitializeComponent();

? ? ? ? ? ? this.Loaded += MainWindow_Loaded;
? ? ? ? }

? ? ? ? //参考链接 http://blog.csdn.net/gaobobo138968/article/details/47663607
? ? ? ? private void MainWindow_Loaded(object sender, RoutedEventArgs e)
? ? ? ? {
? ? ? ? ? ? string sFile = AppDomain.CurrentDomain.BaseDirectory + "Test.jpg";

? ? ? ? ? ? System.Drawing.Image img = System.Drawing.Image.FromFile(sFile);
? ? ? ? ? ? Bitmap barcodeBitmap = new Bitmap(img);
? ? ? ? ? ? Image<Bgr, byte> img_src = new Image<Bgr, byte>(barcodeBitmap);

? ? ? ? ? ? this.ShowBgrImage(this.Img1, img_src);

? ? ? ? ? ? //灰度化
? ? ? ? ? ? Image<Gray, byte> imput_gray = new Image<Gray, byte>(img_src.Size);
? ? ? ? ? ? CvInvoke.CvtColor(img_src, imput_gray, ColorConversion.Bgr2Gray);
? ? ? ? ? ? this.ShowGrayImage(this.Img2, imput_gray);

? ? ? ? ? ? //计算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.Sobel(imput_gray, grad_x1, DepthType.Default, 0, 1, 3);
? ? ? ? ? ? CvInvoke.Sobel(imput_gray, grad_y1, DepthType.Default, 1, 0, 3);
? ? ? ? ? ? CvInvoke.Add(grad_x1, grad_y1, grad_all, null);
? ? ? ? ? ? this.ShowGrayImage(this.Img3, grad_all);

? ? ? ? ? ? // 高斯模糊
? ? ? ? ? ? grad_all = grad_all.SmoothGaussian(9);
? ? ? ? ? ? this.ShowGrayImage(this.Img4, grad_all);

? ? ? ? ? ? // 二值化
? ? ? ? ? ? CvInvoke.Threshold(grad_all, grad_all, 100, 255, ThresholdType.Binary);
? ? ? ? ? ? this.ShowGrayImage(this.Img5, grad_all);

? ? ? ? ? ? //消除裂缝
? ? ? ? ? ? Mat oMat1 = CvInvoke.GetStructuringElement(Emgu.CV.CvEnum.ElementShape.Rectangle,?
? ? ? ? ? ? ? ? new System.Drawing.Size(15, 15), new System.Drawing.Point(0, 0));
? ? ? ? ? ? CvInvoke.MorphologyEx(grad_all, grad_all, Emgu.CV.CvEnum.MorphOp.Close, oMat1,?
? ? ? ? ? ? ? ? new System.Drawing.Point(0, 0), 1, BorderType.Default,
? ? ? ? ? ? ? ? new MCvScalar(255, 0, 0, 255));
? ? ? ? ? ? this.ShowGrayImage(this.Img6, grad_all);

? ? ? ? ? ? //膨胀与腐蚀(消除杂点)
? ? ? ? ? ? Mat oMat2 = CvInvoke.GetStructuringElement(Emgu.CV.CvEnum.ElementShape.Rectangle,
? ? ? ? ? ? ? ?new System.Drawing.Size(5, 5), new System.Drawing.Point(0, 0));
? ? ? ? ? ? CvInvoke.Erode(grad_all, grad_all, oMat2, new System.Drawing.Point(0, 0), 4,?
? ? ? ? ? ? ? ? BorderType.Default, new MCvScalar(255, 0, 0, 255));
? ? ? ? ? ? CvInvoke.Dilate(grad_all, grad_all, oMat2, new System.Drawing.Point(0, 0), 4,
? ? ? ? ? ? ? ? BorderType.Default, new MCvScalar(255, 0, 0, 255));
? ? ? ? ? ? this.ShowGrayImage(this.Img7, grad_all);

? ? ? ? ? ? //查找轮廓,绘制轮廓
? ? ? ? ? ? #region Find triangles and rectangles
? ? ? ? ? ? List<Triangle2DF> triangleList = new List<Triangle2DF>();
? ? ? ? ? ? List<RotatedRect> boxList = new List<RotatedRect>(); //a box is a rotated rectangle

? ? ? ? ? ? using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint())
? ? ? ? ? ? {
? ? ? ? ? ? ? ? CvInvoke.FindContours(grad_all, contours, null, RetrType.List, ChainApproxMethod.ChainApproxSimple);
? ? ? ? ? ? ? ? int count = contours.Size;
? ? ? ? ? ? ? ? for (int i = 0; i < count; i++)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? using (VectorOfPoint contour = contours[i])
? ? ? ? ? ? ? ? ? ? using (VectorOfPoint approxContour = new VectorOfPoint())
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? CvInvoke.ApproxPolyDP(contour, approxContour, CvInvoke.ArcLength(contour, true) * 0.05, true);
? ? ? ? ? ? ? ? ? ? ? ? if (CvInvoke.ContourArea(approxContour, false) > 500)
? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? if (approxContour.Size == 3)
? ? ? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? System.Drawing.Point[] pts = approxContour.ToArray();
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? triangleList.Add(new Triangle2DF(
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?pts[0],
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?pts[1],
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?pts[2]
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?));
? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? else if (approxContour.Size == 4)
? ? ? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #region determine if all the 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 + 1) % edges.Length].GetExteriorAngleDegree(edges[j]));
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (angle < 80 || angle > 100)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? isRectangle = false;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #endregion
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (isRectangle)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? boxList.Add(CvInvoke.MinAreaRect(approxContour));
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? ? ? //this.Img8.Source = new BitmapImage(new Uri(sFile));
? ? ? ? ? ? this.ShowGrayImage(this.Img8, grad_all);
? ? ? ? ? ? foreach (RotatedRect box in boxList)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? System.Drawing.Point[] pts = Array.ConvertAll(box.GetVertices(), System.Drawing.Point.Round);

? ? ? ? ? ? ? ? for (int i = 0; i < pts.Length; i++)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? System.Drawing.Point point = pts[i];
? ? ? ? ? ? ? ? ? ? System.Drawing.Point point1 = new System.Drawing.Point();
? ? ? ? ? ? ? ? ? ? if (i == pts.Length-1)
? ? ? ? ? ? ? ? ? ? ? ? point1 = pts[0];
? ? ? ? ? ? ? ? ? ? else
? ? ? ? ? ? ? ? ? ? ? ? point1 = pts[i + 1];

? ? ? ? ? ? ? ? ? ? Line oLine = new Line();
? ? ? ? ? ? ? ? ? ? oLine.Stroke = new SolidColorBrush(Colors.Red);
? ? ? ? ? ? ? ? ? ? oLine.StrokeThickness = 5;
? ? ? ? ? ? ? ? ? ? oLine.X1 = point.X;
? ? ? ? ? ? ? ? ? ? oLine.Y1 = point.Y;

? ? ? ? ? ? ? ? ? ? oLine.X2 = point1.X;
? ? ? ? ? ? ? ? ? ? oLine.Y2 = point1.Y;
? ? ? ? ? ? ? ? ? ? this.CvMainZm.Children.Add(oLine);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? #endregion
? ? ? ? }

? ? ?BitmapSourceConvert 类直接使用的SDK中的示例。

原文地址:https://www.cnblogs.com/lonelyxmas/p/9472677.html

时间: 2024-10-27 00:19:38

Emgu-WPF学习使用-识别二维码的位置的相关文章

【咸鱼教程】Egret可长按识别二维码(精确位置和大小)

教程目录一 实现原理二 实现过程三 Demo下载 本教程是在Egret中实现长按识别的二维码,并可以精确定位二维码的位置和大小,支持横屏和竖屏. 一 实现原理 微信中长按识别二维码,需要长按jpg或png等图片上,才会调起识别. 因为egret中的二维码,是绘制在canvas上的,故不能被长按识别. 所以为了解决这个问题,需要在canvas上覆盖一个二维码<img>标签, 达到可以长按识别的需求. 二 实现过程 1 在index.html中为div增加id = gameDiv,以备在egret

Qt+QZXing编写识别二维码的程序

本人最近在用Qt编写程序,需要用编写二维码识别功能.在网上搜寻一番,找到了QZXing.配置过程中确实出了一大把汗,这里我写这篇文章记录配置方法,替后人省一把汗吧!我的开发环境:MSVC2010 + Qt5 从这里下载最新版的QZXing_sourceV2.3.zip,解压之后得到的是源代码,里面有一个QZXing.pri文件.理论上用MSVC加载这个pri文件之后这个库的代码就会出现在工程的代码列表中,但是理论归理论,实际上msvc在加载pri的过程中,弹出一大堆错误信息,完全不知所云,网上找

Android的二维码功能实现以及长按识别二维码

一.初步集成Zxing项目 二维码的识别可是在生活中随处可见的,现在基本上所有APP都有二维码的相关操作,如果识别二维码从头开始开发做起来还是相当复杂和麻烦的,从零开始开发肯定不现实,最好的做法就是借助现有的开源项目,Github上名气最大的就是Zxing了,提供了多个平台的二维码扫码解决方案,开源项目地址是:https://github.com/zxing/zxing,我们今天集成Zxing到我们自己的项目中去,并实现一些二维码生成.扫描.长按识别二维码等相关操作: 1.下载Zxing项目所依

Jquery生成二维码(微信中长按图片识别二维码功能)

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <script type="text/javascript" src="//cdn.bootcss.com/jquery/3.1.1/jquery.js"></script> <script src="

HTML5实现扫描识别二维码/生成二维码

扫描识别二维码 思路: 1. 操作摄像头,获取图片.HTML5 WEBRTC的navigator.getUserMedia方法去实时获取摄像头资源. 2. 利用canvas使用相关算法分析图片识别图片得出结果,可用jquery.qrcode分析二维码 .(技术点:getImageData) 局限性: 移动平台支持getUserMedia/Stream API的浏览器比较少,支持列表http://caniuse.com/#feat=stream (目前没发现有IOS是支持的) 代码实现: 感谢gi

C# ZXing.Net生成二维码、识别二维码、生成带Logo的二维码(一)

一.ZXing.Net 源代码地址:http://zxingnet.codeplex.com/ 也可以使用Nuget包管理,添加如图: 说明:ZXing是一个开源Java类库用于解析多种格式的1D/2D条形码.目标是能够对QR编码.Data Matrix.UPC的1D条形码进行解码. 其提供了多种平台下的客户端包括:J2ME.J2SE和Android.现在也有了对应的.Net版本 二.生成二维码 将字符编码时可以指定字符格式:默认为ISO-8859-1英文字符集,但一般移动设备常用UTF-8字符

unity 调用手机摄像机 识别二维码

简单的调用手机摄像 拍摄 然后识别二维码 显示二维码的内容 需要导入一个zxing.unity.dll文件,现在这个脚本的识别数据是放在Updata里边扫描的 数据量特别大会卡  要是用的话就自己做一下一秒执行一次.我这里没有弄 下载地址http://download.csdn.net/detail/chh19941125/8734149 代码: using System.Threading; using UnityEngine; using ZXing; public class WebCam

在Android用ZXing.jar识别二维码的精简版(简化了配置和代码)

最近公司做了一款OTP令牌激活的产品,由于之前激活手机令牌需要输入很多的激活信息才能进行激活.经过一段使用后,发现易用性不是很强,考虑如果加入二维码的的扫码功能岂不是大大增加了易用性.     在网上搜了很多资料,要不是配置太多,要不就是代码量太大,最后没办法就硬着头皮去写和去精简,最后压缩至目前的版本.如果有更好的版本可以联系我. 具体DEMO可以通过 下载http://download.csdn.net/detail/fugui6611634/7341277下载 本文代码运行的结果如下: 代

PHP识别二维码(php-zbarcode

PHP识别二维码(php-zbarcode) 标签: php二维码扩展 2015-11-06 17:12 609人阅读 评论(0) 收藏 举报  分类: PHP(1)  Linux 版权声明:本文为博主原创文章,未经博主允许不得转载. 说明:扩展需要依赖ImageMagick和zbar,安装前先安装这两个软件 1.安装ImageMagick(http://www.imagemagick.org/) yum install ImageMagick.x86_64 ImageMagick-devel.