今天给项目拷机,发现视频会偶现绿屏,非常偶现,很难复现出来。
由于问题暂时没有定位,只能先表面解决一下,就是过滤掉出现绿屏的帧。
当然,首先要把绿帧检测出来,才能做后续的补救措施。
绿屏、绿帧出现的时候,实际上就是一张全绿图像,它的R、B通道一般为0,G通道都为一个相同的值,比如我此次的:
R、B通道像素值为0,G通道像素值全都是153;
于是我们就可以直接使用均值、标准差来检测绿帧
#include <opencv4/opencv2/highgui.hpp>
#include <opencv4/opencv2/imgproc.hpp>
#include <iostream>
int main() {
cv::Mat mat = cv::imread("./绿屏.jpg");
cv::Scalar mean;
cv::Scalar dev;
auto s1 = std::chrono::system_clock::now();
mean = cv::mean(cv::Mat{mat, cv::Rect{0,0,100,100}});
auto s2 = std::chrono::system_clock::now();
auto dura = std::chrono::duration_cast<std::chrono::microseconds>(s2-s1);
std::cout << dura.count() << std::endl;
printf("%f,%f,%f\n", mean.val[0], mean.val[1], mean.val[2]);
if ( mean.val[0] < 5 && mean.val[2] < 5 && abs(mean.val[1] - 153) < 5 ) //此处的153只针对我自己的问题
printf("is green img\n");
cv::imshow(" ", mat);
cv::waitKey(10000);
}
首先解释一下cv::mean函数,它返回是三通道的均值,即R通道均值,G通道均值,B通道均值;
由于我的问题中的绿帧很稳定,我是指像素值很稳定,固定的[0,153,0],因此简单的均值就可以很好的检测出来。
如果你的绿帧没有这么“稳定”,那么可以试着放宽检测标准,比如这样:
if ( mean.val[0] < 5 && mean.val[2] < 5 && mean.val[1] > 100 )
或者也可以加上标准差,使用cv::meanStdDev函数,它的用法是:
void meanStdDev(const cv::Mat& src, cv::Scalar mean, cv::Scalar stddev);