Russian Qt Forum
Ноябрь 22, 2024, 13:01 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: некорректная отрисовка  (Прочитано 7870 раз)
bra1ss
Гость
« : Февраль 16, 2012, 14:23 »

Имеется камера, подключенная по Ethernet. В отдельном потоке с камеры граббятся кадры

Код:
void Camera::run()
{
   ...
   while (capture)
   {
      ...     // получение изображения через API камеры, генерация QImage image
      emit frameReady();
   }
}

QImage Camera::getImage()
{
    QMutexLocker locker(&mutex_image);
    return image;
}

соответственно в классе виджета

Код:
connect(&camera, SIGNAL(frameReady()), this, SLOT(update()));

void MainWidget::paintEvent(QPaintEvent *pe)
{
   QPainter painter(this);
   painter.drawImage(0, 0, camera.getImage());
 }

при отображении наблюдаются "проскоки" кадров (скрин)
кроме того, демонстрационная программа, поставляемая с камерой (написана тоже на Qt), имеет те же самые проблемы, техподдержка ничем не помогла
пробовал выводить видео средствами OpenCV - то же самое

разбирал сетевой трафик - пакеты не теряются, доходят в полном объеме
изменение разрешения/частоты кадров не влияет

но при этом если кадры сохранять например в jpg, то они сохраняются так как надо, целыми, так что проблема именно в отображении
грешу на оконную систему (Xorg), как-нибудь можно поднять ее производительность?

ОС - Ubuntu 10.04, x64.
Записан
Bepec
Гость
« Ответ #1 : Февраль 16, 2012, 14:29 »

Такое чуйство, что у вас просто смешиваются кадры Подмигивающий Попробуйте поставить задержку между передачей/грабом кадров.
Записан
bra1ss
Гость
« Ответ #2 : Февраль 16, 2012, 14:58 »

задержку в несколько миллисекунд ставил - результат тот же
Записан
Rem Norton
Гость
« Ответ #3 : Февраль 16, 2012, 15:04 »

Покажи, как создаешь поток и запускаешь.
Записан
bra1ss
Гость
« Ответ #4 : Февраль 16, 2012, 15:22 »

класс Camera унаследован от QThread, переопределен метод virtual void run()

В mainwidget.h объявлен объект данного класса
Код:
Camera camera;

В конструкторе MainWidget производится инициализация камеры и запуск потока
Код:
camera.init();    // в init происходят вызовы методов API камеры, необходимые для запуска
camera.start();

повторюсь, если кадры сохранять в файл вызовом camera.getImage().save, то никаких проблем нет, кадр сохраняется таким, каким он и должен быть, что-то не то с отображением
Записан
Bepec
Гость
« Ответ #5 : Февраль 16, 2012, 15:28 »

Задержка в несколько миллисекунд?Непонимающий

Поставь хотя бы секунду и тогда уже смотри.

Возможно у тебя наложение уже в памяти идёт? по 10 раз в 1 переменную данные не сбрасываешь?
Записан
Rem Norton
Гость
« Ответ #6 : Февраль 16, 2012, 15:48 »

Попробуй так:
Код
C++ (Qt)
Camera *camera = new Camera;
camera->moveToThread(camera);
// ну а потом init, start и т.д.
 
Записан
Bepec
Гость
« Ответ #7 : Февраль 16, 2012, 15:51 »

Вообще приведи полный код потока, который у тебя принимает кадры.
Записан
BRE
Гость
« Ответ #8 : Февраль 16, 2012, 15:58 »

2 bra1ss
Так а "проскоки" эти постоянно происходят, каждый кадр? Или иногда проскакивают?
Записан
bra1ss
Гость
« Ответ #9 : Февраль 17, 2012, 07:37 »

Задержка в несколько миллисекунд?Непонимающий

Поставь хотя бы секунду и тогда уже смотри.
нужно хотя бы 25 кадров в секунду иметь, задержку в секунду нельзя позволить

2 bra1ss
Так а "проскоки" эти постоянно происходят, каждый кадр? Или иногда проскакивают?
не постоянно, но достаточно часто, может раз в 50 кадров

код потока

camera.h
Код:
public:
   QImage getImage();
   virtual void run();
private:
   QImage image;
   QMutex mutex_image;
signals:
   void frameReady();

camera.cpp
Код:
while (capture)
{
// методы из API камеры
   GrabResult Result;
   StreamGrabber.RetrieveResult(Result);

   if (Grabbed == Result.Status())
   {
      mutex_image.lock();
      image = QImage::QImage(c_width, c_height, QImage::Format_ARGB32);
   // здесь происходит преобразование цветового формата, обновленный буфер записывается в image.bits()
      CPixelFormatConverterBayer converter;
      SImageFormat inputformat;
      inputformat.Width = c_width;
      inputformat.Height = c_height;
      inputformat.LinePitch = c_width;
      inputformat.PixelFormat = PixelType_BayerGB8;
      converter.Init(inputformat);
      SOutputImageFormat outputformat;
      outputformat.LinePitch = c_width*BPP;
      outputformat.PixelFormat = PixelType_RGBA8packed;

      converter.Convert(image.bits(), c_width*c_height*BPP, (uchar*)Result.Buffer(), c_width*c_height, inputformat, outputformat);
      emit frameReady();
      mutex_image.unlock();

   // Reuse the buffer for grabbing the next image
      StreamGrabber.QueueBuffer(Result.Handle(), NULL);
   }
}

QImage Camera::getImage()
{
    QMutexLocker locker(&mutex_image);
    return image;
}
Записан
Bepec
Гость
« Ответ #10 : Февраль 17, 2012, 07:44 »

ничего даже сказать не могу, но:

"нельзя позволить задержку в секунду" - Это не для релизной версии программы!!!!

А чтобы определить, есть ли ошибка в твоём коде.

Я бы на твоём месте сделал проще - буфер на 50-150 изображений. В него записывать и скидывать раз в секунду в виде коллекции изображений.
Потом просмотреть и понять, на каком и где и чем вызвано изменение Подмигивающий
Записан
Rem Norton
Гость
« Ответ #11 : Февраль 17, 2012, 10:08 »

ТС, давай весь код показывай. По отпечатку левой пятки никто диагноз не ставит.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.091 секунд. Запросов: 21.