IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> opencv快速实现任意角度二维码矫正 -> 正文阅读

[人工智能]opencv快速实现任意角度二维码矫正

作者:token keyword

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

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

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

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

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

如下面这个

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

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

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

一般图片矫正方式

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

  • 对图片进行预处理获取出轮廓,并求得轮廓的近似矩形,通过矩形的定位点来进行透视变换
  • 对图片进行预处理后,进行霍夫变换进行直线检测,再根据直线的倾斜角进行旋转

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

二维码图片矫正

思路

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

以下面图为例:
示例过程

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

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

两点的斜率公式: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)

最终输出的图片结果:
最终图片
矫正成功!

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

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2022-06-01 15:13:42  更:2022-06-01 15:14:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 4:46:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码