美文网首页
openCV-python(二)图像的几何变换-旋转、缩放

openCV-python(二)图像的几何变换-旋转、缩放

作者: 一杯海风_3163 | 来源:发表于2020-05-20 18:57 被阅读0次

    openCV函数介绍

    cv2的getRotationMatrix2D函数,通过将旋转的中心点坐标,旋转的角度,缩放比例作为参数传入即可得到中间旋转矩阵,warpAffine函数将通过这个矩阵,计算出旋转缩放后的图像,以及坐标(坐标单独有函数进行处理)

    # 例子
        M = cv2.getRotationMatrix2D((w * 0.5, h * 0.5), angle, scale)
        new_image = cv2.warpAffine(Image, M, (int(math.ceil(nw)), int(math.ceil(nh))))
    

    一、旋转和缩放介绍

    图像旋转根据角度不同,有不同的处理,因为旋转角度小于90°,图像的四角坐标会改变,但顺序不会变化,保持左上-右上-右下-左下的顺序。但假如旋转的角度为90°,180°,或者270°,都不仅会改变坐标的值,而且会改变图像原来四个角坐标的顺序。这个特点在做图像增强处理的时候是要特别注意的,尤其在处理增强后的图像坐标的时候。
    下面关于缩放的介绍内容来自中文手册:
    http://woshicver.com/FifthSection/4_2_%E5%9B%BE%E5%83%8F%E5%87%A0%E4%BD%95%E5%8F%98%E6%8D%A2/

    缩放只是调整图像的大小。为此,OpenCV带有一个函数cv.resize()。图像的大小可以手动指定,也可以指定缩放比例。也可使用不同的插值方法。首选的插值方法是cv.INTER_AREA用于缩小,cv.INTER_CUBIC(慢)和cv.INTER_LINEAR用于缩放。默认情况下,出于所有调整大小的目的,使用的插值方法为cv.INTER_LINEAR。

    本次将旋转和缩放合并在一起,有两个重点需要注意:

    1.获得旋转和缩放后的图像
    2.获得旋转和缩放后的坐标

    代码示例
    import cv2
    import math
    import random
    import numpy as np
    import matplotlib.pyplot  as plt
    from PIL import Image, ImageFont,ImageDraw
    
    
    def rotate_bound(Image,total_points_list):
        '''图片倾斜,缩放'''
        angle = random.choice([random.randint(0,45),90,180,270])  # 获取随机旋转角度
        # 随机缩放
        scale = 1
        if random.randint(0,1)==0: # 不进行缩放
            pass
        else:
            scale=round(random.uniform(0.5,1.5),1) # 缩放因子
    
        w = Image.shape[1]
        h = Image.shape[0]
        rangle = np.deg2rad(angle)
        nw = (abs(np.sin(rangle) * h) + abs(np.cos(rangle) * w)) * scale
        nh = (abs(np.cos(rangle) * h) + abs(np.sin(rangle) * w)) * scale
        M = cv2.getRotationMatrix2D((w * 0.5, h * 0.5), angle, scale)
        nw = max(w, nw)
        nh = max(h, nh)
        M[0, 2] += (nw - w) / 2
        M[1, 2] += (nh - h) / 2
        new_image = cv2.warpAffine(Image, M, (int(math.ceil(nw)), int(math.ceil(nh))))
        if angle<=45:
            # 获取变换后的坐标
            total_points_list =get_points(total_points_list,M)
    
    
        elif angle==90:
            total_points_list = get_points(total_points_list, M)
            for i in total_points_list:
                i[0], i[1],i[2], i[3],i[4], i[5],i[6], i[7] =i[2], i[3],i[4], i[5],i[6], i[7], i[0], i[1]
    
    
    
        elif angle==180:
            total_points_list = get_points(total_points_list, M)
            for i in total_points_list:
                i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7] = i[4], i[5],i[6], i[7],i[0], i[1],i[2], i[3]
    
    
        elif angle==270:
            total_points_list = get_points(total_points_list, M)
            for i in total_points_list:
                i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]= i[6], i[7],i[0], i[1],i[2], i[3],i[4], i[5]
    
    
        return new_image,total_points_list
    
    
    def get_points(points_list, M):
        '''坐标转换'''
        for i in points_list:
            i[0], i[1] = [int(i) for i in list(np.dot(M, np.array([i[0], i[1], 1])))]
            i[2], i[3] = [int(i) for i in list(np.dot(M, np.array([i[2], i[3], 1])))]
            i[4], i[5] = [int(i) for i in list(np.dot(M, np.array([i[4], i[5], 1])))]
            i[6], i[7] = [int(i) for i in list(np.dot(M, np.array([i[6], i[7], 1])))]
    
        return points_list
    
    if __name__ == '__main__':
        image = cv2.imread('../myimages/1.jpg')
        # 图片原来的固有字段的坐标及值
        points_list = []
        # 这里txt文本的每行格式为      x1,y2,x2,y2,x3,y3,x4,y4,0,'文本内容'       其中前面8个点为该文本内容的顺时针四个点的坐标,第一个为左上角
        with open('../myimages/gt_1.txt','r',encoding='utf-8') as f:
            for line in f.readlines():
                # 获取前8个元素,也就是四点坐标,后面的是文本内容,可以不用变
                data_line = line.split(',')
                # 将列表中坐标元素变成int
                data =  [ int(i) if data_line.index(i)<=7  else i for i in data_line]
                points_list.append(data)
    
        # 开始旋转
        new_image,points_list = rotate_bound(image,points_list)
        # 将新的图片写在本地
        cv2.imwrite('new_image.jpg',new_image)
        # 将新的坐标也写在本地
        f = open('new_image.txt', 'w', encoding='utf-8')
    
        for lab in points_list:
            line = ",".join(str(i) for i in lab)
            f.write(line)
            f.write('\n')
        f.close()
    
        # 也可以在窗口查看效果
    
        plt.subplot(121), plt.imshow(image), plt.title('Input')
        plt.subplot(122), plt.imshow(new_image), plt.title('Output')
        plt.show()
    
    
    
    运行结果:这个是同时进行了旋转和缩放
    image.png

    相关文章

      网友评论

          本文标题:openCV-python(二)图像的几何变换-旋转、缩放

          本文链接:https://www.haomeiwen.com/subject/phynohtx.html