[python] 工作记录一、利用opencv,numpy旋转图片无黑边(轮子必须由我造!!!)
- 1. 第三方库的安装
- 2. 程序目的
- 3. 图片理解
- 4. 编写代码
- (1).旋转顺时针90°
- (2).逆时针旋转90°
- (3).旋转180°
- (4).水平翻转与垂直翻转
- 总结
- 代码
- 寄语
1. 第三方库的安装
opencv和numpy不是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
寄语
路过的小伙伴一键三连呗!不许下次!!