我的应用程序正在从监视器上进行屏幕截图(还没有其他内容)。有一个区域,要么变化很快,要么变化有点慢。我想知道哪一个是它,根据它我会选择行动方案(现在只打印0或1)。我该怎么做?有没有类似的测量方法可以测量几毫秒内像素的变化?我应该比较最后两张照片还是其他什么?我还能用其他方法吗?任何线索都会很棒!非常感谢
编辑:我想学习使用OpenCV,我玩一个游戏。我希望能够使用OpenCV读取这个游戏(有窗口)中发生的事情,然后处理我看到的内容。有一个迷你游戏,有两种运动状态。一个很快,第二个很慢。因此,我们设定了一个目标,即编写一个应用程序,该应用程序将能够识别哪个是
2016年7月18日5:13编辑
有没有类似的测量方法可以测量几毫秒内像素的变化?
我想知道哪一个是它,根据它我会选择行动方案(现在只打印0或1)。我该怎么做?
我应该比较最后两张照片还是其他什么?
你似乎在问很多问题,最好把它们分开。
然而,为了回答如何获得屏幕信息的具体问题,你需要让你的算法发挥作用。。。您可以使用这样的方法来处理来自Windows API的视频流。
我的建议是找到一种方法,用最准确的开始和结束时间记录一个非常短的流,然后你可以使用这些信息在你决定的时间线上比较流中的每一帧,你可以计算像素增量作为cxyzs7提到的平均值。。。又称
//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
以下是您如何实现ROI的方法。
或者,您可以使用此指导直方图计算来查找作为一组的值,然后比较直方图值的变化,以检测特定值、颜色或饱和度等的变化,而不是ROI。
重要的是要确保每一帧都有一个准确的时间,这更容易根据视频流而不是一串单一的屏幕大小来计算。
流中的截屏将为您提供相对更准确的帧,因此在屏幕输出和差异计算之间会有一些滞后时间,但如果循环足够短,它应该足够快,可以根据需要准确地提供结果。
由于您用opencv标记了这个问题,我假设您知道如何将屏幕截图读取为cv::Mat
。现在,让我们使用cv::Rect roi
来表示您感兴趣监视的区域。
你需要做的第一件事就是定义"改变"。有许多方法可以测量两个图像之间的差异,例如,绝对差异之和(SAD)或归一化互相关(NCC)。根据你的描述,听起来你在寻找"改变像素的数量"。在这种情况下,你可以创建一个差异图像,然后计算图像中有多少非零元素(假设零意味着相等):
cv::Mat diff = (f1(roi) != f2(roi));
double change = static_cast<double>(cv::countNonZero(diff))/roi.area();
这里,f1
和f2
是您想要比较的两个屏幕截图,结果change
将为您提供区域内像素变化的比率(0 <= change <= 1
)。
现在,通过这种测量,您需要进一步定义"随时间变化"。假设你每50毫秒拍一张屏幕截图。判断这是快速变化还是缓慢变化的一种简单方法是将最后两张屏幕截图中的change
与阈值进行比较,比如0.5。如果change < 0.5
,则是缓慢的变化,否则,则是快速的变化。根据您的应用程序,这可能会起作用,也可能会太吵。更稳健的方法是计算最后一秒(或500ms)的change
的平均值。你可以用移动平均线来使它更花哨。