脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|shell|

服务器之家 - 脚本之家 - Python - Python OpenCV实现任意角度二维码矫正

Python OpenCV实现任意角度二维码矫正

2023-02-23 11:55水中加点糖 Python

这篇文章主要为大家详细介绍了如何利用Python OpenCV实现任意角度的二维码快速矫正,文中的示例代码讲解详细,感兴趣的小伙伴可以尝试一下

前言

那天听到领导他们在讨论,说要将图片进行个矫正处理,还叫来了算法部的大佬来讨论将要如何处理这个,讨论场面很是激烈

不得不说好奇心是个很神奇的东西,就把我给吸引过去了

我定眼一看,感觉作为JAVA开发的我自己也能进行处理

因为看到了图片后,发现了图片中一个很重要的特征点:

要进行矫正的图片中都会有一个二维码图案,想要矫正的文字和二维码图案是处于同一水平线的。

如下面这个

Python OpenCV实现任意角度二维码矫正

要把图片中的“水中加点糖”四个字矫正,只需要把二维码矫正就可以了。

具体想法就是,求得二维码矫正的角度a,对原图整体按照角度a进行旋转就可以了。

有了想法后,就趁热打铁,正好周末了在家试试。

 

一般图片矫正方式

对于一般的图片矫正,最常见的做法有这么两种:

对图片进行预处理获取出轮廓,并求得轮廓的近似矩形,通过矩形的定位点来进行透视变换

对图片进行预处理后,进行霍夫变换进行直线检测,再根据直线的倾斜角进行旋转

但是对于图片中有二维码的图片进行矫正就可以更加简单了,因为二维码中有定位点并且成熟框架很多,实现起来也更加方便且识别率非常高。

 

二维码图片矫正

思路

识别出二维码的角点,通过相邻两个角点的坐标计算出夹角度数,再次用此度数对图片进行旋转。

以下面图为例:

Python OpenCV实现任意角度二维码矫正

先获取出二维码正方向时底部的两点坐标,并求得两点的倾斜角。

斜率计算用初中数学中求两点坐标斜率的公式算一下即可,忘了就搜搜回忆一下:

两点的斜率公式:k=(y1-y2)/(x1-x2),x1≠x2。其中(x1,y1),(x2,y2)是已知两点的坐标,x1≠x2。

斜率是表示一条直线(或曲线的切线)关于(横)坐标轴倾斜程度的量。它通常用直线(或曲线的切线)与(横)坐标轴夹角的正切,或两点的纵坐标之差与横坐标之差的比来表示。记作k,k=tgα。

一条直线与某平面直角坐标系横坐标轴正半轴方向所成的角的正切值即该直线相对于该坐标系的斜率。如果直线与x轴互相垂直,直角的正切值为tan90,故此直线不存在斜率(也可以说直线的斜率为无穷大)。当直线L的斜率存在时,对于一次函数y=kx+b(斜截式),k即该函数图像的斜率。

编码实现

实现时对于二维码的识别用到了pyzbar库,对图片处理用的opencv包

"""
author: puhaiyang
blog: https://blog.csdn.net/puhaiyang
github: https://github.com/puhaiyang
"""
import math
import cv2
from pyzbar import pyzbar
import imutils


def azimuthangle(x1, y1, x2, y2):
  """ 已知两点坐标计算角度 -
  :param x1: 原点横坐标值
  :param y1: 原点纵坐标值
  :param x2: 目标点横坐标值
  :param y2: 目标纵坐标值
  """
  dx = x2 - x1
  dy = y2 - y1
  # 求斜率
  k = dy / dx
  # 结果是弧度值
  angle = math.atan(k)
  # 弧度值转为角度
  return angle * 180 / math.pi


def get_angle(qr_item):
  """
  获取出进行矫正所需要的角度
  """
  # 将坐标从下到上,从左到右进行排序
  locs = {qr_item.polygon[0], qr_item.polygon[1], qr_item.polygon[2], qr_item.polygon[3]}
  locs = sorted(locs, key=lambda x: x.y * 100000 + x.x * 1000)
  return azimuthangle(locs[2].x, locs[2].y, locs[3].x, locs[3].y)


def to_up_angle(qr_item):
  """
  获取出使二维码朝上的角度
  """
  if qr_item.orientation == 'UP':
      angle_ext = 0
  elif qr_item.orientation == 'RIGHT':
      angle_ext = 270
  elif qr_item.orientation == 'DOWN':
      angle_ext = 180
  else:
      angle_ext = 90
  return angle_ext


def resize_img(ori_img):
  """
  图片压缩
  """
  height = ori_img.shape[0]
  width = ori_img.shape[1]
  # 执行压缩,按照500的宽度为标准
  if width > 500:
      scale_percent = int(500 / width * 100)
      s_width = int(width * scale_percent / 100)
      s_height = int(height * scale_percent / 100)
      # 新的宽度和高度
      dim = (s_width, s_height)
      return cv2.resize(ori_img, dim, interpolation=cv2.INTER_AREA)
  else:
      return ori_img


def adjust_rotae_angle(img):
  angle = 0
  # 对图片进行压缩
  img = resize_img(img)
  # symbol为64代表二维码
  qr_result = pyzbar.decode(img, symbols=[64])
  if len(qr_result) == 1:
      # 识别到了一个二维码,将二维码朝上旋转
      first_adjust_angle = to_up_angle(qr_result[0])
      # 进行旋转
      img_rotae_to_up = imutils.rotate_bound(img, first_adjust_angle)
      # 再次识别
      qr_result2 = pyzbar.decode(img_rotae_to_up, symbols=[64])
      if len(qr_result2) == 1:
          last_adjust_angle = -get_angle(qr_result2[0])
          angle = first_adjust_angle + last_adjust_angle
          print("first angle:%d last angle:%d angle:%d" % (first_adjust_angle, last_adjust_angle, angle))
      else:
          print('last 未识别到二维码')
  else:
      print('first 未识别到二维码')
  return angle


if __name__ == '__main__':
  # 加载图片
  img = cv2.imread('123.jpg')
  adjust_angle = adjust_rotae_angle(img.copy())
  if adjust_angle != 0:
      img_rotae = imutils.rotate_bound(img, adjust_angle)
      cv2.imwrite('img_rotae.jpg', img_rotae)

最终输出的图片结果:

Python OpenCV实现任意角度二维码矫正

矫正成功!

需要说明的是,上面之所以要进行对图片的resize,是因为图片太大的话pyzbar可能会识别不出来二维码

到此这篇关于Python OpenCV实现任意角度二维码矫正的文章就介绍到这了,更多相关Python OpenCV二维码矫正内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/puhaiyang/article/details/125033101

延伸 · 阅读

精彩推荐
  • PythonPytorch模型转onnx模型实例

    Pytorch模型转onnx模型实例

    今天小编就为大家分享一篇Pytorch模型转onnx模型实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧 ...

    joey.lei53922020-04-21
  • Pythonpython链接oracle数据库以及数据库的增删改查实例

    python链接oracle数据库以及数据库的增删改查实例

    下面小编就为大家分享一篇python链接oracle数据库以及数据库的增删改查实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    浅颜半夏11052021-01-10
  • PythonPython实现以时间换空间的缓存替换算法

    Python实现以时间换空间的缓存替换算法

    缓存是指可以进行高速数据交换的存储器,它先于内存与CPU交换数据,因此速度很快。缓存就是把一些数据暂时存放于某些地方,可能是内存,也有可能硬...

    Python教程网5592020-08-13
  • Python定制FileField中的上传文件名称实例

    定制FileField中的上传文件名称实例

    下面小编就为大家带来一篇定制FileField中的上传文件名称实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    linxiyue3942020-12-03
  • PythonOpenCV HSV颜色识别及HSV基本颜色分量范围

    OpenCV HSV颜色识别及HSV基本颜色分量范围

    这篇文章主要介绍了OpenCV HSV颜色识别及HSV基本颜色分量范围,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    Taily老段6682021-06-08
  • PythonPython词法结构

    Python词法结构

    这篇文章主要介绍了Python词法结构,变量是一种存储数据的载体,也就是一个容器。计算机中的变量是实际存在的数据或者说是存储器中存储数据的一块内...

    一碗周9272022-02-21
  • PythonPython pyecharts绘制折线图详解

    Python pyecharts绘制折线图详解

    pyecharts是一个由百度开源的数据可视化,凭借着良好的交互性,精巧的图表设计,得到了众多开发者的认可。本文将利用其绘制折线图,需要的可以参考一...

    渴望成为寂寞胜者9652022-11-21
  • PythonPython爬虫文件下载图文教程

    Python爬虫文件下载图文教程

    在本篇内容里小编给大家分享的是关于Python爬虫文件下载的相关知识点内容,有需要的朋友们学习下。...

    fangjun123fj10742021-05-06