In the last post, we solved the issue about sizing, however I mentioned that, I needed to adapt a few things. Except the usual little code optimization and cleanups, there were two main things: the color approximation, and the way we process the frames.
The main idea about the buckets was good. The issue came in at the extremes, the smallest and largest cells. If you remember there was a threshold set to 5, being the acceptable difference in buckets in order to count that color. Well for the smallest images it was too small and excluded the actual cell value. If I adjusted it to bigger then there were some misreadings (although in hindsight these might have been caused by the frame processing). But let’s look at what I did.
void GameImageAnalyzer::ExtractColor(Mat* src, int* col, Rect roi)
{
int stx = roi.x;
int sty = roi.y;
int enx = roi.x + roi.width;
int eny = roi.y + roi.height;
int count = 0;
int totals[3]{ 0 };
for (int i = stx; i < enx; i++)
{
for (int j = sty; j < eny; j++)
{
auto c = src->at<Vec3b>(j, i);
auto diff01 = abs(c.val[0] - c.val[1]);
auto diff02 = abs(c.val[0] - c.val[2]);
auto diff12 = abs(c.val[1] - c.val[2]);
// detect grayish color
if (max(diff01, max(diff02, diff12)) < 30)
continue;
totals[0] += c.val[0];
totals[1] += c.val[1];
totals[2] += c.val[2];
count++;
}
}
if (count > 0)
{
col[0] = totals[0] / count;
col[1] = totals[1] / count;
col[2] = totals[2] / count;
col[3] = (100 * count) / (roi.width * roi.height);
}
}