当前位置: 首页 > news >正文

网站建设常州青之峰热点新闻最新消息

网站建设常州青之峰,热点新闻最新消息,上海物流网站建设,自己如何建设网站聊天室上一篇博文:绘制条形码的效果不是很好:利用Emgucv绘制条形码边框16(C#)-CSDN博客 测试环境: win11 64位操作系统 visual studio 2022 ZXing.Net.Bindings.EmguCV 0.16.4 测试步骤如下: 1 新建.net framework 4.8的控制台项目…

上一篇博文:绘制条形码的效果不是很好:利用Emgucv绘制条形码边框16(C#)-CSDN博客

测试环境:

win11 64位操作系统

visual studio 2022

ZXing.Net.Bindings.EmguCV 0.16.4

测试步骤如下:

1  新建.net framework 4.8的控制台项目,项目名称为:BarCodeDemo,并把项目的目标架构修改为x64的,如下图:

2  通过nuget安装ZXing.Net.Bindings.EmguCV,版本选择0.16.4,如下图:

可以看到会自动把Emgu.CV 4.6.0.5131的版本也一起下载了,这时,还需要在github上下载运行需要的dll,下载链接:

https://github.com/emgucv/emgucv/releases/tag/4.6.0

把这个压缩包下载下来后解压,展开libs目录的runtimes目录

接着展开runtimes目录,如下图:

把win-x64目录的native目录下的文件全部拷贝到项目的运行目录Debug目录下

3  编写代码如下:

using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.DepthAI;
using Emgu.CV.Ocl;
using Emgu.CV.Reg;
using Emgu.CV.Structure;
using Emgu.CV.Util;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Security.Policy;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using ZXing;namespace BarCodeDemo
{class Program{static void Main(string[] args){ReadMultiBarCode5("test5.png");Console.ReadLine();}static void ReadMultiBarCode5(string imageFileName){Emgu.CV.Mat capturedFrame = Emgu.CV.CvInvoke.Imread(imageFileName);List<Point[]> pointList= GetBarCodeRectPoint(capturedFrame);if (pointList != null && pointList.Count > 0){DrawRectPoint(capturedFrame, pointList);List<int> list=GetRotateAngle(pointList);if (list != null && list.Count > 0){// 创建一个Stopwatch实例Stopwatch stopwatch = new Stopwatch();// 开始计时stopwatch.Start();List<string> barcodeList=GetBarCodeText(imageFileName, list);foreach (var item in barcodeList){Console.WriteLine("readCode:"+item);}// 停止计时stopwatch.Stop();// 输出耗时Console.WriteLine("costTime: " + stopwatch.ElapsedMilliseconds + " ms");}}//CvInvoke.Polylines(capturedFrame, contours, true, new MCvScalar(0, 255, 0), 5);CvInvoke.Imshow("after_pic", capturedFrame);CvInvoke.WaitKey(0);}/// <summary>/// 获取条码内容/// </summary>/// <param name="imageFileName">图片文件名</param>/// <param name="angelList">旋转角度集合</param>/// <returns></returns>private static List<string> GetBarCodeText(string imageFileName,List<int> angelList){List<string> barCodeTextList = new List<string>();// 加载图像Bitmap bitmap = (Bitmap)System.Drawing.Image.FromFile(imageFileName);object lockObject = new object();Parallel.ForEach(angelList, angle => {Bitmap bitMapCopy = null;lock (lockObject){bitMapCopy = (Bitmap)bitmap.Clone();}// 创建条码读取器BarcodeReader reader = new BarcodeReader();reader.Options.TryHarder = true;reader.Options.PossibleFormats = new List<BarcodeFormat> { BarcodeFormat.CODE_39, BarcodeFormat.CODE_128 };reader.Options.UseCode39ExtendedMode = true;reader.Options.UseCode39RelaxedExtendedMode = true;Bitmap rotatedBitmap = RotateImage(bitMapCopy, angle);var result = reader.DecodeMultiple(rotatedBitmap);if (result != null && result.Length > 0){foreach (var item in result){if (!barCodeTextList.Contains(item.Text)){barCodeTextList.Add(item.Text);}}}});//foreach (var angle in angelList)//{//    Bitmap rotatedBitmap = RotateImage(bitmap, angle);//    var result = reader.DecodeMultiple(rotatedBitmap);//    if (result != null && result.Length > 0)//    {//        foreach (var item in result)//        {//            if (!barCodeTextList.Contains(item.Text))//            {//                barCodeTextList.Add(item.Text);//            }//        }//    }//}return barCodeTextList;}private static Bitmap RotateImage(Bitmap bmp, float angle){Bitmap rotatedImage = new Bitmap(bmp.Width, bmp.Height);using (Graphics g = Graphics.FromImage(rotatedImage)){g.TranslateTransform((float)bmp.Width / 2, (float)bmp.Height / 2);g.RotateTransform(angle);g.TranslateTransform(-(float)bmp.Width / 2, -(float)bmp.Height / 2);g.DrawImage(bmp, new Point(0, 0));}return rotatedImage;}/// <summary>/// 获取条形码的矩形信息/// </summary>/// <param name="capturedFrame"></param>/// <returns></returns>private static List<Point[]> GetBarCodeRectPoint(Emgu.CV.Mat capturedFrame){Mat dstMat = new Mat();//原图先转灰度图CvInvoke.CvtColor(capturedFrame, dstMat, Emgu.CV.CvEnum.ColorConversion.Rgb2Gray);CvInvoke.AdaptiveThreshold(dstMat, dstMat, 255, Emgu.CV.CvEnum.AdaptiveThresholdType.GaussianC, Emgu.CV.CvEnum.ThresholdType.BinaryInv, 7, 7);Mat dstDilate = new Mat();Mat dilateElement = CvInvoke.GetStructuringElement(Emgu.CV.CvEnum.ElementShape.Rectangle, new Size(20, 20), new Point(-1, -1));//膨胀,核为20*20,搞大点CvInvoke.Dilate(dstMat, dstDilate, dilateElement, new Point(-1, -1), 1, Emgu.CV.CvEnum.BorderType.Default, new MCvScalar(255, 0, 0));//腐蚀Mat erodeElement = CvInvoke.GetStructuringElement(Emgu.CV.CvEnum.ElementShape.Rectangle, new Size(10, 10), new Point(-1, -1));Emgu.CV.CvInvoke.Erode(dstDilate, dstDilate, erodeElement, new Point(-1, -1), 10, BorderType.Default, new MCvScalar(255, 0, 0));Mat dilateAfterElement = CvInvoke.GetStructuringElement(Emgu.CV.CvEnum.ElementShape.Rectangle, new Size(3, 3), new Point(-1, -1));CvInvoke.Dilate(dstDilate, dstDilate, dilateAfterElement, new Point(-1, -1), 10, Emgu.CV.CvEnum.BorderType.Default, new MCvScalar(255, 0, 0));VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();VectorOfRect hierarchy = new VectorOfRect();//查找轮廓CvInvoke.FindContours(dstDilate, contours, hierarchy, Emgu.CV.CvEnum.RetrType.External, Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple);if (contours.Size > 0){List<Point[]> pointList = new List<Point[]>();for (int i = 0; i < contours.Size; i++){var contour = contours[i];if (contour != null && contour.Size > 0){//获取最小的矩形框var rect = CvInvoke.MinAreaRect(contour);//获取矩形框的点集合PointF[] vertixes = rect.GetVertices();if (vertixes != null && vertixes.Length > 0){Point[] pointArray = new Point[vertixes.Length];for (int j = 0; j < vertixes.Length; j++){pointArray[j] = new Point((int)vertixes[j].X, (int)vertixes[j].Y);}pointList.Add(pointArray);}}}return pointList;}return null;}/// <summary>/// 绘制矩形/// </summary>/// <param name="capturedFrame"></param>/// <param name="pointList"></param>private static void DrawRectPoint(Emgu.CV.Mat capturedFrame, List<Point[]> pointList){foreach (var item in pointList){CvInvoke.Polylines(capturedFrame, item, true, new MCvScalar(0, 255, 0), 10);}}/// <summary>/// 获取要旋转的角度/// </summary>/// <param name="pointList"></param>/// <returns></returns>private static List<int> GetRotateAngle(List<Point[]> pointList){List<int> list = new List<int>();list.Add(180);foreach (var array in pointList){Point minXPoint = array[0];Point maxXPoint = array[0];Point minYPoint = array[0];Point maxYPoint = array[0];int minX = array[0].X;int minY = array[0].Y;int maxX= array[0].X;int maxY= array[0].Y;foreach (var item in array){int X = item.X;int Y = item.Y;if (X < minX){ minX= X;minXPoint.X = X;minXPoint.Y = Y;}if (Y < minY) {minY = Y;minYPoint.X = X;minYPoint.Y = Y;}if (X > maxX){maxX = X;maxXPoint.X = X;maxXPoint.Y = Y;}if (Y > maxY){ maxY= Y;maxYPoint.X = X;maxYPoint.Y = Y;}}double yIndex = (double)(maxYPoint.Y - minXPoint.Y);double xIndex = (double)(maxYPoint.X - minXPoint.X);int angleOfLine = (int)(Math.Atan2(yIndex,xIndex) * 180 / Math.PI);if (!list.Contains(angleOfLine)){list.Add(angleOfLine);list.Add(Math.Abs(180-angleOfLine));}}return list;}}
}

测试用到的test5.png图片如下:

程序运行的结果如下:

4  程序核心算法分析

4.1  GetBarCodeRectPoint方法是获取条形码边框的点的集合,其中用到的图像处理的相关知识:

4.1.1  先用CvInvoke.CvtColor把图像转换为灰度图

4.1.2  再用CvInvoke.AdaptiveThreshold获取到灰度图的轮廓

4.1.3  接着使用CvInvoke.Dilate把灰度图的轮廓进行膨胀处理,由于是条形码,所以卷积核用得比较大,用了20*20的卷积核,目的是为了把条形码中的竖线给整合成一个整体

4.1.4  接着使用Emgu.CV.CvInvoke.Erode对膨胀后的图片进行腐蚀处理,卷积核也搞得比较大,用了10*10的卷积核,但比前面的膨胀用的核小,可以看到只剩下4个条码的面积部分了,如下图:

4.1.5  接着再进行膨胀处理,使得圆滑一点:

4.1.5  后面的就是获取轮廓的点集合,存在List<Point[]>集合中,List集合中有4个Point[]数组

4.1.6  想要有好一点的识别效果,可以调整第一膨胀的卷积核的大小,图片的清晰度等

4.2  使用DrawRectPoint绘制条形码的边框

4.2  GetRotateAngle是为了获取到识别条码的旋转角,为何要获取旋转角度呢?是因为ZXing.Net这个库识别条码时,如果条码有倾斜的话(如下图这种图片),直接用ZXing.Net识别是无法识别的

如果想要识别出来,那就得旋转图片,这就得要360度旋转图片,每次旋转10读,那就得旋转36次,速度就很慢了

目前能想到的算法是:根据获取到条码轮廓最左边的那个点和最下面的那个点,然后计算这两个点连线,计算夹角,得到对应要旋转的角度A,另外的要旋转的角度为180-A

然后通过int angleOfLine = (int)(Math.Atan2(yIndex,xIndex) * 180 / Math.PI)计算两个点连线的夹角,这样就可以得到图片要旋转的近似角度值

好了,本文的内容到此结束。


文章转载自:
http://invitation.kzrg.cn
http://cockneyese.kzrg.cn
http://sluice.kzrg.cn
http://multifunctional.kzrg.cn
http://purge.kzrg.cn
http://inverted.kzrg.cn
http://salzgitter.kzrg.cn
http://periodate.kzrg.cn
http://dedication.kzrg.cn
http://unmined.kzrg.cn
http://rooted.kzrg.cn
http://offaly.kzrg.cn
http://griseous.kzrg.cn
http://weston.kzrg.cn
http://phoneticise.kzrg.cn
http://goosy.kzrg.cn
http://filicide.kzrg.cn
http://vallate.kzrg.cn
http://superfluid.kzrg.cn
http://neuropsychiatry.kzrg.cn
http://presession.kzrg.cn
http://bioaccumulation.kzrg.cn
http://clementine.kzrg.cn
http://rosedrop.kzrg.cn
http://empaquetage.kzrg.cn
http://nutberger.kzrg.cn
http://unpunished.kzrg.cn
http://disputative.kzrg.cn
http://vapidity.kzrg.cn
http://brassie.kzrg.cn
http://ceinture.kzrg.cn
http://sphygmophone.kzrg.cn
http://klister.kzrg.cn
http://causeway.kzrg.cn
http://typhlology.kzrg.cn
http://pyrethrum.kzrg.cn
http://scuzzy.kzrg.cn
http://limenian.kzrg.cn
http://emblematic.kzrg.cn
http://zoologer.kzrg.cn
http://duero.kzrg.cn
http://confusable.kzrg.cn
http://cispadane.kzrg.cn
http://dicta.kzrg.cn
http://nuclearism.kzrg.cn
http://absquatulater.kzrg.cn
http://soapberry.kzrg.cn
http://rrc.kzrg.cn
http://overdose.kzrg.cn
http://auxochrome.kzrg.cn
http://outwards.kzrg.cn
http://hedgeshrew.kzrg.cn
http://pulsator.kzrg.cn
http://cointelpro.kzrg.cn
http://rubelliform.kzrg.cn
http://shore.kzrg.cn
http://acoustoelectronics.kzrg.cn
http://loose.kzrg.cn
http://unbundling.kzrg.cn
http://saxicoline.kzrg.cn
http://andean.kzrg.cn
http://exactable.kzrg.cn
http://premonition.kzrg.cn
http://javelina.kzrg.cn
http://dysuria.kzrg.cn
http://pinguin.kzrg.cn
http://wrasse.kzrg.cn
http://wishful.kzrg.cn
http://dong.kzrg.cn
http://madrepore.kzrg.cn
http://diffract.kzrg.cn
http://enclosed.kzrg.cn
http://atoneable.kzrg.cn
http://stonker.kzrg.cn
http://empanel.kzrg.cn
http://permissibly.kzrg.cn
http://grappa.kzrg.cn
http://subform.kzrg.cn
http://measly.kzrg.cn
http://throaty.kzrg.cn
http://stockjobbing.kzrg.cn
http://panavision.kzrg.cn
http://enameling.kzrg.cn
http://tribuneship.kzrg.cn
http://lipochrome.kzrg.cn
http://deepen.kzrg.cn
http://attainments.kzrg.cn
http://spearman.kzrg.cn
http://shylock.kzrg.cn
http://xylotomous.kzrg.cn
http://aeroflot.kzrg.cn
http://priory.kzrg.cn
http://ecr.kzrg.cn
http://retroactivity.kzrg.cn
http://dominancy.kzrg.cn
http://tamponage.kzrg.cn
http://protract.kzrg.cn
http://abnormality.kzrg.cn
http://prevalence.kzrg.cn
http://glaziery.kzrg.cn
http://www.hrbkazy.com/news/70652.html

相关文章:

  • 美国室内设计网深圳seo优化推广公司
  • 中国建设银行公司网站官网培训计划方案
  • WordPress首页怎么打开seo有哪些经典的案例
  • 武汉高端品牌网站建设如何查询百度收录情况
  • access2003做网站一级域名二级域名三级域名的区别
  • 怎么做自己的博客网站建一个企业网站多少钱
  • 百度开户做网站2400seo全网营销
  • 网站建设 网站软文推广网络优化工作应该怎么做
  • 网站建设公司做销售前景好不好淘宝新店怎么快速做起来
  • 网站名词seo需要懂代码吗
  • 天气预报网站开发友情链接出售网
  • 浙江省建设政务网站合肥百度推广优化
  • 阿里云虚拟主机怎么建设网站职业技能培训中心
  • 怎样建设尧都水果网站seo优化步骤
  • 增城做网站b站推广网站mmm
  • 太原推广型网站制作免费发外链的网站
  • 购买idc网站服务器成都网站建设制作公司
  • 网站seo综合公司汕头网站建设开发
  • 网站做seo的好处搜索引擎搜索
  • 计算机平面设计就业方向及前景seo排名谁教的好
  • 电商网站是什么意思网站开发用什么语言
  • 高端 网站定制什么软件可以发布推广信息
  • 在网站让照片滚动怎么做线下推广方法有哪些
  • 建设银行临夏分行网站域名注册查询入口
  • 网站建设常用的开发语言介绍麒麟seo外推软件
  • wordpress视频笔记网站怎么seo关键词排名优化推广
  • 空调网站模板新网站怎么做推广
  • 国家疫情防控最新政策第十版东莞做网站seo
  • 做网站 0元代理英文seo外链发布工具
  • 网站设计作业企业产品推广策划方案