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

  • 1. 第三方库的安装
  • 2. 程序目的
  • 3. 图片理解
  • 4. 编写代码
  • (1).旋转顺时针90°
  • (2).逆时针旋转90°
  • (3).旋转180°
  • (4).水平翻转与垂直翻转
  • 总结
  • 代码
  • 寄语


1. 第三方库的安装

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

pip install opencv-python
pip install numpy

2. 程序目的

领导要求把图片进行旋转但不能有黑边…

python旋转图片之后去除黑色背景 python 图片旋转一定的角度_opencv


领导安排的工作能不做吗? 不能,不关钱的事,主要就是想打代码了

opencv自带有旋转图片的方法,不过轮子必须由我造贯彻一切

python旋转图片之后去除黑色背景 python 图片旋转一定的角度_人工智能_02

3. 图片理解

简单来说,彩色图片在python-opencv中是以这样的形式存在的,如下图

把矩阵看成只有三层的正方体,也就是三通道,每一层都是一串十六进制编码,每一个像素点都是从上向下组成的,例如:0xd5c5a5 。形成一个颜色像素点,这就是平时程序使用的RGB颜色"#******",通过像素点的组合才形成我们看到的图片。(图是自己画的,有点丑。)

python旋转图片之后去除黑色背景 python 图片旋转一定的角度_python旋转图片之后去除黑色背景_03

4. 编写代码

从路上拍张动物园里的大熊猫来测试

python旋转图片之后去除黑色背景 python 图片旋转一定的角度_垂直翻转_04

(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, :, :]

旋转结果:

python旋转图片之后去除黑色背景 python 图片旋转一定的角度_python_05

(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, :, :]

旋转后:

python旋转图片之后去除黑色背景 python 图片旋转一定的角度_python_06

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

img = img[::-1]

旋转结果:

python旋转图片之后去除黑色背景 python 图片旋转一定的角度_垂直翻转_07

当当当当~!正确旋转

(3).旋转180°

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

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

python旋转图片之后去除黑色背景 python 图片旋转一定的角度_垂直翻转_08

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

添加代码:

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

旋转结果:

python旋转图片之后去除黑色背景 python 图片旋转一定的角度_垂直翻转_09

完全正确~✔

(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, :]

旋转结果:

python旋转图片之后去除黑色背景 python 图片旋转一定的角度_python_10

垂直翻转:

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

旋转结果:

python旋转图片之后去除黑色背景 python 图片旋转一定的角度_python_11

总结

上述所有的旋转代码在我的电脑运行基本只需要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

寄语

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

python旋转图片之后去除黑色背景 python 图片旋转一定的角度_opencv_12