您的位置:首页 > 编程语言 > MATLAB

python-opencv-matlab图像处理接口关系

2017-08-16 17:44 435 查看

1、说明

caffe框架由C++编写,其还提供python和matlab接口调用。而caffe的图像读取与保存是利用opencv实现,因此需要梳理图像在不同接口中的转换关系,方便不同接口下的数据传输与保存。


关键点:图像文件在内存中的保存形式是连续存储的。如果是3通道RGB图像,则其在内存中存储的格式为 r1g1b1,r2g2b2,r3g3b3.........

2、图像读取及转换

2.1 python直接调用图像

python利用matplotlib库可直接读入、显示、保存图像。

已知图像大小为(height,width,channel)=(194,295,3);

import matplotlib.pyplot as plt
pyimg=plt.imread('HappyFish.jpg')
plt.imshow(pyimg)
plt.show()




查看读入的数据类型及大小如下:

print type(pyimg)
print pyimg.shape




可知,python保存图像数据的数据类型为numpy.ndarray类型,数据存放模式为(height,width,channel)=(194,259,3);

(0,0)处的像素值关系如下:

print pyimg[0,0]




从上图可以看出,(0,0)处的像素值如上。

2.2 python利用opencv调用图像

import cv2
cvimg=cv2.imread('HappyFish.jpg')
cv2.imshow("wnd",cvimg)
cv2.waitKey(0)




数据类型及数据调用如下:

print type(cvimg)
print cvimg.shape
print cvimg[0,0]




可以看出,opencv的python接口同样是采用numpy.ndarray类型存储像素值,存储方式依然是【height,width,channel】,此种存放模式方便图像像素值索引,如【0,0】可直接调用三个通道的数据。


虽然打开的同样一个图像,但是在用 matplotlib读取的时候与cv2读取,在【0,0】处的像素值是不同的,原因是opencv读图像的时候,像素在内存中的存储的顺序为BGR,而python中为RGB。

2.3 python与opencv 数据之间转换

利用opencv 读入图像,利用matplotlib显示图像

import cv2
cvimg=cv2.imread('HappyFish.jpg')
plt.imshow(cvimg)
plt.show()




图像显示异常,主要是应为opencv将图像像素的存储顺序改为BRG,而python默认显示图像格式为RGB.为了显示正常,可执行如下操作:

#方法1
import cv2
cvimg=cv2.imread('HappyFish.jpg')
b,g,r=cv2.split(cvimg)
rgb=cv2.merge([r,g,b])
plt.imshow(rgb)
plt.show()

#方法2
rgb=cv2.cvtColor(cvimg,cv2.COLOR_BGR2RGB)
plt.imshow(rgb)
plt.show()

#方法3
rgb=cvimg[:,:,::-1]
plt.imshow(rgb)
plt.show()


3、numpy多维数组相关操作

python中,图像数据存储的数据格式为numpy.ndarray,因此有必要了解相关操作,特别是transpose和reshape操作。

3.1 reshape

tt=np.arange(24)
/*array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23])
*/
t1=tt.reshape(2,3,4)
/*
array([[[ 0,  1,  2,  3],
[ 4,  5,  6,  7],
[ 8,  9, 10, 11]],

[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]])
*/
t2=t1.reshape(4,3,2)
/*
array([[[ 0,  1],
[ 2,  3],
[ 4,  5]],

[[ 6,  7],
[ 8,  9],
[10, 11]],

[[12, 13],
[14, 15],
[16, 17]],

[[18, 19],
[20, 21],
[22, 23]]])
*/
t2.shape=[2,3,4]
/*
t2=
array([[[ 0,  1,  2,  3],
[ 4,  5,  6,  7],
[ 8,  9, 10, 11]],

[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]])
*/


可以看出,reshape不会改变数据在内存中的先后顺序,改变shape属性同reshape()函数效果相同。

3.2 transpose

transpose方法,用于改变多维数组各个维度(通道)上的映射关系。numpy多维数组的维度(通道)变化规律为:最左端维度最大,变化速率最低,向右维度依次降低,变化速率依次变高。如三维数组,通道编号分别为 0–>1–>2

t3=t2.transpose(0,2,1)
/*
array([[[ 0,  4,  8],
[ 1,  5,  9],
[ 2,  6, 10],
[ 3,  7, 11]],

[[12, 16, 20],
[13, 17, 21],
[14, 18, 22],
[15, 19, 23]]])
某点关系: t3[1,3,2]==t2[1,2,3] t3某点的值映射回t2的索引
*/


为了更加直观,利用matlab生成如上有三个通道的伪图像块img,图像大小格式为【height,width,channel】=【5,4,3】。



利用python读入图像,其在内存中存储的数据格式如下所示:



看上去有点诡异,没有matlab单通道独立显示的方式直观,但是,这种存储格式方便像素直接索引,如img[0,0]可直接返回三个通道的像素值 【1,2,4】


可不可以利用transpose将python格式的图像,转化为类似与matlab单通道的表示形式,当然可以:

imgt=img.transpose(2,0,1)  ## 好强大
/*
array([[[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]],

[[2, 2, 2, 2],
[2, 2, 2, 2],
[2, 2, 2, 2],
[2, 2, 2, 2],
[2, 2, 2, 2]],

[[4, 4, 4, 4],
[4, 4, 4, 4],
[4, 4, 4, 4],
[4, 4, 4, 4],
[4, 4, 4, 4]]], dtype=uint8)
*/


利用opencv读取img,如下,在次证明了像素值按照BGR格式存储的事实。

ccimg=cv2.imread('img.jpg')
/*
array([[[4, 2, 1],
[4, 2, 1],
[4, 2, 1],
[4, 2, 1]],

[[4, 2, 1],
[4, 2, 1],
[4, 2, 1],
[4, 2, 1]],

[[4, 2, 1],
[4, 2, 1],
[4, 2, 1],
[4, 2, 1]],

[[4, 2, 1],
[4, 2, 1],
[4, 2, 1],
[4, 2, 1]],

[[4, 2, 1],
[4, 2, 1],
[4, 2, 1],
[4, 2, 1]]], dtype=uint8)
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  python