如何测量图像某些区域中像素颜色的变化

时间:2016-07-17 22:43:14

标签: opencv colors pixel screen-capture

我的应用程序正在从监视器中截取屏幕截图(还没有其他内容)。有一个区域,要么变化很快,要么有点慢。我希望能够分辨出它是什么,并根据它我将选择行动方案(现在只需打印0或1)。我该怎么办?是否有类似于在几毫秒内改变了多少像素的度量?我应该比较最后两张图片还是其他什么?我可以使用其他方法吗?任何线索都会很棒!非常感谢你

编辑:我想学习使用OpenCV并玩游戏。我希望能够使用OpenCV阅读此游戏中发生的事情(窗口化)然后处理我看到的内容。有一个小游戏,有两种运动状态。一个很快,第二个很慢。所以设定一个目标来编写一个能够识别哪个

的应用程序

2 个答案:

答案 0 :(得分:0)

由于您使用opencv标记了问题,我假设您知道如何将屏幕截图读入cv::Mat。现在让我们使用cv::Rect roi来表示您有兴趣监控的区域。

您需要做的第一件事是定义“更改”。有许多方法可以测量两个图像之间的差异,例如Sum of absolute differences(SAD)或Normalized cross correlation(NCC)。根据您所描述的内容,听起来您正在寻找“更改像素的数量”。在这种情况下,您可以创建差异图像,然后计算图像中有多少非零元素(假设零表示相等):

cv::Mat diff = (f1(roi) != f2(roi));
double change = static_cast<double>(cv::countNonZero(diff))/roi.area();

此处f1f2是您要与之比较的两个屏幕截图,结果change将为您提供区域内已更改的像素数的比率({{ 1}})。

现在,通过此测量,您需要进一步定义“随时间变化”。假设你每50毫秒拍一张截图。确定它是快速更改还是缓慢更改的一种简单方法是将最后两个屏幕截图中的0 <= change <= 1与阈值进行比较,例如0.5。如果change,这是一个缓慢的变化,否则,这是一个快速的变化。根据您的应用程序,这可能会有效,也可能会太嘈杂。更强大的方法是在最后一秒(或500毫秒)计算change < 0.5的平均值。您可以使用Moving Average使其更加华丽。

答案 1 :(得分:0)

编辑5:13 7/18/2016

  

是否有类似于在几毫秒内改变了多少像素的度量?

     

我希望能够分辨出它是什么,并且根据它我将选择行动方案(现在只需打印0或1)。我该怎么做?

     

我应该比较最后两张图片还是别的什么?

你似乎在这里提出了很多问题,如果你将它们分开,这可能是最好的。

但是,要回答有关如何获取屏幕信息的具体问题,您需要使算法正常工作......您可以使用this之类的方法来处理来自Windows API的视频流。

我的建议是找到一种方法来记录一个非常短的流,其中包含大致准确的开始和结束时间,然后您可以使用此信息在您决定的时间轴上比较流中的每个帧,并且您可以计算像素delta作为cxyzs7提到的平均值... aka(以一种非常概念的方式)

//do in a loop of some kind of your choice
cv::Mat diff = (f1(roi) != f2(roi));
//followed by a calculation of how long it's been since the last change

if(diff == a_Mat_ofZeros)
     changeDetected[i++] = 1;
else changeDetected[i++] = 0;
//then track the changes through an array in a loop

here就是你投资回报率的方式。

或者,您可以使用本指南histogram calculation以便将值作为一组查找,然后比较直方图值的变化,以便检测特定值,颜色或饱和度等的变化......而不是投资回报率。

重要的是要确保每个帧都有准确的时间,这比基于视频流而不是一串单个屏幕上限更容易计算。

流中的屏幕大小将为您提供相对于彼此更准确的帧,因此屏幕输出和差异的计算之间会有一些延迟时间,但如果它是一个足够短的循环,它应该足够快,可以根据需要准确地为您提供结果。