关于cv.cvtColor转换的问题及解决方法

问题描述篇:

今天在调试困扰了我很久的一个问题,在训练网络生成batch数据的时候读入原始图像,输出的时候却老是出问题。

 

我们都知道YUV和RGB之间的转换关系:

R = Y + 1.4075 * V;

G = Y - 0.3455 * U - 0.7169*V;

B = Y + 1.779 * U;

 

Y = 0.299 * R + 0.587 * G + 0.114 * B;

U = -0.169 * R - 0.331 * G + 0.5 * B ;

V = 0.5 * R - 0.419 * G - 0.081 * B;

 

问题在于,我从RGB到YUV的时候,cv.cvtColor(Img, cv2.COLOR_RGB2YUV)输出的是(Y,U,V),Y属于0-255,U和V却是在128左右徘徊(其实也是0-255)而不是公式计算出来的-127-127。

最终导致的结果就是存在色偏(可能不仅仅是色偏,连有一些结构都有改变,但是我准备先解决这个色偏的问题),具体情况如图:

原始图像:

输出图像:

于是寻找解决问题,发现在直接读进去的时候用

Img = cv.cvtColor(Img, cv2.COLOR_RGB2YUV)

Img = cv.cvtColor(Img, cv2.COLOR_YUV2RGB)

连续使用的时候是可以直接转换成功的,但是一旦中间经过网络输出之后,再用YUV转换到RGB的函数就会出错。

于是我把每次转换的内容存了下来。

原图(没问题):

YUV(也很正常):

转换回RGB(出问题了):

后来发现问题出在最后一步,转换回去的时候,从YUV空间变回RGB空间的时候,用的公式是上面那个没有经过量化的公式,计算出来的结果很多都是四百多五百多的值。找了很久网上的博客,都没有这个问题的解决方法。最后试验了各种情况,锁定了bug位置,然后仔细看了cv2的文档,最后调通了。

 

解谜篇:

先说一下在python的opencv中,是有三种图像文件的存储方式的,分别是:

CV_8U,指的是0-255的uint8型

CV_16U,指的是0-65535的uint16型

CV_32F,指的是0-1的float32型

在我们刚从文件中读进来一幅图像的时候,都是存储在uint8型的一个ndarray中,但是如果要严格按照公式转换成YUV空间的话,那么U或者V空间中必然会存在小于0的数,那怎么办呢?

cv.cvtColor(Img, cv2.COLOR_YUV2RGB)这个函数的输出范围刚才已经说过了,Y(0-255)U(0-255)V(0-255),所以这个函数其实是将UV空间做了一个平移,原来均值可能为零的地方平移到了127,所以才会避免刚才说的小于零的情况出现。

那么问题也就出现了,我在直接读入图片之后在YUV空间和RGB空间中来回转换是没有出现问题的。但是我把网络输出重新转换回RGB空间的时候这个函数的输出大于了255,所以导致输出图像出错。到底是为什么呢?

这就该我们刚才所说的三种文件存储方式登场了,其实在调用cv.cvtColor(Img, cv2.COLOR_YUV2RGB)的时候,会先判断你输入图像的类别,如果是CV_8U,那么UV空间的中心点就在127,如果是CV_16U,那么就在32768,如果是CV_32F,那么就在0.5。而我网络的输出由于是float32型,导致调用这个函数的时候判断为我的中心点在0.5左右,然后通过上面的公式计算之后导致我数据溢出。

最后,其实就直接在转存之前调整一下这个数据类型即可,即:

Pic = Pic.astype(‘uint8’)

问题解决!

 

总结一下:

这个问题困扰了我好久,当然之前因为各种原因一直不是很想面对,也一度觉得有没有可能是我的脑子出了问题(真实想法),不过最后比自己看文档找博客来解决之后还是很有成就感的,毕竟自己还在起步,多看paper多写代码,踏踏实实干点什么事情比什么都重要。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值