Сравнение двух изображений неверноC++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Сравнение двух изображений неверно

Сообщение Anonymous »

Я работаю над приложением, которое измеряет FPS в определенной области. Проблема в том, что если в зоне ничего не происходит, я хочу, чтобы значение fps было равно 0. Но когда я начинаю измерение и, например, перемещаю окно близко к тому месту, где происходит измерение, значение fps меняется. Как будто область, которую я измеряю, больше, чем мне на самом деле нужно.
Я даже пытался сохранить сравниваемые QImages, и визуально разницы нет. Таким образом, сравнение двух QImage должно было вернуть false, но оно вернуло true.
Вот мой код:

Код: Выделить всё

#include "framecounter.h"

FrameCounter::FrameCounter(QWidget* parent) : QWidget(parent)
{
// Connect the captureTimer's timeout signal to the captureScreen slot.
connect(&m_captureTimer, &QTimer::timeout, this, &FrameCounter::captureScreen);

m_elapsedTimer.start(); // Start the elapsed timer.
}

void FrameCounter::captureScreen()
{
#ifdef Q_OS_MAC
// Capture the screen using Core Graphics
CGImageRef cgImage = CGWindowListCreateImage(CGRectMake(m_x, m_y, m_size, m_size), kCGWindowListOptionOnScreenOnly, kCGNullWindowID, kCGWindowImageDefault);
QImage screenCapture = CGImageToQImage(cgImage);
CGImageRelease(cgImage);
#else
// Capture the screen using Qt
QScreen* screen = QGuiApplication::primaryScreen();
if (!screen)
return;

QImage screenCapture = screen->grabWindow(0, m_x, m_y, m_size, m_size).toImage();
#endif

if (!m_previousFrame.isNull() &&  screenCapture != m_previousFrame)
{
++m_frameCount;
}

m_previousFrame = screenCapture;
calculateFps();
}

void FrameCounter::calculateFps()
{
qint64 elapsed = m_elapsedTimer.elapsed();
//Calculate the current FPS and update the list of FPS values every 300 milliseconds.
if (elapsed >= 300)
{
m_currentFps = static_cast(m_frameCount) / (static_cast(elapsed) / 1000.0);
if(m_currentFps!=0){
m_listOfFps.append(m_currentFps);
}

// Reset the frame count and restart the timer.
m_frameCount = 0;
m_elapsedTimer.restart();
emit newfpsvalue();
}
}

void FrameCounter::startMeasurement(int x, int y, int size)
{
// Define the measurement area and start timers
m_x = x;
m_y = y;
m_size = size;
// Start the capture timer to capture frames every 16 milliseconds.
m_captureTimer.start(16);

m_elapsedTimer.restart();
}

void FrameCounter::stopMeasurement()
{
m_captureTimer.stop();

// Reset FPS and clear the list of FPS values.
m_currentFps = 0;
m_listOfFps.clear();
}

double FrameCounter::getCurrentFps() const
{
// Return the current FPS value.
return m_currentFps;
}

#ifdef Q_OS_MAC
CGBitmapInfo FrameCounter::CGBitmapInfoForQImage(const QImage &image)
{
CGBitmapInfo bitmapInfo = kCGImageAlphaNone;

switch (image.format()) {
case QImage::Format_ARGB32:
bitmapInfo = kCGImageAlphaFirst | kCGBitmapByteOrder32Host;
break;
case QImage::Format_RGB32:
bitmapInfo = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host;
break;
case QImage::Format_RGBA8888_Premultiplied:
bitmapInfo = kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big;
break;
case QImage::Format_RGBA8888:
bitmapInfo = kCGImageAlphaLast | kCGBitmapByteOrder32Big;
break;
case QImage::Format_RGBX8888:
bitmapInfo = kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Big;
break;
case QImage::Format_ARGB32_Premultiplied:
bitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host;
break;
default:
break;
}

return bitmapInfo;
}

QImage FrameCounter::CGImageToQImage(CGImageRef cgImage)
{
const size_t width = CGImageGetWidth(cgImage);
const size_t height = CGImageGetHeight(cgImage);
QImage image(static_cast(width), static_cast(height), QImage::Format_ARGB32_Premultiplied);
image.fill(Qt::transparent);

CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
CGContextRef context = CGBitmapContextCreate(static_cast(image.bits()), static_cast(image.width()), static_cast(image.height()), 8,
static_cast(image.bytesPerLine()), colorSpace, CGBitmapInfoForQImage(image));

// Scale the context so that painting happens in device-independent pixels
const qreal devicePixelRatio = image.devicePixelRatio();
CGContextScaleCTM(context, devicePixelRatio, devicePixelRatio);

CGRect rect = CGRectMake(0, 0, width, height);
CGContextDrawImage(context, rect, cgImage);

CFRelease(colorSpace);
CGContextRelease(context);

return image;
}
#endif
Кто-нибудь знает, в чем может быть причина этого? Связано ли это с захватом или сравнением QImage?
Если это может помочь, если я измеряю область, где верхний левый угол имеет эти координаты (300,300) а при размере (250 250) значение FPS меняется всякий раз, когда что-то происходит в области с верхним левым углом примерно (245 205) и размером примерно (360 375).
РЕДАКТИРОВАНИЕ:
Как было предложено, я сравнил значения пикселей и увидел, что, когда окно приближается к некоторым значениям RGB, происходит небольшое изменение, поэтому я реализовал функцию, которая сравнивает два QImage. и терпеть небольшие изменения:

Код: Выделить всё

bool FrameCounter::framesAreEqual(const QImage& img1, const QImage& img2) const
{
if (img1.size() != img2.size())
return false;

int width  = img1.width();
int height = img1.height();

for (int y = 0; y < height; ++y)
{
for (int x = 0; x < width; ++x)
{
QRgb pixel1 = img1.pixel(x, y);
QRgb pixel2 = img2.pixel(x, y);

int redDiff   = qAbs(qRed(pixel1) - qRed(pixel2));
int greenDiff = qAbs(qGreen(pixel1) - qGreen(pixel2));
int blueDiff  = qAbs(qBlue(pixel1) - qBlue(pixel2));
if (redDiff > 15 || greenDiff > 15 || blueDiff > 15)
{
return false;
}
}
}

return true;
}
Это работает, но меня все еще не полностью устраивает это решение. Кто-нибудь знает, почему значение пикселя меняется при движении близко к области, где происходит измерение?
РЕДАКТИРОВАТЬ 2:
Проблема заключалась в том, что тень окон. Когда окно приближается, его тень попадает в область измерения.

Подробнее здесь: https://stackoverflow.com/questions/785 ... s-is-wrong
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Сравнение двух изображений неверно
    Anonymous » » в форуме C++
    0 Ответы
    12 Просмотры
    Последнее сообщение Anonymous
  • Проверка проверки активов неверно неверно исполняется. Исполняемый файл 'myapp.app/frameworks/cardio.framework/cardio' с
    Anonymous » » в форуме IOS
    0 Ответы
    23 Просмотры
    Последнее сообщение Anonymous
  • Streamlit ляплят, что неверно, неверно, при работе с глобальной установки от Global Install
    Anonymous » » в форуме Python
    0 Ответы
    14 Просмотры
    Последнее сообщение Anonymous
  • Сравнение двух изображений в PHP
    Anonymous » » в форуме Php
    0 Ответы
    13 Просмотры
    Последнее сообщение Anonymous
  • Сравнение двух изображений с помощью PHP
    Anonymous » » в форуме Php
    0 Ответы
    12 Просмотры
    Последнее сообщение Anonymous

Вернуться в «C++»