图像自动裁剪和角度矫正

引言

在做图像处理方面的毕设,希望在正式处理图像之前先把图像处理得比较“正”,比如对下面的图片,希望它是堂正的,就不用歪着头看。所以用python的cv库写了一个自动矫正的程序。
在这里插入图片描述

注意

:为了让图像和背景尽量区别,最好使用纯黑的背景(比如黑衣服,还能吸光)

步骤

1.提取目标的边界,比如课本
2.将边界之内的部分填充白色,那么这张图片就变成了掩码
3.根据掩码,将原来的图片扣到新的图片里
4.根据边界的轮廓得到它的最小外接矩形
5.根据矩形的偏斜角度,旋转图像

代码

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
import cv2

def correctImage(path):
    img = cv2.imread('test2.bmp')
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    """将图片转化成二值图像"""
    ret, binary = cv2.threshold(gray,100,255,cv2.THRESH_BINARY)  
    """
    *** cv2.finContours 函数能求取图像的边界,
    返回的第一个值是用list存储的边界的数组每个边界又有多个点来组成
    *** cv2.RETR_EXTERNAL 参数的含义是仅求取外围的边界
    """
    contours, hierarchy = cv2.findContours(binary,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)  
    """
    *** 下面的循环遍历了边界,找到含有最多点的那个边界的下标
    *** 这是我观察发现的(没有科学的论证),有其中一个边界的点是最多的,基本能通过这个边界画出物体的轮廓
    """
    m = 0;index = 0
    for i in range(len(contours)):
        if len(contours[i]) > m:
            m = len(contours[i])
            index = i
    """
    *** cv2.minAreaRect 函数能根据点集求最小的外接矩形
    (rect, rect[0] = 矩形中心, rect[1] = 矩形长和宽, rect[3] = 矩形的角度)
    角度的大小是[0,90], 表示的是x轴逆时针旋转到与rect的一边重合的角度,重合的那条边是举行的宽。
    """
    rect = cv2.minAreaRect(contours[index])
    """
    *** cv2.drawContours(  #函数能将边界画到图像里
        binary,            #第一个参数是目标图像
        contours=contours, #边界集
        contourIdx=-1,     #选择的边界的序号,-1表示选择集合内的所有的边界
        thickness=-1,      #表示边界内的图形的填充方式,-1表示filled方式,也就是填满颜色
        color=(255) )      #表示填充的颜色,255表示填充白色
    """
    dst = np.zeros((img.shape))
    cv2.drawContours(binary,contours=contours,contourIdx=-1,color=(255),thickness=-1)
    """
    cv2.copyTo(src,mask) 根据mask(掩码)来将img填充到dst
    """
    dst = cv2.copyTo(img,binary)
    """
    *** cv2.getRotationMatrix2D( #根据输入的参数,返回旋转矩阵(因为对图像的旋转操作是采用的矩阵相乘)
        centry, #旋转中心
        angel,  #旋转角度
        scale   #缩放
    )
    *** cv2.warpAffine(对图像进行旋转和缩放
        1st, #输入图像
        2sc, #旋转矩阵
        3rd, #输出图像大小
        4th, #输出
        5th, #flag
        6th  #填充颜色
    )
    """
    angel = abs(rect[2])
    if angel > 60:
        angel = 90 - angel
    mat = cv2.getRotationMatrix2D(rect[0],angel, 1)
    rotimg = np.zeros((img.shape))
    rotimg = cv2.warpAffine(dst,mat,(img.shape[1],img.shape[0]),rotimg,1,0)
    
    im1 = img
    im2 = binary
    im3 = dst
    im4 = rotimg
    plt.subplot(2,2,1),plt.title('source')
    plt.imshow(im1,)
    plt.subplot(2,2,2),plt.title('contours')
    plt.imshow(im2,'gray')
    plt.subplot(2,2,3),plt.title('cppyTo')
    plt.imshow(im3)
    plt.subplot(2,2,4),plt.title('final')
    plt.imshow(im4)
    plt.show()

correctImage('')

结果

第一张是原图,第二张是提取到的源码
第三张是根据掩码得到的填充
第四章是最终的旋转后的图形
左下角有一点缺陷,如果多几个灯光应该可以改正,总体效果还可以
在这里插入图片描述

参考

https://www.cnblogs.com/skyfsm/p/6902524.html

  • 3
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值