opencv-python(cv2)读取和显示图片的若干问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_35732969/article/details/83375188

读取图片:

import cv2

#cv2.IMREAD_COLOR=1彩色方式读入,无透明度,默认;cv2.IMREAD_GRAYSCALE=0灰度方式读入;cv2.IMREAD_UNCHANGED包含alpha通道(透明度)
#img = cv2.imread('../material/images/23126-5.jpg',cv2.IMREAD_GRAYSCALE)
#img = cv2.imread('../material/images/23126-5.jpg',0)
img = cv2.imread('../material/images/23126-152.jpg')

具体参数说明见上面的代码注释。使用的图片如下(已经压缩过上传的):

图片显示:

cv2.imshow('image',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

第一行代码表示把图片在一个窗口中显示,第一个参数是设置窗口的名字,第二个参数就是imread()函数的返回值。下面两行代码暂时不用考虑。

如果图片尺寸不大,直接这么写没问题,正常显示。如果图片尺寸过大,就会显示不全。

我们使用:

print(img.shape)

输出图片尺寸,得到:(3539, 4892, 3),表示这里我用的图片尺寸是3539*4892,而我的电脑屏幕的分辨率才1366*768,导致显示不全,效果如下:

整个电脑屏幕只显示了原图片的左上角部分,窗口还不能缩放。

有两种处理方法:

1、使用resize()函数调整图片大小:

height,width = img.shape[:2]
#cv2.resize(src,dsize,dst=None,fx=None,fy=None,interpolation=None)
#scr:原图
#dsize:输出图像尺寸
img2 = cv2.resize(img,(int(width/8),int(height/8)))
cv2.imshow('image',img2)

参数说明见代码注释。效果如下:

2、使用namedWindow()函数使窗口大小可调整:

#创建一个名为‘image’窗口,默认参数cv2.WINDOW_AUTOSIZE不可改变大小,cv2.WINDOW_NORMAL可调整窗口大小
cv2.namedWindow('image',cv2.WINDOW_NORMAL)
cv2.imshow('image',img)

namedWindow()函数是创建一个窗口,第一个参数是命名窗口的名字,第二个参数见代码注释。效果如下(拉伸了窗口):

做一个小功能:打开一个图片,按下esc键关闭图片窗口,按下s键保存图片并关闭窗口。代码如下:

import cv2

#灰度方式打开图片
img = cv2.imread('../material/images/23126-152.jpg',0)
cv2.namedWindow('image',cv2.WINDOW_NORMAL)
cv2.imshow('image',img)
#获取键盘输入
k = cv2.waitKey(0)
#输入为esc
if k == 27:
    #关闭所有窗口
    cv2.destroyAllWindows()
#输入为s
elif k == ord('s'):
    #保存图片,第一个参数为保存的路径
    cv2.imwrite('../output/images/1810250811.jpg',img)
    cv2.destroyAllWindows()

使用matplotlib绘制imread加载的图片时,需要注意的是matplotlib使用的是RGB模式,而opencv加载时是BGR模式,所以如果直接绘制会产生奇怪的颜色,代码和效果如下:

import cv2
from matplotlib import pyplot as plt

img = cv2.imread('../material/images/23126-152.jpg')
#直接绘制,参数interpolation表示绘制时使用的插值的算法
plt.imshow(img,interpolation='bicubic')

plt.xticks([])
plt.yticks([])
plt.show()

直接绘制的颜色失真效果:

所以,正确的做法是绘制前将imread()返回值的BGR模式转化成matplotlib的RGB模式,然后再绘制。如下:

img = cv2.imread('../material/images/23126-152.jpg')
#opencv加载时是BGR模式,拆分通道
b,g,r = cv2.split(img)
#matplotlib是RGB模式,进行转化,合并通道
img2 = cv2.merge([r,g,b])
plt.imshow(img2,interpolation='bicubic')

效果如下:

当然,上面BGR转RGB的写法,强大的python有更灵活的写法:

img = cv2.imread('../material/images/23126-152.jpg')
#::-1表示倒序,下面两种写法都可以
img2 = img[:,:,::-1]
#img2 = img[...,::-1]
plt.imshow(img2,interpolation='bicubic')

因为imread函数的返回值是如下形式:

[

[[ 66  83 104]...[167 212 246]]

...

[[ 63  80 101]...[167 212 246]]

]

可以看到,最里层(第三层)的元素是类似[ 66  83 104]的bgr顺序向量,上面的代码写法更直接的将imread的返回值的最里层bgr元素逆序变成rgb,从而实现BGR到RGB的颜色模式转换。

另外,因为cv2.split()操作是比较耗时的,所以,应尽量用Numpy索引操作。

参考资料:《OpenCV-Python 中文教程》段力辉 译

猜你喜欢

转载自blog.csdn.net/weixin_35732969/article/details/83375188