赞
踩
“ 由于项目中需要用到图片识别来获取图片的金额,本文主要介绍如何用OpenCv库来处理图片,识别到所需的内容以及处理内部干扰。”
需要引用的Dll如下所示:
使用场景介绍:1.解决背景颜色和文字颜色差异较大
2.目标数字背景有干扰线的情况
3.目标数字文本模糊的情况
4.目标文本数字之间靠拢过近情况
本文以数字背景存在干扰线情况做介绍,如下:
1. 图像灰度处理
图像灰度处理适用于背景颜色比较深的情况,能够有效的区分识别内容和背景
图像灰度前:
图像灰度后:
图像灰度化(内存法,速度最快)处理流程:
1. 通过截图宽高新建矩形获取要锁定的bitmap部分
Rectangle rect = new Rectangle(0, 0, wide, height)
2.将Bitmap锁定到系统内存中,获得BitmapData
- BitmapData srcBmData = srcBitmap.LockBits(rect,ImageLockMode.ReadWrite,
- PixelFormat.Format24bppRgb);
3.通过灰度化方法创建Bitmap
- Bitmap dstBitmap = CreateGrayscale(wide, height); //此方法用于创建灰度图
- BitmapData dstBmData = dstBitmap.LockBits(rect,ImageLockMode.ReadWrite,
- PixelFormat.Format8bppIndexed);
- IntPtr srcPtr = srcBmData.Scan0;
- IntPtr dstPtr = dstBmData.Scan0;
4.将Bitmap对象的信息存放到byte数组中
- int src_bytes = srcBmData.Stride * height;
- byte[] srcValues = new byte[src_bytes];
- int dst_bytes = dstBmData.Stride * height;
- byte[] dstValues = new byte[dst_bytes];
5.复制GRB信息到byte数组
- Marshal.Copy(srcPtr, srcValues, 0, src_bytes);
- Marshal.Copy(dstPtr, dstValues, 0, dst_bytes);
- for (int i = 0; i < height; i++)
- for (int j = 0; j < wide; j++)
- {
- //根据根据RGB彩色和亮度的计算公式:Y=0.299*R+0.114*G+0.587B,Y为亮度
- //注意位图结构中RGB按BGR的顺序存储
- int k = 3 * j;
- byte temp = (byte)(srcValues[i * srcBmData.Stride + k + 2] * .299
- + srcValues[i * srcBmData.Stride + k + 1] * .587
- + srcValues[i * srcBmData.Stride + k] * .114);
- dstValues[i * dstBmData.Stride + j] = temp;
- }
- Marshal.Copy(dstValues, 0, dstPtr, dst_bytes);
6.解锁位图
- srcBitmap.UnlockBits(srcBmData);
- dstBitmap.UnlockBits(dstBmData);
图像灰度:
- public static Bitmap CreateGrayscale(int width, int height) {
- Bitmap bmp = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
- // 将调色板设置为灰度
- if (srcImg.PixelFormat != PixelFormat.Format8bppIndexed)
- throw new ArgumentException();
- ColorPalette cp = srcImg.Palette;
- for (int i = 0; i < 256; i++) {
- cp.Entries[i] = Color.FromArgb(i, i, i);
- }
- srcImg.Palette = cp;
- return bmp;
- }
图像灰度反转:
- public static Bitmap GrayReverse(Bitmap bmp) {
- for (int i = 0; i < bmp.Width; i++) {
- for (int j = 0; j < bmp.Height; j++) {
- //获取该点的像素的RGB的颜色
- Color color = bmp.GetPixel(i, j);
- Color newColor = Color.FromArgb(255 - color.R, 255 - color.G, 255 - color.B);
- bmp.SetPixel(i, j, newColor);
- }
- }
- return bmp;
- }
2. 图像模糊处理
先灰度处理:
模糊处理前:
模糊处理后:
- private static Mat Blur(Mat src, int kernalSize) {
- var dst = new Mat();
- //图像平滑操作,使用OpenCvSharp.Blur均值滤波处理
- Cv2.Blur(src, dst, new OpenCvSharp.Size(kernalSize, kernalSize));
- return dst;
- }
参数解释:
kernalSize:表示滤波处理值,范围0~10
Src:表示InputArray类型的src,输入图像,即源图像,填Mat类的对象即可
Dst:表示OutputArray类型的dst,即目标图像,需要和源图片有一样的尺寸和类型
new OpenCvSharp.Size(kernalSize, kernalSize):表示进行均值滤波的方框大小
3. 图像颜色加强处理
颜色加深处理前:
颜色加深处理后:
- private static Mat Threshold(Mat src, int thresh) {
- var dst = new Mat();
- Cv2.CvtColor(src, src, ColorConversionCodes.BGR2GRAY, 0);//转灰度图
- //对图像进行二值化处理
- _ = Cv2.Threshold(src, dst, thresh, 255, ThresholdTypes.Binary);
- return dst;
- }
Src-源图片
Dst-处理后的图
Thresh-阈值
255-填充色,取值范围0~255
ThresholdTypes.Binary-阈值类型
常用的有:
• cv2.THRESH_BINARY(黑白二值)
• cv2.THRESH_BINARY_INV(黑白二值反转)
• cv2.THRESH_TRUNC (得到的图像为多像素值)
• cv2.THRESH_TOZERO
• cv2.THRESH_TOZERO_INV
4. 图片内容识别
调用OPencv库OcrPredict方法识别内容:
[DllImport("opencv_lite340.dll", EntryPoint = "ocrPredict", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
public static extern int OcrPredict(byte[] src, int srclen, byte[] dst, int dstlen);
参数解释:
Src:图片的byte类型对象
SrcLength: 图片数据大小
Dst:处理数据的数组
Dstlength:处理数组的大小
部分代码如下:
- public bool Predict(byte[] data, out string str) {
- str = string.Empty;
- var array = new byte[64];
- var ocrNum = OcrPredict(data, data.Length, array, array.Length);
- if (ocrNum != 0) {
- this.Warn($"OCR识别错误,OcrPredict={ocrNum}");
- return false;
- }
- // 找到字符串结尾的\0
- var indexLast = Array.IndexOf<byte>(array, 0);
- str = Encoding.UTF8.GetString(array, 0, indexLast);
- return true;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。