Hello everyone,

It's been a while that I am trying to come up with a method to do some image processing and displaying results in a Widget, that is a child of MainWindow, on frames that I get from a camera (maybe at rate of 25 frames/sec). So, I started by reading tones of documents and forums and etc to find the method, and so far I have been able to implement this application. Since image processing algorithms are computationally intensive, I thought it would be a good idea to use QThread in my project. I found mandelbrot example extremely useful for my purpose.
http://doc.qt.io/qt-5/qtcore-threads...t-example.html

Like the example:
  • I created a class to display image (mQtPaintWidget). Then I added a Widget to my central widget in mainwindow.ui and promoted to this class and called it Screen. I also added a Text Edit to my central widget and called it Console.
  • I created a class to assign a thread for my image processing algorithms (RenderThread).



Before writing a class to handle my camera, I wanted to test if I can display noise using qrand() function but it does not run the way I expect. I got it to work till the paintevent checks the pixmap to see if it is NULL and draws a text on Screen.
I copied my codes down here. I would appreciate if any body can suggest any solution.

cheers



main.cpp
Qt Code:
  1. #include "mainwindow.h"
  2. #include <QApplication>
  3.  
  4. int main(int argc, char *argv[])
  5. {
  6. QApplication app(argc, argv);
  7. MainWindow w;
  8. w.show();
  9.  
  10. return app.exec();
  11. }
To copy to clipboard, switch view to plain text mode 

mainwindow.h
Qt Code:
  1. #ifndef MAINWINDOW_H
  2. #define MAINWINDOW_H
  3.  
  4. #include <QMainWindow>
  5. #include <QWidget>
  6.  
  7. namespace Ui {
  8. class MainWindow;
  9. }
  10.  
  11. class MainWindow : public QMainWindow
  12. {
  13. Q_OBJECT
  14.  
  15. public:
  16. explicit MainWindow(QWidget *parent = 0);
  17. ~MainWindow();
  18.  
  19. private:
  20. Ui::MainWindow *ui;
  21. };
  22.  
  23. #endif // MAINWINDOW_H
To copy to clipboard, switch view to plain text mode 

mainwindow.cpp
Qt Code:
  1. #include "mainwindow.h"
  2. #include "ui_mainwindow.h"
  3.  
  4. MainWindow::MainWindow(QWidget *parent) :
  5. QMainWindow(parent),
  6. ui(new Ui::MainWindow)
  7. {
  8. ui->setupUi(this);
  9.  
  10. QPalette p = palette();
  11. p.setColor(QPalette::Base, Qt::black);
  12. p.setColor(QPalette::Text, Qt::green);
  13. ui->Console->setPalette(p);
  14. }
  15.  
  16. MainWindow::~MainWindow()
  17. {
  18. delete ui;
  19. }
To copy to clipboard, switch view to plain text mode 

renderthread.h
Qt Code:
  1. #ifndef RENDERTHREAD_H
  2. #define RENDERTHREAD_H
  3.  
  4. #include <QWidget>
  5. #include <QMutex>
  6. #include <QThread>
  7. #include <QWaitCondition>
  8.  
  9. QT_BEGIN_NAMESPACE
  10. class QImage;
  11. QT_END_NAMESPACE
  12.  
  13. class RenderThread : public QThread
  14. {
  15. Q_OBJECT
  16.  
  17. public:
  18. RenderThread(QObject *parent = 0);
  19. ~RenderThread();
  20.  
  21. void render();
  22.  
  23. signals:
  24. void renderedImage(const QImage &image);
  25.  
  26. protected:
  27. void run() Q_DECL_OVERRIDE;
  28.  
  29. private:
  30. QMutex mutex;
  31. QWaitCondition condition;
  32. QSize frameSize;
  33. bool restart;
  34. bool abort;
  35. };
  36.  
  37. #endif // RENDERTHREAD_H
To copy to clipboard, switch view to plain text mode 

renderthread.cpp
Qt Code:
  1. #include "renderthread.h"
  2.  
  3. RenderThread::RenderThread(QObject *parent)
  4. : QThread(parent)
  5. {
  6. restart = false;
  7. abort = false;
  8. }
  9.  
  10. RenderThread::~RenderThread()
  11. {
  12. mutex.lock();
  13. abort = true;
  14. condition.wakeOne();
  15. mutex.unlock();
  16.  
  17. wait();
  18. }
  19.  
  20. void RenderThread::render()
  21. {
  22. QMutexLocker locker(&mutex);
  23.  
  24. if (!isRunning()) {
  25. start(LowPriority);
  26. } else {
  27. restart = true;
  28. condition.wakeOne();
  29. }
  30. }
  31.  
  32. void RenderThread::run()
  33. {
  34. forever
  35. {
  36. mutex.lock();
  37. if (restart || abort)
  38. return;
  39. mutex.unlock();
  40.  
  41. uint imWidth = 600;
  42. uint imHeight = 480;
  43. QSize frameSize(imWidth,imHeight);
  44. QImage image(frameSize,QImage::Format_Indexed8);
  45.  
  46. for(uint i = 0; i < imHeight; ++i)
  47. {
  48. uint *scanLine = reinterpret_cast<uint *>(image.scanLine(i));
  49. for(uint j = 0; j < imWidth; ++j)
  50. *scanLine++ = (qrand() > RAND_MAX/2) * 255;
  51. }
  52.  
  53. if (!restart)
  54. emit renderedImage(image);
  55.  
  56. mutex.lock();
  57. if (!restart)
  58. condition.wait(&mutex);
  59. restart = false;
  60. mutex.unlock();
  61. }
  62.  
  63. }
To copy to clipboard, switch view to plain text mode 

mqtpaintwidget.h
Qt Code:
  1. #ifndef MQTPAINTERWIDGET_H
  2. #define MQTPAINTERWIDGET_H
  3.  
  4. #include <QWidget>
  5. #include <QPixmap>
  6. #include <QPainter>
  7. #include "renderthread.h"
  8.  
  9. class mQtPainterWidget : public QWidget
  10. {
  11. Q_OBJECT
  12. public:
  13. explicit mQtPainterWidget(QWidget *parent = 0);
  14.  
  15. protected:
  16. void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
  17.  
  18. private slots:
  19. void updatePixmap(const QImage &image);
  20.  
  21. private:
  22. RenderThread thread;
  23. QPixmap pixmap;
  24. };
  25.  
  26. #endif // MQTPAINTERWIDGET_H
To copy to clipboard, switch view to plain text mode 

mqtpaintwidget.cpp
Qt Code:
  1. #include "mqtpainterwidget.h"
  2.  
  3. mQtPainterWidget::mQtPainterWidget(QWidget *parent) :
  4. QWidget(parent)
  5. {
  6. connect(&thread, SIGNAL(renderedImage(QImage)), this, SLOT(updatePixmap(QImage)));
  7. //thread.render();
  8. }
  9.  
  10. void mQtPainterWidget::paintEvent(QPaintEvent *event)
  11. {
  12. Q_UNUSED(event);
  13.  
  14. QPainter painter(this);
  15. painter.fillRect(rect(), Qt::black);
  16.  
  17. if (pixmap.isNull()) {
  18. painter.setPen(Qt::green);
  19. painter.drawText(rect(), Qt::AlignCenter, tr("Rendering initial image, please wait..."));
  20. return;
  21. }
  22.  
  23. painter.drawPixmap(0,0,pixmap);
  24. }
  25.  
  26. void mQtPainterWidget::updatePixmap(const QImage &image)
  27. {
  28. pixmap = QPixmap::fromImage(image);
  29. update();
  30. }
To copy to clipboard, switch view to plain text mode 

screenshot.jpg