以下放在开头,备忘:
打开的图片是PIL类型,默认RGB。
将PIL类型转化为numpy类型:im = numpy.array(img)
才能看到shape属性,是(height, width, channel)数组,channel的通道数据是RGB。
path: 图片的路径;
读取方式: cv2.IMREAD_COLOR:读入一副彩色图片;cv2.IMREAD_GRAYSCALE:以灰度模式读入图片;cv2.IMREAD_UNCHANGED:读入一幅图片,并包括其alpha通道。
默认为cv2.IMREAD_COLOR。
返回值是(height,width,channel)数组,channel的顺序是BGR顺序
PIL Image转化为OpenCV格式:
img = Image.open()
img = cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
OpenCV转化为PIL Image格式:
img = cv2.imread()
img2 = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
这个显示是和读取对着的,也就是说要想可视化出来正常的RGB格式,给plt.imshow()的应该是rgb格式的图片,给cv2.imshow()的应该是bgr格式的图片。多说一些,因为我平时几乎不用。在中,接受的图片类型可以是np.ndarray,tensor, PIL Image这些任意的类型。
在SSD和YOLO的源码中,使用opencv读取图片,其处理图片时都有以下图片通道转换的代码,做以下记录:
以https://github.com/ultralytics/yolov3中的一部分为例:
其中的不用管,是YOLO对输入图片按Padded方式进行Resize。
我们要分析的是img = img[:, :, ::-1].transpose(2, 0, 1)这句代码
先放结论:
img[:,:,::-1] 这句的作用,是说:图像张量有三个维度,分别表示宽度、长度和颜色通道。既然image[:,:,::-1]的作用是对颜色通道把RGB转换成BGR。
怎么转换的呢?
对于列表img进行img[:,:,::-1]的作用是列表数组左右翻转,例如:
可以明确看出,[:,:,::-1]的作用就是对数组进行左右翻转。那为什么对于图像而言却能实现RGB通道转换为BGR通道呢?先看一些读取图片的方法是怎么读取吧
一般有opencv(cv2)和matplotlib(plt)的读取方式:(cv2把图片读取后是把图片读成BGR形式的,plt则是读成RGB形式)
证明如下:
以一张图片为样例:
正常显示就是以RGB为格式显示的。当我们用plt读取时:
打印出来的是:
取第一个值,(129,80,73),在网上以查,颜色是深棕色的,确实跟图片的左上角是一致的:
证明plt读取图片的方式确实是以RGB的格式读取。
接着:
当执行 [:,:,::-1]后,数组会左右翻折:
,
可以看到(129 80 73)变成(73 80 129)。
通过网上查询(73 80 129)是什么颜色的,发现是蓝色的。
所以,如果拆测没错的话,这是后显示出来的图片应该左上角就是蓝色的,我们试试:
果然左上角就是蓝色的。因此,这应该是BRG格式的图片了。所以得证,[:,:,::-1]的作用就是把RGB(或BRG)转换成BGR(或者RGB)。
=============================
插一句题外话,用opencv(即cv2)读取图片,是以BGR的形式来读取的。我们用cv2的imshow()函数显示图片发现跟我们打开图片的样子一样,是因为cv2的imshow()又把BGR转回RGB再显示。但cv2确实是以BGR形式读取图片的,而plt则是以RGB形式。
代码中有时也会有这种操作,这个的意义也是通道的转换。其实都是因为opencv中imread读取出来的图片是BGR格式,也就是说下列三组代码是完全等价的,操作的结果都是将imread读取的BGR格式的图片转换为RGB格式
回到最初的问题,img = img[:, :, ::-1].transpose(2, 0, 1)这句代码,有什么用,一句话总结:
常见如下代码
PIL读取很正常,没什么操作,通常也不进行转换
参考:
图像领域img[:,:,::-1]的理解
pytorch:读取图像的两种方法
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.mushiming.com/mjsbk/9116.html