Results 1 to 14 of 14

Thread: Processing and Displaying Image on Widget

  1. #1
    Join Date
    Mar 2016
    Posts
    7
    Thanks
    2
    Qt products
    Qt5
    Platforms
    Windows

    Question Processing and Displaying Image on Widget

    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

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Processing and Displaying Image on Widget

    Well, your paintEvent() make the widget display text if the pixmap is null, which is the default state if the "pixmap" member.
    Since you haven't started the thread, it couldn't have sent an image yet, so the "pixmap" will stay null.

    Btw, your early exit in run() leaves the mutex locked and you are accessing "restart" once without proper locking.

    Cheers,
    _

  3. #3
    Join Date
    Mar 2016
    Posts
    7
    Thanks
    2
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Processing and Displaying Image on Widget

    Thanks for your quick response

    I have a problem with starting the thread. start function is in my render() routine in my RenderThread class. I have tried to call render routine from various locations in my code, but all of them resulted in crashing right at the startup of my application.

    I even added a timer event slot to my RenderThread class and call it when I construct the object of this class but got the same result, crashing about a second after the startup!
    I have no idea why my app crashes like this!
    you can see my code down here.

    Qt Code:
    1. private slots:
    2. void timerEvent(QTimerEvent *event);
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. RenderThread::RenderThread(QObject *parent)
    2. : QThread(parent)
    3. {
    4. restart = false;
    5. abort = false;
    6.  
    7. startTimer(500);
    8. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. void RenderThread::timerEvent(QTimerEvent *event)
    2. {
    3. Q_UNUSED(event);
    4.  
    5. render();
    6. }
    To copy to clipboard, switch view to plain text mode 

  4. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,229
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Processing and Displaying Image on Widget

    You are creating your QImage on the stack in your render thread, then passing it as a reference to your main window via a signal. Perhaps the crash is because the QImage has gone out of scope by the time the slot receives the reference. Try making the QImage either a member variable of the thread class or passing it by value (so a copy gets made).

    If you make it a member variable, then you might have concurrency problems if the main window is trying to read the image at the same time the render thread is changing it.

  5. #5
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Processing and Displaying Image on Widget

    Quote Originally Posted by d_stranz View Post
    You are creating your QImage on the stack in your render thread, then passing it as a reference to your main window via a signal. Perhaps the crash is because the QImage has gone out of scope by the time the slot receives the reference. Try making the QImage either a member variable of the thread class or passing it by value (so a copy gets made).
    No, I think that's ok.
    The image copied into a QVariant which is then put into an event and sent to the receiver object's event loop.
    While QImage is implicitly shared the "going out of scope" should make the copy inside the variant the only surviving reference and thus safe to access from the main thread.

    Quote Originally Posted by mhb88 View Post
    I have a problem with starting the thread. start function is in my render() routine in my RenderThread class. I have tried to call render routine from various locations in my code, but all of them resulted in crashing right at the startup of my application.
    Then you'll have to debug why it crashes.
    Not running the image source will not give you any images.

    My guess is that you are accessing memory areas that are not valid while looping over the image.
    Your inner loop's step size is 1 uint per loop, an uint is usually 4 bytes.
    But your image format is one byte per pixel.

    Cheers,
    _
    Last edited by anda_skoa; 28th March 2016 at 19:35.

  6. The following user says thank you to anda_skoa for this useful post:

    mhb88 (28th March 2016)

  7. #6
    Join Date
    Mar 2016
    Posts
    7
    Thanks
    2
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Processing and Displaying Image on Widget

    Quote Originally Posted by anda_skoa View Post
    My guess is that you are accessing memory areas that are not valid while looping over the image.
    Your inner loop's step size is 1 uint per loop, an uint is usually 4 bytes.
    But your image format is one byte per pixel.
    oh, Wow!! I can't believe that I let this warning confuse me!!

    uchar *QImage::scanLine(int i)
    Returns a pointer to the pixel data at the scanline with index i. The first scanline is at index 0.
    The scanline data is aligned on a 32-bit boundary.
    Warning: If you are accessing 32-bpp image data, cast the returned pointer to QRgb* (QRgb has a 32-bit size) and use it to read/write the pixel value. You cannot use the uchar* pointer directly, because the pixel format depends on the byte order on the underlying platform. Use qRed(), qGreen(), qBlue(), and qAlpha() to access the pixels.
    thank you very much anda_skoa

    cheers

  8. #7
    Join Date
    Mar 2016
    Posts
    7
    Thanks
    2
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Processing and Displaying Image on Widget

    as you see in my code I posted at the beginning of this thread, I have bunch of classes already in my project and I am going to add a few more as I progress in my project. I came up with the idea to add a TextEdit to my mainwindow.ui and called it Console to display some text there through out my code.
    I want to be able to do this from all my classes.
    At first I thought there is no easier task than this, but apparently I can't find a solution.
    would you guys help me on this?

    cheers

  9. #8
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Processing and Displaying Image on Widget

    You have different options:

    - add signals that emit new "console" text to classes that need it and connect to the text edit or a slot in main window
    - pass the pointer to the text edit or main window to wherever this is needed
    - make the pointer to the text edit or the main window globally accessible

    Cheers,
    _

  10. The following user says thank you to anda_skoa for this useful post:

    mhb88 (31st March 2016)

  11. #9
    Join Date
    Mar 2016
    Posts
    7
    Thanks
    2
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Processing and Displaying Image on Widget

    OK, I got everything working as the base of my project. At this point I can communicate with camera, and receive its frames, and just display them in my widget.
    But I have an issue.
    My camera supports up to 100 frames/sec, but I am barely displaying 15 frames/sec.
    My camera resolution is 480x640 and I am just receiving 8bits grayscale frames. So each frame has 480 x 640 x 8 = 300KBytes of data and if I want to receive them at rate of 100 fps, I have to receive them 300KBytes/frame x 100 frames/sec = 30000 KBytes/sec, about 30MBytes/sec, which is half of the speed of the USB2.0. So I think my USB2.0 should be able to do handle that amount of data transfer.

    So I think the issue is in my software, but I am not doing any processing in my code, I am just displaying frames. I have created a class with a paint event, and I have promoted a Qwidget to this class to display on it.

    I don't know if Qwidget can handle transferring this amount of data?
    Does any one has any suggestion or solution?

    cheers

  12. #10
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Processing and Displaying Image on Widget

    For such high througput rendering you probably have to use a more direct rendering approach, e.g. OpenGL.

    It might be worthwhile to look into creating a QCamera backend and then use the existing video widget infrastructure.

    Cheers,
    _

  13. #11
    Join Date
    Mar 2016
    Posts
    7
    Thanks
    2
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Processing and Displaying Image on Widget

    Do you know any tutorials that start from foundation and builds up to it?
    I don't have any experience with OpenGL.
    I found most tutorials to be about QGLWidget.
    But in the new versions of Qt 5, QOpenGLWidget is intended to be a modern replacement for QGLWidget.
    I haven't been able find a good tutorial for QOpenGLWidget.

    cheers

  14. #12
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Processing and Displaying Image on Widget

    No, sorry, I haven't had anything to do with that yet myself either.

    Cheers,
    _

  15. #13
    Join Date
    Mar 2016
    Posts
    7
    Thanks
    2
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Processing and Displaying Image on Widget

    I was wondering if this would work?
    a function is getting a pointer to a QImage as a parameter.
    I want to copy the entire QImage to a buffer of that is going to hold 100 QImages.

    Qt Code:
    1. public:
    2. void function(QImage *frame);
    3.  
    4. protected:
    5. enum{size = 100};
    6. QImage *data[size];
    7. int front; // points to the front of the buffer
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. void Buffer::function(QImage *frame)
    2. {
    3. ++front; // Increment front.
    4. if (front == size)
    5. front = 0; // Wrap around.
    6.  
    7. data[front] = frame;
    8. }
    To copy to clipboard, switch view to plain text mode 

    cheers

  16. #14
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Processing and Displaying Image on Widget

    Sure, why not.
    I assume you handle deletion of the QImage pointers somewhere else?

    Cheers,
    _

Similar Threads

  1. Replies: 7
    Last Post: 2nd December 2013, 17:06
  2. image processing
    By IRON_MAN in forum Qt Programming
    Replies: 4
    Last Post: 18th November 2009, 14:37
  3. Image processing
    By NicNac in forum Newbie
    Replies: 25
    Last Post: 2nd November 2008, 11:05
  4. Image processing via matrix
    By jones.79 in forum Qt Programming
    Replies: 10
    Last Post: 22nd September 2008, 01:42
  5. Image Processing using Qt
    By danielperaza in forum Qt Programming
    Replies: 2
    Last Post: 9th March 2008, 19:15

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.