python中利用Image和cv2库对图像操作的相关方法总结

python中利用Image和cv2库对图像操作的相关方法总结

用python做图像处理和机器视觉一定避不开Image和cv2这两个基本的图像处理库,想着我做这方面也有好长时间了,总是记不住一些基本的操作,为简单的代码一遍又一遍的上网查找方法,所以今天特地写下我用这两个库进行图像的读取和保存的常用方法。我写这篇博文只是为了总结自己常用的方法和向大家分享一些最基本的操作。我总结的不一定全面和专业,但是我想这些方法对于一个小白来说还是有很大用的。在本篇文章中可能会有一些概念上的不严谨和代码上的冗余(平庸),如有问题,请多指教!
声明:在本文中有一些内容是借鉴别人的博文,因为本文不做商业用途,这里就不一一注释出处了,请多见谅!
ps 本文主要用到了三个库,分别为:Image,cv2和numpy
具体的引用方法为(本文):

from PIL import Image
import cv2
import numpy as np

1 读取图片(转为numpy数组格式)

1.1 用cv2读取图像

cv2是经常用到的库,用它读入图像的方法为:

img = cv2.imread(参数1,参数2)        #直接读入是一个三维矩阵

其中:
参数1是所要读的图像的路径名
参数2是加载图像的方式,主要有以下三种:(可以写数字,也可写前面的英文字符串)
cv2.IMREAD_COLOR:加载彩色图片,这个是默认参数,可以直接写1。
cv2.IMREAD_GRAYSCALE:以灰度模式加载图片,可以直接写0。
cv2.IMREAD_UNCHANGED:包括alpha,可以直接写-1。
例如以下代码:

import cv2
path = 'C:\picture.jpg'
img = cv2.imread(path)
img = cv2.imread(path,1)
img = cv2.imread(path,cv2.IMREAD_COLOR)

其中的img三句产生的效果是一样的,都是以彩图的形式读取picture.jpg图像。

以下做一个实验,说明cv2用不同方式读取图像的差别。我们假设现在的picture.jpg图像是一个576*768像素大小的三通道彩图。

import cv2
path = 'C:\picture.jpg'
img = cv2.imread(path,1)
print(img.shape)              #输出:(576, 768, 3)
img = cv2.imread(path,0)
print(img.shape)              #输出:(576, 768)

1.2 用Image读取图像

因为Image是PIL里的一个字库,所以在使用Image是需要安装PIL库,并且需要用如下形式引用Image库:

from PIL import Image

用Image库读取图像的方法是:

img = Image.open(参数1)

这里的参数1是图像的路径名。
Image.open函数本身并不提供以什么方式读取图像的方法,它默认是以彩图(就是图像本来的样子)读取图像,在用的时候也不需要我们可以注意用什么方法读(其实cv2也一样)。如果非得用这个方法将一张彩图(三通道)以灰度图(单通道)的方式加载,那么可以考虑在这个函数后加上“.convert(参数2)”的方法。具体的代码通式为:

img1 = Image.open(path).convert(参数2)     #可选“L”,"RGB"

这里的参数2是具体的读入图像格式(下文在图像保存的地方会详细说,这里简要说下用法),通常为“L”或者“RGB”。
其中“L”表示以灰度图(单通道)的方式读入,“RGB”表示以彩图(三通道)的方式读入。
例如:

from PIL import Image
path = 'C:\picture.jpg'
img1 = Image.open(path).convert("L")

这段代码的意思就是将picture.jpg这张彩图以灰度图的形式读入并存到img1上。

我们依旧以picture.jpg这张576*768像素大小的三通道彩图为例,感受下不同的Image读法所产生的不同结果:

import cv2
import numpy as np
path = 'C:\picture.jpg'

img = Image.open(path)
print(img.size)             #输出:(768,576)    这没写错,就是这样输出的
img = np.array(img)
print(img.shape)           #输出:(576,768,3)

img1 = Image.open(path).convert("L")
print(img1.size)            #输出:(768,576)
img1 = np.array(img1)
print(img1.shape)            #输出:(576,768)

1.3 用numpy转化读入的图像为数组

在1.2最后的实验中也用到了这个方法, 具体的操作就是:

import numpy as np
maritx = np.array(img)

其中img是用cv2或Image读入的图像

2 矩阵转存为图像

2.1 cv2下矩阵转存图像

cv2可以直接无视numpy的数组操作,直接对矩阵保存就行,不用考虑现在是矩阵,保存图像需要转码这些问题,这点好评!

2.2 Image下矩阵转存图像

Image库的保存函数是“图像名.save()”,但是在保存前必须将numpy数组的形式转为图像的编码格式,否则就会在保存的时候报出如下错误:

AttributeError: 'numpy.ndarray' object has no attribute 'save'

正确的数组转图像编码通式为:

img = Image.fromarray(martix)

这里的martix为numpy下的数组,此时的img就为图片格式了。

3 保存图像

3.1 cv2下保存图像

保存的通式为:

save_path = "D:\1.jpg"
cv2.imwrite(save_path, img)

其中img是读入的(或经numpy操作的)图像(数组)。save_path是所有保存的路径名。

3.2 Image下保存图像

保存的方法为:

save_path = "D:\1.jpg"
img.save(save_path)

其中img为待保存的图像,记住一定是图像的编码格式!!!。这个是默认的保存方法, 按照这种方法保存的图像的通道数与img保持一致。
回到最初打开图像那个问题,如果我想以特定的通道方法保存图像该怎么做?这个问题Image给出了很好的解决方案,那就是应用“.convert(“参数”)”方式对要保存的图像进行重新编码。具体的方法就是:

save_path = "D:\1.jpg"
img.save(save_path).convert("编码参数")

'''
#单独使用.convert()也可,例如:
save_path = "D:\1.jpg"
img = img.convert("编码参数")
img.save(save_path)
'''

这里的编码参数主要反映的是不同的存储(数据类型和通道深度),具体的选项和对应的含义如下:
1 ------------------ (1位像素,黑白,每字节一个像素存储)
L ------------------(8位像素,黑白灰度图)
P ------------------ (8位像素,使用调色板映射到任何其他模式)
RGB--------------(3x8位像素,真彩色,三通道)
RGBA--------------(4x8位像素,带透明度掩模的真彩色)
CMYK------------- (4x8位像素,分色)
YCbCr--------------(3x8位像素,彩色视频格式)
I--------------------- (32位有符号整数像素)
F---------------------(32位浮点像素)
这里面最常用的就是"L"和"RGB"。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值