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 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> python 图片倾斜校正 -> 正文阅读

[人工智能]python 图片倾斜校正

0. 前言

进行图片校正是将拍照倾斜的图片恢复水平状态,大致思路为:

  1. 用canny算子检测出图像中的边缘轮廓线;
  2. 用霍夫线变换检测出图像中的所有直线;
  3. 筛选出接近水平方向上的直线,求出他们偏移角度的平均值;
  4. 根据倾斜角旋转矫正;
  5. 输出图片。

这里设计到几个知识点:
canny算子
原理:数字图像处理(20): 边缘检测算子(Canny算子)
cv2.Canny函数:OpenCV-Python教程(8、Canny边缘检测)
edge = cv2.Canny(image, threshold1, threshold2[, edges[, apertureSize[, L2gradient ]]])

变量内容
image要检测的图像

threshold1 和 threshold2 的值较小时,能够捕获更多的边缘信息,下文中canny_threshold(self, img_path)函数即可可视化不同threshold的效果。

霍夫变换
原理:霍夫变换——神奇的特征提取算法
cv2.HoughLines函数:每天一练P9-Python和OpenCV做图像处理(HoughLines)

其他
Python2 math.degrees() 函数
Python scipy.ndimage.rotate用法及代码示例(该函数是按逆时针旋转)
利用向量推导坐标旋转公式(方案一)
atctan

1. 代码

在使用代码前,canny的阈值一定要根据实际情况修改!

import cv2
import math
import numpy as np
from scipy import ndimage


class HorizontalCorrection:
    def __init__(self):
        self.rotate_vector = np.array([0, 1])  # 图片中地面的法线向量
        self.rotate_theta = 0  # 旋转的角度

    def process(self, img):
        img = cv2.imread(img)  # 读取图片
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 二值化
        # cv2.imshow('gray', gray)
        # cv2.waitKey()
        edges = cv2.Canny(gray, 350, 400, apertureSize=3)  # canny算子
        cv2.imwrite('./test result/edges.png', edges)
        # cv2.imshow('edges', edges)
        # cv2.waitKey()

        # 霍夫变换
        lines = cv2.HoughLines(edges, 1, np.pi / 180, 120)
        sum = 0
        count = 0
        for i in range(len(lines)):
            for rho, theta in lines[i]:
                a = np.cos(theta)
                b = np.sin(theta)
                x0 = a * rho
                y0 = b * rho
                x1 = int(x0 + 1000 * (-b))
                y1 = int(y0 + 1000 * (a))
                x2 = int(x0 - 1000 * (-b))
                y2 = int(y0 - 1000 * (a))

                if x2 != x1:
                    t = float(y2 - y1) / (x2 - x1)
                    if t <= np.pi / 5 and t >= - np.pi / 5:
                        rotate_angle = math.degrees(math.atan(t))
                        sum += rotate_angle
                        count += 1
                        cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 2)

        if count == 0:
            avg_rotate_angle = 0
        else:
            avg_rotate_angle = sum / count
        self.rotate_img = ndimage.rotate(img, avg_rotate_angle)  # 逆时针旋转
        # cv2.imwrite('./test result/1.png', self.rotate_img)
        # cv2.imshow('rotate', rotate_img)
        # cv2.waitKey()

        self.rotate_theta = avg_rotate_angle  # 向量顺时针旋转公式
        self.count_rotate_vector()

    def count_rotate_vector(self):
        v1_new = (self.rotate_vector[0] * np.cos(self.rotate_theta / 180)) - \
                 (self.rotate_vector[1] * np.sin(self.rotate_theta / 180))
        v2_new = (self.rotate_vector[1] * np.cos(self.rotate_theta / 180)) + \
                 (self.rotate_vector[0] * np.sin(self.rotate_theta / 180))
        self.rotate_vector = np.array([v1_new, v2_new])

    def manual_set_rotate_vector(self, rotate_theta):
        self.rotate_theta = rotate_theta
        self.count_rotate_vector()

    def canny_threshold(self, img_path):
        img_original = cv2.imread(img_path)
        #设置窗口
        cv2.namedWindow('Canny')
        #定义回调函数
        def nothing(x):
            pass
        #创建两个滑动条,分别控制threshold1,threshold2
        cv2.createTrackbar('threshold1','Canny',50,400,nothing)
        cv2.createTrackbar('threshold2','Canny',100,400,nothing)
        while(1):
            #返回滑动条所在位置的值
            threshold1=cv2.getTrackbarPos('threshold1','Canny')
            threshold2=cv2.getTrackbarPos('threshold2','Canny')
            #Canny边缘检测
            img_edges=cv2.Canny(img_original,threshold1,threshold2)
            #显示图片
            cv2.imshow('original',img_original)
            cv2.imshow('Canny',img_edges)
            if cv2.waitKey(1)==ord('q'):
                break
        cv2.destroyAllWindows()


if __name__ == '__main__':
    horizontal_correction = HorizontalCorrection()
    # horizontal_correction.canny_threshold(r'./test image/IMG_6386.JPG')
    horizontal_correction.process(r'./test image/IMG_6386.JPG')
    print(horizontal_correction.rotate_theta)
    cv2.imwrite('./test result/1.png', horizontal_correction.rotate_img)
    cv2.imshow('rotate', horizontal_correction.rotate_img)
    cv2.waitKey()

2. 效果图

在这里插入图片描述

在这里插入图片描述

从图中可以看出霍夫变换根据栏杆的水平线进行校正。

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2022-05-08 08:05:07  更:2022-05-08 08:09:14 
 
开发: 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 6:17:59-

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