[python] 工作记录一、利用opencv,numpy旋转图片无黑边(轮子必须由我造!!!)

1. 第三方库的安装

opencvnumpy不是python的自带库,所以需要我们进行手动安装( 注意是opencv-python )

pip install opencv-python
pip install numpy

2. 程序目的

领导要求把图片进行旋转但不能有黑边…
请添加图片描述
领导安排的工作能不做吗? 不能,不关钱的事,主要就是想打代码了
opencv自带有旋转图片的方法,不过轮子必须由我造贯彻一切
请添加图片描述

3. 图片理解

简单来说,彩色图片在python-opencv中是以这样的形式存在的,如下图
把矩阵看成只有三层的正方体,也就是三通道,每一层都是一串十六进制编码,每一个像素点都是从上向下组成的,例如:0xd5c5a5 。形成一个颜色像素点,这就是平时程序使用的RGB颜色"#******",通过像素点的组合才形成我们看到的图片。(图是自己画的,有点丑。)
在这里插入图片描述

4. 编写代码

从路上拍张动物园里的大熊猫来测试
请添加图片描述

(1).旋转顺时针90°

思路:创建一个与原本图像尺寸一致的空矩阵,遍历原始图像的长写入空矩阵的宽保持通道数不变尺寸不变,开撸~

src = cv.imread(pictrue_path)
height = src.shape[0]  # 图片的高度、图片的垂直尺寸
width = src.shape[1]  # 图片的宽度、图片的水平尺寸
channels = src.shape[2]  # 通道
img = np.zeros([width, height, channels], np.uint8)
for row in range(height):
    img[:, height - row - 1, :] = src[row, :, :]

旋转结果:
在这里插入图片描述

(2).逆时针旋转90°

思路:```同上,当然了,得改变一下写入的位置

src = cv.imread(pictrue_path)
height = src.shape[0]  # 图片的高度、图片的垂直尺寸
width = src.shape[1]  # 图片的宽度、图片的水平尺寸
channels = src.shape[2]  # 通道
img = np.zeros([width, height, channels], np.uint8)
for row in range(height):
    img[:, row, :] = src[row, :, :]

旋转后:
在这里插入图片描述

可以看到图片还不是我们想要的效果,还得上下翻转一下
新增语句:

img = img[::-1]

旋转结果:
在这里插入图片描述

当当当当~!正确旋转

(3).旋转180°

思路:上下翻转后看看结果

src = cv.imread(pictrue_path)
height = src.shape[0]  # 图片的高度、图片的垂直尺寸
width = src.shape[1]  # 图片的宽度、图片的水平尺寸
channels = src.shape[2]  # 通道
temp = src[::-1]

在这里插入图片描述

思路:现在得水平翻转一下才能达到我们的效果,创建一个与原本图像尺寸一致的空矩阵,遍历原始图像的第一个宽写入空矩阵的最后一个宽保持通道数不变尺寸不变

添加代码:

img = np.zeros([height, width, channels], np.uint8)
for col in range(width):
    img[:, width - col - 1, :] = temp[:, col, :]

旋转结果:
在这里插入图片描述

完全正确~✔

(4).水平翻转与垂直翻转

认真看的小伙伴应该已经看到了

水平翻转:

src = cv.imread(pictrue_path)
height = src.shape[0]  # 图片的高度、图片的垂直尺寸
width = src.shape[1]  # 图片的宽度、图片的水平尺寸
channels = src.shape[2]  # 通道
img = np.zeros([height, width, channels], np.uint8)
for col in range(width):
    img[:, width - col - 1, :] = src[:, col, :]

旋转结果:
在这里插入图片描述

垂直翻转:

src = cv.imread(pictrue_path)
height = src.shape[0]  # 图片的高度、图片的垂直尺寸
width = src.shape[1]  # 图片的宽度、图片的水平尺寸
channels = src.shape[2]  # 通道
img = src[::-1]

旋转结果:
在这里插入图片描述

总结

上述所有的旋转代码在我的电脑运行基本只需要0.14s,跟opencv自带的旋转图片不相上下,旗鼓相当,锣鼓喧天,鞭炮齐鸣,红旗招展,人山人海····

代码

我将代码写成一个方法,便于使用

def create_image(pictrue_path, width, height, channel, img, angle):
    global img1
    if angle == 90:  # 右旋90° 
        img1 = np.zeros([width, height, channel], np.uint8)
        for row in range(height):
            img1[:, height - row - 1, :] = img[row, :, :]
    elif angle == 270:  # 左旋转90° 右旋270° 
        img1 = np.zeros([width, height, channel], np.uint8)
        for row in range(height):
            img1[:, row, :] = img[row, :, :]
        img1 = img1[::-1]
    elif angle == 180:  # 旋转180° 
        temp = img[::-1]
        img1 = np.zeros([height, width, channel], np.uint8)
        for col in range(width):
            img1[:, width - col - 1, :] = temp[:, col, :]
    elif angle == -180:  # 垂直翻转180° 
        img1 = img[::-1]
    elif angle == -90:  # 水平翻转90° 
        img1 = np.zeros([height, width, channel], np.uint8)
        for col in range(width):
            img1[:, width - col - 1, :] = img[:, col, :]
    new_img = os.path.split(pictrue_path)[1].split('.')[0] + '副本.jpg'
    cv.imencode('.jpg', img1)[1].tofile(new_img)
    return {'status': 1, 'msg': '成功处理图片!', 'path': new_img}


def run_pictrue_spin(pictrue_path, angle):
    if not os.path.exists(pictrue_path):
        return {'status': 2, 'msg': '文件路径不存在!'}
    src = cv.imread(pictrue_path)
    height = src.shape[0]  # 图片的高度、图片的垂直尺寸
    width = src.shape[1]  # 图片的宽度、图片的水平尺寸
    channels = src.shape[2]  # 通道
    result = create_image(pictrue_path, width, height, channels, src, angle)  # angle=90 or 270 or 180 or -90 or -180
    return result

寄语

路过的小伙伴一键三连呗!不许下次!!

请添加图片描述

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

物无物没

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值