首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >OpenCV实现图片批号效期提取

OpenCV实现图片批号效期提取

作者头像
Vaccae
发布2022-04-06 20:48:02
发布2022-04-06 20:48:02
1.1K0
举报
文章被收录于专栏:微卡智享微卡智享

前言

最近正好遇到了一个图片的效期提取,正好当做一个小练习记录一下。

实现效果

左边的大图是截取后的原图,右边是提取后的实际图,然后根据提取出来的再进行OCR识别,识别这块就不再说了,这里只是写一下怎么提取的图片。

#

实现思路

1

转灰度图、高斯模糊

2

Canny边缘提取

3

定义X轴较长的一个卷积进行膨胀操作

4

查找轮廓,找到符合条件的截取出来

01

预处理

读取图像,转为灰度图,然后高斯模糊。

预处理后的图像

02

Canny边缘提取

这里测试后发现使用50,120的阈值效果不错

Canny后的效果

用Canny的边缘提取的效果是最好的,如果考虑图像二值化什么的,效果会差很多,下面是用二值化和自适应二值化后的效果,可以看到都很不理想。

二值化的效果

自适应二值化效果

上面可以看到,正常二值化效果最差,自适应二值化干扰项也很多,Canny边缘提取的效果最好。

03

膨胀操作

其实上图Canny提取后,里面直接就有一个正方形了,可以不需要这一步直接提取轮廓即可,不过再另一张图效果就没有那么好了,比如下面这个。

所以要对上面这个图做一个卷积为(30,5)的膨胀操作,尽量让其都连接起来。

膨胀后的效果

04

查找轮廓

将所有轮廓都查找出来,这里只查找最外侧轮廓就行,然后画出效果

这一步只是看效果的,真正可以用不到,直接判断符合的轮廓提取即行

完整代码

代码语言:javascript
复制
#pragma once
#include <iostream>
#include<opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main(int argc, char** argv) {
  Mat src = imread("E:/DCIM/testdate/pic1.png");

  imshow("src", src);

  Mat gray, dst;
  //转换灰度图
  cvtColor(src, gray, COLOR_BGR2GRAY);
  //高斯模糊
  GaussianBlur(gray, gray, Size(3, 3), 0.5, 0.5);

  imshow("gray", gray);


  //Canny边缘检测
  Canny(gray, dst, 50, 120);
  imshow("Canny", dst);

  Mat dst2;
  //使用膨胀操作,kernel定义的要长一点
  Mat kernel = getStructuringElement(MORPH_RECT, Size(30, 5));
  morphologyEx(dst, dst2, MORPH_DILATE, kernel);

  imshow("morph", dst2);

  //查找轮廓,只找最外侧轮廓
  vector<vector<Point>> contours;
  findContours(dst2, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

  RNG rng(12345);
  Mat dstzero = Mat::zeros(dst2.size(), CV_8UC3);
  for (int i = 0; i < contours.size(); ++i) {
    //判断符合区域
    RotatedRect rRect = minAreaRect(contours[i]);
    Rect rect = rRect.boundingRect();

      Scalar color = Scalar(rng.uniform(0, 255), 
        rng.uniform(0, 255), rng.uniform(0, 255));
      rectangle(dstzero, rect, color);
  }
  imshow("zero", dstzero);

  for (int i = 0; i < contours.size(); ++i) {
    //判断符合区域
    RotatedRect rRect = minAreaRect(contours[i]);
    Rect rect = rRect.boundingRect();
    if (rect.width / rect.height < 2) {
      Mat cutmat = src(rect);
      imshow("dstzero"+i, cutmat);
    }
  }

  waitKey(0);
  return 0;
}

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-02-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 微卡智享 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 完整代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档