昨晚参考其它blog,将之前的SDL框架的显示改成了opencv显示。结果学习过程中遇到2个bug,结果都顺利解决,主要是图像格式转换问题。
问题1
显示变色
![](https://img.haomeiwen.com/i12010880/7ad49e3ceb7216e1.png)
通过vs2017中调试,对比正常变色的数据,发现rgb和bgr颠倒了
![](https://img.haomeiwen.com/i12010880/85d8aa7810d5737a.png)
cv::Mat frameImage(cv::Size(width, height), CV_8UC3, cv::Scalar(0));
stepWidth = frameImage.step;
nChannels = frameImage.channels();
pData = frameImage.data;
//frameImage.data = pFrame->data[0];
#if 1
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
pData[i * stepWidth + j * nChannels + 0] = pFrame->data[0][i * pFrame->linesize[0] + j * nChannels + 2];
pData[i * stepWidth + j * nChannels + 1] = pFrame->data[0][i * pFrame->linesize[0] + j * nChannels + 1];
pData[i * stepWidth + j * nChannels + 2] = pFrame->data[0][i * pFrame->linesize[0] + j * nChannels + 0];
}
}
#endif
cv::namedWindow("Video", CV_WINDOW_AUTOSIZE);
cv::imshow("Video", frameImage);
小结:正常sws_scale函数转换格式后,应该frameImage.data = pFrame->data[0]; 就可以通过cv::imshow显示了,不需要再进行data赋值,此赋值代码中把RGB和BGR进行了转换,导致的变色。
问题2
显示3段,而且是灰色调的,图像也不太正常
![](https://img.haomeiwen.com/i12010880/589bbe82cae12b5e.png)
调试数据
0x00000292744DD080 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 ...................
0x00000292744DD093 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 ...................
0x00000292744DD0A6 12 12 12 12 12 12 12 12 12 12 13 13 13 13 13 13 13 13 13 ...................
0x00000292744DD0B9 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 ...................
0x00000292744DD0CC 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 ...................
0x00000292744DD0DF 13 13 13 13 13 13 13 13 13 13 13 13 13 14 14 14 14 14 14 ...................
0x00000292744DD0F2 14 14 14 15 14 14 15 15 15 15 15 15 16 16 15 16 16 16 16 ...................
0x00000292744DD105 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 ...................
0x00000292744DD118 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 ...................
0x00000292744DD12B 17 17 16 19 18 18 1c 1b 1a 1e 1e 1d 20 20 1f 20 20 20 21 ............ . !
0x00000292744DD13E 21 20 21 21 21 21 21 21 20 21 21 20 20 20 20 20 20 21 21 ! !!!!!! !! !!
0x00000292744DD151 20 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 !!!!!!!!!!!!!!!!!!
0x00000292744DD164 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 !!!!!!!!!!!!!!!!!!!
0x00000292744DD177 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 !!!!!!!!!!!!!!!!!!!
0x00000292744DD18A 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 !!!!!!!!!!!!!!!!!!!
0x00000292744DD19D 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 !!!!!!!!!!!!!!!!!!!
0x00000292744DD1B0 21 21 21 21 21 21 21 21 21 21 21 21 21 21 22 21 21 22 22 !!!!!!!!!!!!!!"!!""
0x00000292744DD1C3 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 """""""""""""""""""
问题分析:因为图像转换的时候都用了AV_PIX_FMT_YUV420P,而此格式是planar。而把3个byte的Y(灰度)数据给了合并为一个RGB数据,导致看上去有3片灰色的
YUV420 planar数据, 以720×488大小图象YUV420 planar为例,
其存储格式是: 共大小为(720×480×3>>1)字节,
分为三个部分:Y,U和V
Y分量: (720×480)个字节
U(Cb)分量:(720×480>>2)个字节
V(Cr)分量:(720×480>>2)个字节
三个部分内部均是行优先存储,三个部分之间是Y,U,V 顺序存储。
即YUV数据的0--720×480字节是Y分量值,
720×480--720×480×5/4字节是U分量
720×480×5/4 --720×480×3/2字节是V分量。
sws_scale经过YUV转换后的数组有3个,一个是Y数组,一个是U数组,一个是V数组。而进入RGB转换数组只有1个,存储方式是RGB交叉排列的
找到根本原因后,问题顺利解决。
网友评论