最近有个项目,在加载同事提供的png图像后,发现图像显示全黑,一开始排查流程,使用自己的png测试却正常。于是有了这次的探索记录。
随手百度出来,很多人有这个疑问,但是大部分人的解决方案都是使用某些软件转换格式,却没有说出原因,这明显对于程序员来说并不能解决问题。
使用OpenCV加载图片,不管是使用imshow或是imwrote,背景图片都是黑色的。默认imread加载的图像是BGR三通道,IMREAD_UNCHANGED参数可以成功加载四通道数据,然而并不能解决问题,OpenCV对png的支持并不友好。
通过验证,直接读取四通道的BGR三通道值保存bmp图像,明显背景就全黑了,所以可以知道OpenCV的cvtcolor就是直接提取三个通道的值把BGRA转成BGR。
正如前文提到,有的png会全黑,有的不会,这是因为在Alpha通道的值并没有全部255,而有的软件或是库加载的时候就直接使用了BGR通道,而默认Alpha通道是255。比如使用ImageJ软件打开png图片,但是显示的是正常的,查看的时候已经默认转成了RGB三通道了,也就是它正确的提取了数据进行了转换。
以上图像,左图是原图png图像,右图是我处理完的bmp图像,在此处看两者似乎是没有区别的。
再看看使用Beyond Compare的对比结果图:
左上是我处理完的bmp图,右上是原图png图,下图是对比图。
背景中有一部分是全黑的,这部分数据BGRA(0,0,0,0),而OpenCV提取的时候就是BGR(0,0,0),但是我们想要的是BGR(255,255,255)。还有边缘一些其他值,Alpha通道值是0—255的,在这里不一一举例了。
所以结论是,当要实现BGRA2BGR时,可以不用OpenCV的接口,可以自己实现,伪代码如下:
B = (B | (255 - Alpha))
同理其他两通道一致。