opencv-python 图像对比_opencv、matplotlib、Pillow读取图像的对比

opencv,Pillow,matplotlib是目前比较常用的一些图像的标准库

对于Pillow的使用踩坑,import Pillow失败,No module named 'Pillow',参照如下文章:HUST小菜鸡:No module named 'Pillow'​zhuanlan.zhihu.com

一、opencv图像的读取

import cv2

img = cv2.imread('img.jpg')

print('img_shape',img.shape) #读取数据的形状

print('img_size',img.size) #读取数据的大小

print('img_dtype',img.dtype) #读取数据的编码格式

print('img',img) #打印img数据

print('img_type',type(img)) #读取img的数据类型

b, g, r = cv2.split(img) #通道分离

# print(img.shape[:2])

zeros = np.zeros(img.shape[:2],dtype='uint8')

merge_r = cv2.merge([r,zeros,zeros])

merge_g = cv2.merge([zeros,g,zeros])

merge_b = cv2.merge([zeros,zeros,b])

plt.subplot(231);plt.imshow(b)

plt.subplot(232);plt.imshow(g)

plt.subplot(233);plt.imshow(r)

plt.subplot(234);plt.imshow(merge_r)

plt.subplot(235);plt.imshow(merge_g)

plt.subplot(236);plt.imshow(merge_b)

plt.show()

cv2.imshow('img',img) #显示图片

cv2.waitKey(0)

cv2.destroyAllWindows()第一排从左到右分别是bgr通道的灰度图像,第二排从左到右分别是rgb各通道的图像原图

D:\Setup\python\python.exe D:/Pycharm/bboxe_context/test.py

img_shape (480, 640, 3)

img_size 921600

img_dtype uint8

img [[[255 255 255]

[255 255 255]

[255 255 255]

...

[255 255 255]

[255 255 255]

[255 255 255]]

[[255 255 255]

[255 255 255]

[255 255 255]

...

[255 255 255]

[255 255 255]

[255 255 255]]

[[255 255 255]

[255 255 255]

[255 255 255]

...

[255 255 255]

[255 255 255]

[255 255 255]]

...

[[ 41 95 102]

[ 60 118 117]

[ 96 164 157]

...

[ 20 113 86]

[ 16 103 93]

[ 9 120 106]]

[[ 27 92 107]

[ 93 157 162]

[ 74 153 140]

...

[ 45 118 92]

[ 6 71 46]

[ 8 88 45]]

[[ 21 126 117]

[ 72 145 149]

[ 62 136 136]

...

[ 42 122 79]

[ 23 120 76]

[ 18 80 66]]]

img_type

Process finished with exit code 0

由打印的数据结果可知及查阅资料可知,opencv读取的图像的通道顺序为BGR,读取的数据类型为numpy.ndarray,取值范围为[0,255],数据元素类型为uint8.

二、matplotlib

关于使用matplotlib进行数据处理可以参照我的这两篇文章:HUST小菜鸡:数据可视化——matplotlib(一)​zhuanlan.zhihu.comHUST小菜鸡:数据可视化——matplotlib(二)​zhuanlan.zhihu.com

import cv2

import matplotlib.pyplot as plt

img = plt.imread('img.jpg')

print('img_shape',img.shape) #读取数据的形状

print('img_size',img.size) #读取数据的大小

print('img_dtype',img.dtype) #读取数据的编码格式

print('img',img) #打印img数据

print('img_type',type(img)) #读取img的数据类型

r, g, b = cv2.split(img) #通道分离

# print(img.shape[:2])

zeros = np.zeros(img.shape[:2],dtype='uint8')

merge_r = cv2.merge([r,zeros,zeros])

merge_g = cv2.merge([zeros,g,zeros])

merge_b = cv2.merge([zeros,zeros,b])

plt.subplot(231);plt.imshow(r)

plt.subplot(232);plt.imshow(g)

plt.subplot(233);plt.imshow(b)

plt.subplot(234);plt.imshow(merge_r)

plt.subplot(235);plt.imshow(merge_g)

plt.subplot(236);plt.imshow(merge_b)

plt.show()

plt.imshow(img)

plt.show()

cv2.imshow('img',img) #显示图片

cv2.waitKey(0)

cv2.destroyAllWindows()第一排自左到右为rgb通道的灰度图像,第二排自左到右为rgb通道的图像matplotlib显示的图像opencv显示plt读取的img的图像

对比两者可以看出图像的色彩明显不对,是因为通道顺序不对

img_shape (480, 640, 3)

img_size 921600

img_dtype uint8

img [[[255 255 255]

[255 255 255]

[255 255 255]

...

[255 255 255]

[255 255 255]

[255 255 255]]

[[255 255 255]

[255 255 255]

[255 255 255]

...

[255 255 255]

[255 255 255]

[255 255 255]]

[[255 255 255]

[255 255 255]

[255 255 255]

...

[255 255 255]

[255 255 255]

[255 255 255]]

...

[[102 95 41]

[117 118 60]

[157 164 96]

...

[ 86 113 20]

[ 93 103 16]

[106 120 9]]

[[107 92 27]

[162 157 93]

[140 153 74]

...

[ 92 118 45]

[ 46 71 6]

[ 45 88 8]]

[[117 126 21]

[149 145 72]

[136 136 62]

...

[ 79 122 42]

[ 76 120 23]

[ 66 80 18]]]

img_type

由打印的结果可以看出,matplotlib读取的图像的通道顺序为RGB,读取的数据类型为numpy.ndarray,取值范围为[0,255],数据元素类型为uint8。

以上分析了opencv和matplotlib的图像读取,可以看出通道顺序存在明显的差别

(读取的结果详细见上述的print(img)返回的结果)

plt.imshow(img)

plt.show()

img_cv = cv2.cvtColor(img,cv2.COLOR_RGB2BGR)

cv2.imshow('img',img_cv) #显示图片

cv2.waitKey(0)

cv2.destroyAllWindows()

通道变换后,两个图像都正常显示没有差别

三、Pillow的图像读取

使用pip安装Pillow。Pillow是从PIL fork过来的Python 图片库。

from PIL import Image

im = Image.open('img.jpg')

print(im)

print('PIL_im_mode & type:',im.mode,type(im.mode)) #读取im的图片模式

print('PIL_im_size & type:',im.size,type(im.size)) #读取im的图片尺寸

print('PIL_im_height & type:',im.height,type(im.height)) #读取im的图片高度

print('PIL_im_width & type:',im.width,type(im.width)) #读取im的图片宽度

print('PIL_im_palette & type:',im.palette,type(im.palette)) #读取im的图片调色板

print('PIL_im_info & type:',im.info,type(im.info)) #读取im的图片有关数据

Image._show(im)

PIL_im_mode & type: RGB

PIL_im_size & type: (640, 480)

PIL_im_height & type: 480

PIL_im_width & type: 640

PIL_im_palette & type: None

PIL_im_info & type: {'jfif': 257, 'jfif_version': (1, 1), 'dpi': (72, 72), 'jfif_unit': 1, 'jfif_density': (72, 72)}

PIL_im_format & type: JPEG

由打印的结果可知,PIL读取的图像的数据格式不是一个numpy.ndarray,打印出来的结果是一个物理地址,读取的结果包含mode,size,info,format等属性。

通过np.array可将其转换成numpy.ndarray供后期的处理和使用

from PIL import Image

im = Image.open('img.jpg')

print(im)

img = np.array(im)

img = plt.imread('img.jpg')

print('img_shape',img.shape) #读取数据的形状

print('img_size',img.size) #读取数据的大小

print('img_dtype',img.dtype) #读取数据的编码格式

print('img',img) #打印img数据

print('img_type',type(img)) #读取img的数据类型

可以使用opencv等对其处理

img_shape (480, 640, 3)

img_size 921600

img_dtype uint8

img [[[255 255 255]

[255 255 255]

[255 255 255]

...

[255 255 255]

[255 255 255]

[255 255 255]]

[[255 255 255]

[255 255 255]

[255 255 255]

...

[255 255 255]

[255 255 255]

[255 255 255]]

[[255 255 255]

[255 255 255]

[255 255 255]

...

[255 255 255]

[255 255 255]

[255 255 255]]

...

[[102 95 41]

[117 118 60]

[157 164 96]

...

[ 86 113 20]

[ 93 103 16]

[106 120 9]]

[[107 92 27]

[162 157 93]

[140 153 74]

...

[ 92 118 45]

[ 46 71 6]

[ 45 88 8]]

[[117 126 21]

[149 145 72]

[136 136 62]

...

[ 79 122 42]

[ 76 120 23]

[ 66 80 18]]]

img_type

Process finished with exit code 0

在用神经网络处理图像的时候,都会将numpy的图像数组转换成tensor的类型,将PIL.Image和numpy.nd (H x W x C),取值范围为[0,255]转换成torch.FloatTensor(C x H x W),取值范围为[0,1]

torch.Tensor 高维矩阵的表示: (nSample)x C x H x W

numpy.ndarray 高维矩阵的表示: H x W x C

在深度学习中,原始图像需要转换为深度学习框架自定义的数据格式,在pytorch中,需要转为torch.Tensor。pytorch提供了torch.Tensor与numpy.ndarray转换接口,同时由于矩阵维度不同,还需要使用numpy.transpose( ) 来改变矩阵形状。

torch.from_numpy( ) #numpy.ndarray转为torch.Tensor

img_tensor.numpy() #将tensor转为numpy

转换过程如下

import torch

import numpy as np

import matplotlib.pyplot as plt

import cv2

img_orig = cv2.imread('img.jpg')

img = cv2.cvtColor(img_orig,cv2.COLOR_BGR2RGB)

print('orig_img_shape:',img.shape)

img_tensor = torch.from_numpy(np.transpose(img,(2,0,1)))

print('tensor_shape:',img_tensor.shape)

img_numpy = np.transpose(img_tensor.numpy(),(1,2,0))

print('from_tensor2numpy:',img_numpy.shape)

print(img == img_numpy)

plt.subplot(121);plt.imshow(img)

plt.subplot(122);plt.imshow(img_numpy)

plt.show()左边为原始图像,右边为从numpy->tensor->numpy

D:\Setup\python\python.exe D:/Pycharm/bboxe_context/test.py

orig_img_shape: (480, 640, 3)

tensor_shape: torch.Size([3, 480, 640])

from_tensor2numpy: (480, 640, 3)

[[[ True True True]

[ True True True]

[ True True True]

...

[ True True True]

[ True True True]

[ True True True]]

[[ True True True]

[ True True True]

[ True True True]

...

[ True True True]

[ True True True]

[ True True True]]

[[ True True True]

[ True True True]

[ True True True]

...

[ True True True]

[ True True True]

[ True True True]]

...

[[ True True True]

[ True True True]

[ True True True]

...

[ True True True]

[ True True True]

[ True True True]]

[[ True True True]

[ True True True]

[ True True True]

...

[ True True True]

[ True True True]

[ True True True]]

[[ True True True]

[ True True True]

[ True True True]

...

[ True True True]

[ True True True]

[ True True True]]]

Process finished with exit code 0

你可能感兴趣的:(opencv-python,图像对比)