最近需要在HEVC中提取出一帧图像进行预处理,并最终输入到神经网络中。因此需要先将存于TComPicYuv->m_piPicOrg[MAX_NUM_COMPONENT]
中的YUV像素信息以I420的格式输入到cv::Mat
中,然后再用cv::cvtColor(src,dst,CV_YUV2BGR_I420)转换为BGR格式。
在显示最终图像时,RGB图像出现了绿色竖线:
很是费解。顺藤摸瓜,于是我又imshow了中间以I420格式存储的YUV图像,也出现了竖线(imshow显示I420格式的YUV图像时只显示其Y分量,其实也就是灰度图像):
说明是我在将HM中本身的YUV导入cv::Mat时出现了问题。
于是debug监视前后两者的矩阵元素,发现了问题所在:
HM中YUV像素信息是用short类型存储的,是16位(可能跟我的操作系统有关);而cv::Mat我是采用的8UC1数据类型,是8位uchar类型。而我是采用memcpy内存拷贝函数进行的赋值,于是出现了以下问题:
HM中像素数据:
cv::Mat中数据:
可见,因为直接采用内存拷贝,导致后者要用两个8位空间存储之前一个16位的数据。用十六进制显示会更直白一些:
HM中像素数据:
cv::Mat中像素数据:
因此,需要在内存拷贝前先将原16位数据转换为8位,再进行拷贝;或者干脆直接用赋值语句进行赋值,强制转换为8位。
inputImg.at<uchar>(i, j) = srcYUV[j];
结论
Opencv显示RGB图像出现绿色竖线,且同时对应YUV图像也出现竖线,是因为前后图像位数不同导致的内存拷贝错误,原16位像素数据现在需要两个8位像素来存储,使得图像在横向上隔一个数据出现一次错误,从而在视觉上表现为密布的竖线。出现这种问题最好的方法就是直接查看图像矩阵的数据详情,查看是否是内存复制出现了问题。