Results 1 to 10 of 10

Thread: Replace Pixmap in GraphicsScene

  1. #1
    Join Date
    Dec 2012
    Posts
    13
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Replace Pixmap in GraphicsScene

    I'd really like to attach to my web camera, process the frames I get out of it, and then display the processed frame in a window with some super-imposed markings.

    The strategy I've been trying is to have a QGraphicsView with a QGraphicsScene that has a QGraphicsPixmap added. I then use a custom VideoSurface to grab frames. Right now I'm trying to just transfer the frames to the QGraphicsView (no extra markings or processing) but if I call setPixmap the program will crash just after the frame handler returns. If I skip the call to setPixmap, it doesn't crash. Could anyone point me in the right direction?

    Qt Code:
    1. MainWindow::MainWindow(QWidget *parent) :
    2. QMainWindow(parent),
    3. ui(new Ui::MainWindow),
    4. frame(640, 480)
    5. {
    6. ui->setupUi(this);
    7. QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
    8. cam = new QCamera(cameras.first(), this);
    9. cam->load();
    10. frame_grabber = new CameraFrameGrabber();
    11. cam->setViewfinder(frame_grabber);
    12. cam->setCaptureMode(QCamera::CaptureViewfinder);
    13. connect(frame_grabber, SIGNAL(frameAvailable(QImage)), this, SLOT(handleFrame(QImage)));
    14. cam->start();
    15. frame_timer.start();
    16. scene = new QGraphicsScene();
    17. pix = new QGraphicsPixmapItem(frame);
    18. scene->addItem(pix);
    19. ui->gv_viewfinder->setScene(scene);
    20. }
    21.  
    22. MainWindow::~MainWindow()
    23. {
    24. delete ui;
    25. }
    26.  
    27. void MainWindow::handleFrame(const QImage& img)
    28. {
    29. frame_times.push_back(frame_timer.elapsed());
    30. frame_timer.restart();
    31. if (frame_times.size() > 10) frame_times.pop_front();
    32. int frame_count = frame_times.size();
    33. int frame_total = 0;
    34. for(int i = 0; i < frame_count; ++i)
    35. {
    36. frame_total += frame_times[i];
    37. }
    38. double fps = 0;
    39. if (frame_count)
    40. {
    41. fps = (frame_total / frame_count);
    42. }
    43. ui->sb_fps->setValue(fps);
    44.  
    45. bool good_pix = frame.convertFromImage(img);
    46. if (good_pix) pix->setPixmap(frame);
    47. this->update();
    48. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. bool CameraFrameGrabber::present(const QVideoFrame &frame)
    2. {
    3. if (frame.isValid()) {
    4. QVideoFrame cloneFrame(frame);
    5. cloneFrame.map(QAbstractVideoBuffer::ReadOnly);
    6. const QImage image(cloneFrame.bits(),
    7. cloneFrame.width(),
    8. cloneFrame.height(),
    9. QVideoFrame::imageFormatFromPixelFormat(cloneFrame .pixelFormat()));
    10. emit frameAvailable(image);
    11. cloneFrame.unmap();
    12. return true;
    13. }
    14. return false;
    15. }
    To copy to clipboard, switch view to plain text mode 

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

    Default Re: Replace Pixmap in GraphicsScene

    The observed behavior would suggest that the "pix" pointer is not valid, thus accessing it crashes.

    Can you try initializing it before starting the camera?

    Cheers,
    _

  3. #3
    Join Date
    Dec 2012
    Posts
    13
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Replace Pixmap in GraphicsScene

    That was a good thought! But it doesn't seem to be the issue. I've also tried a slightly different approach in the handleFrame method, but it doesn't seem to make a difference either.

    The thing is that it doesn't actually crash in handleFrame. I guess it crashes somewhere in the event handler. Certainly it is a null pointer, but the null pointer is way down the stack during a memcpy operation.

    I've included the stack trace as well.


    The current code:
    Qt Code:
    1. MainWindow::MainWindow(QWidget *parent) :
    2. QMainWindow(parent),
    3. ui(new Ui::MainWindow),
    4. frame(640, 480)
    5. {
    6. ui->setupUi(this);
    7. scene = new QGraphicsScene();
    8. pix = new QGraphicsPixmapItem(frame);
    9. scene->addItem(pix);
    10. ui->gv_viewfinder->setScene(scene);
    11. QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
    12. cam = new QCamera(cameras.first(), this);
    13. cam->load();
    14. frame_grabber = new CameraFrameGrabber();
    15. cam->setViewfinder(frame_grabber);
    16. cam->setCaptureMode(QCamera::CaptureViewfinder);
    17. connect(frame_grabber, SIGNAL(frameAvailable(QImage)), this, SLOT(handleFrame(QImage)));
    18. cam->start();
    19. frame_timer.start();
    20.  
    21. }
    22.  
    23. MainWindow::~MainWindow()
    24. {
    25. delete ui;
    26. }
    27.  
    28. void MainWindow::handleFrame(const QImage& img)
    29. {
    30. frame_times.push_back(frame_timer.elapsed());
    31. frame_timer.restart();
    32. if (frame_times.size() > 10) frame_times.pop_front();
    33. int frame_count = frame_times.size();
    34. int frame_total = 0;
    35. for(int i = 0; i < frame_count; ++i)
    36. {
    37. frame_total += frame_times[i];
    38. }
    39. double fps = 0;
    40. if (frame_count)
    41. {
    42. fps = (frame_total / frame_count);
    43. }
    44. ui->sb_fps->setValue(fps);
    45.  
    46. scene->removeItem(pix);
    47. delete pix;
    48. frame = QPixmap::fromImage(img);
    49. pix = scene->addPixmap(frame);
    50. scene->invalidate();
    51.  
    52. this->update();
    53. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. 1 memcpy VCRUNTIME140D 0x7ffc229b1e10
    2. 2 qt_blend_rgb32_on_rgb32 qblendfunctions.cpp 399 0x7ffbfbf7bb85
    3. 3 qt_blend_rgb32_on_rgb32_sse2 qdrawhelper_sse2.cpp 139 0x7ffbfc32c17d
    4. 4 QRasterPaintEnginePrivate::drawImage qpaintengine_raster.cpp 1021 0x7ffbfc03b9bd
    5. 5 QRasterPaintEngine::drawImage qpaintengine_raster.cpp 2133 0x7ffbfc03235b
    6. 6 QRasterPaintEngine::drawPixmap qpaintengine_raster.cpp 2019 0x7ffbfc03163b
    7. 7 QPainter::drawPixmap qpainter.cpp 5070 0x7ffbfc05799c
    8. 8 QGraphicsPixmapItem::paint qgraphicsitem.cpp 9769 0x5de350bf
    9. 9 QGraphicsScenePrivate::draw qgraphicsscene.cpp 4961 0x5de7fe17
    10. 10 QGraphicsScenePrivate::drawSubtreeRecursive qgraphicsscene.cpp 4855 0x5de7f73b
    11. 11 QGraphicsScenePrivate::drawItems qgraphicsscene.cpp 4714 0x5de7e9a0
    12. 12 QGraphicsView::paintEvent qgraphicsview.cpp 3551 0x5dec8c82
    13. 13 QWidget::event qwidget.cpp 8931 0x5d910fb1
    14. 14 QFrame::event qframe.cpp 550 0x5db0c62f
    15. 15 QAbstractScrollArea::viewportEvent qabstractscrollarea.cpp 1213 0x5dbfe81c
    16. 16 QGraphicsView::viewportEvent qgraphicsview.cpp 2974 0x5dec66a4
    17. 17 QAbstractScrollAreaPrivate::viewportEvent qabstractscrollarea_p.h 111 0x5d899c55
    18. 18 QAbstractScrollAreaFilter::eventFilter qabstractscrollarea_p.h 127 0x5dc0375d
    19. 19 QCoreApplicationPrivate::sendThroughObjectEventFilters qcoreapplication.cpp 1099 0x5d0f8644
    20. 20 QApplicationPrivate::notify_helper qapplication.cpp 3795 0x5d8a5e6e
    21. 21 QApplication::notify qapplication.cpp 3762 0x5d8a34c9
    22. 22 QCoreApplication::notifyInternal2 qcoreapplication.cpp 988 0x5d0f78c6
    23. 23 QCoreApplication::sendSpontaneousEvent qcoreapplication.h 234 0x5d264c3b
    24. 24 QWidgetPrivate::sendPaintEvent qwidget.cpp 5699 0x5d91af5d
    25. 25 QWidgetPrivate::drawWidget qwidget.cpp 5640 0x5d91aa57
    26. 26 QWidgetBackingStore::doSync qwidgetbackingstore.cpp 1357 0x5d8bf802
    27. 27 QWidgetBackingStore::sync qwidgetbackingstore.cpp 1152 0x5d8bc8a3
    28. 28 QWidgetPrivate::syncBackingStore qwidget.cpp 1957 0x5d91d650
    29. 29 QWidget::event qwidget.cpp 9084 0x5d911617
    30. 30 QMainWindow::event qmainwindow.cpp 1544 0x5db380b1
    31. 31 QApplicationPrivate::notify_helper qapplication.cpp 3799 0x5d8a5e8e
    32. 32 QApplication::notify qapplication.cpp 3762 0x5d8a34c9
    33. 33 QCoreApplication::notifyInternal2 qcoreapplication.cpp 988 0x5d0f78c6
    34. 34 QCoreApplication::sendEvent qcoreapplication.h 231 0x5d1027f2
    35. 35 QCoreApplicationPrivate::sendPostedEvents qcoreapplication.cpp 1649 0x5d0f9112
    36. 36 QCoreApplication::sendPostedEvents qcoreapplication.cpp 1504 0x5d0f5c4c
    37. 37 QGraphicsViewPrivate::dispatchPendingUpdateRequests qgraphicsview_p.h 204 0x5d88ec31
    38. 38 QGraphicsScenePrivate::_q_emitUpdated qgraphicsscene.cpp 383 0x5de7751b
    39. 39 QGraphicsScene::qt_static_metacall moc_qgraphicsscene.cpp 180 0x5de6e856
    40. 40 QMetaCallEvent::placeMetaCall qobject.cpp 503 0x5d156c81
    41. 41 QObject::event qobject.cpp 1263 0x5d14f6df
    42. 42 QGraphicsScene::event qgraphicsscene.cpp 3522 0x5de74608
    43. 43 QApplicationPrivate::notify_helper qapplication.cpp 3799 0x5d8a5e8e
    44. 44 QApplication::notify qapplication.cpp 3159 0x5d8a0713
    45. 45 QCoreApplication::notifyInternal2 qcoreapplication.cpp 988 0x5d0f78c6
    46. 46 QCoreApplication::sendEvent qcoreapplication.h 231 0x5d1027f2
    47. 47 QCoreApplicationPrivate::sendPostedEvents qcoreapplication.cpp 1649 0x5d0f9112
    48. 48 QEventDispatcherWin32::sendPostedEvents qeventdispatcher_win.cpp 1295 0x5d1b180a
    49. 49 QWindowsGuiEventDispatcher::sendPostedEvents qwindowsguieventdispatcher.cpp 82 0x7ffbfddfc204
    50. 50 qt_internal_proc qeventdispatcher_win.cpp 445 0x5d1af521
    51. 51 CallWindowProcW USER32 0x7ffc29f41c24
    52. 52 DispatchMessageW USER32 0x7ffc29f4156c
    53. 53 QEventDispatcherWin32::processEvents qeventdispatcher_win.cpp 845 0x5d1aff2b
    54. 54 QWindowsGuiEventDispatcher::processEvents qwindowsguieventdispatcher.cpp 74 0x7ffbfddfc1c4
    55. 55 QEventLoop::processEvents qeventloop.cpp 135 0x5d0f24e8
    56. 56 QEventLoop::exec qeventloop.cpp 210 0x5d0f272e
    57. 57 QCoreApplication::exec qcoreapplication.cpp 1261 0x5d0f55ff
    58. 58 QGuiApplication::exec qguiapplication.cpp 1640 0x7ffbfbc63208
    59. 59 QApplication::exec qapplication.cpp 2976 0x5d8a021a
    60. 60 main main.cpp 10 0x7ff6596b2759
    61. 61 WinMain qtmain_win.cpp 123 0x7ff6596bb14d
    62. 62 invoke_main exe_common.inl 109 0x7ff6596b8d7d
    63. 63 __scrt_common_main_seh exe_common.inl 264 0x7ff6596b8c1e
    64. 64 __scrt_common_main exe_common.inl 309 0x7ff6596b8ade
    65. 65 WinMainCRTStartup exe_winmain.cpp 17 0x7ff6596b8d99
    66. 66 BaseThreadInitThunk KERNEL32 0x7ffc2a4a8364
    67. 67 RtlUserThreadStart ntdll 0x7ffc2c1a5e91
    To copy to clipboard, switch view to plain text mode 

  4. #4
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,419
    Thanks
    37
    Thanked 1,545 Times in 1,495 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Replace Pixmap in GraphicsScene

    Hmm, weird.

    Have you tried saving the image? I.e. to see if it is somehow damaged?
    Though I would assume that this would already cause a problem in QPixmap::fromImage().

    Or maybe try showing the resulting pixmap in a separate QLabel, to verify it being OK.

    Cheers,
    _

  5. #5
    Join Date
    Dec 2012
    Posts
    13
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Replace Pixmap in GraphicsScene

    Quote Originally Posted by anda_skoa View Post
    Hmm, weird.

    Have you tried saving the image? I.e. to see if it is somehow damaged?
    Though I would assume that this would already cause a problem in QPixmap::fromImage().

    Or maybe try showing the resulting pixmap in a separate QLabel, to verify it being OK.

    Cheers,
    _
    Well setting to a label results in a crash in exactly the same place. Oddly, saving to a jpg file works fine (and not attempting to display onscreen). Its upside down, but that's is the only thing odd I see about the image.

    I feel like there is something fundamental about what's wrong. Something I'm just not aware of in the Qt world. I don't think its threads, all the crashes and breakpoints show WinMain in the stack. But I have no idea what it could be.

    Thanks for your help, anyway.

  6. #6
    Join Date
    Dec 2012
    Posts
    13
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Replace Pixmap in GraphicsScene

    Perhaps it is something about the event handler. If I set the label to one of the stored pixmaps in the constructor, it works. I see the image. But the captured frame still crashes it.

    Qt Code:
    1. MainWindow::MainWindow(QWidget *parent) :
    2. QMainWindow(parent),
    3. ui(new Ui::MainWindow),
    4. frame(640, 480),
    5. pix_no(0)
    6. {
    7. ui->setupUi(this);
    8.  
    9. frame.load("campix1.jpg");
    10. ui->label->setPixmap(frame);
    11.  
    12. QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
    13. cam = new QCamera(cameras.first(), this);
    14. cam->load();
    15. frame_grabber = new CameraFrameGrabber();
    16. cam->setViewfinder(frame_grabber);
    17. cam->setCaptureMode(QCamera::CaptureViewfinder);
    18. connect(frame_grabber, SIGNAL(frameAvailable(QImage)), this, SLOT(handleFrame(QImage)));
    19. cam->start();
    20. frame_timer.start();
    21.  
    22. }
    23.  
    24. MainWindow::~MainWindow()
    25. {
    26. delete ui;
    27. }
    28.  
    29. void MainWindow::handleFrame(const QImage& img)
    30. {
    31. frame_times.push_back(frame_timer.elapsed());
    32. frame_timer.restart();
    33. if (frame_times.size() > 10) frame_times.pop_front();
    34. int frame_count = frame_times.size();
    35. int frame_total = 0;
    36. for(int i = 0; i < frame_count; ++i)
    37. {
    38. frame_total += frame_times[i];
    39. }
    40. double fps = 0;
    41. if (frame_count)
    42. {
    43. fps = (frame_total / frame_count);
    44. }
    45. ui->sb_fps->setValue(fps);
    46.  
    47. frame = QPixmap::fromImage(img);
    48.  
    49. QString fname("campix");
    50. fname += QString::number(++pix_no);
    51. fname += ".jpg";
    52. bool success = frame.save(fname);
    53.  
    54. ui->label->setPixmap(frame);
    55.  
    56. this->update();
    57. }
    To copy to clipboard, switch view to plain text mode 

    This is the stack while stopped at a breakpoint in the handleFrame event.

    Qt Code:
    1. 1 MainWindow::handleFrame mainwindow.cpp 62 0x7ff6d7082e44
    2. 2 MainWindow::qt_static_metacall moc_mainwindow.cpp 73 0x7ff6d7087bb5
    3. 3 QMetaObject::activate qobject.cpp 3742 0x5d14daf2
    4. 4 QMetaObject::activate qobject.cpp 3603 0x5d14d268
    5. 5 CameraFrameGrabber::frameAvailable moc_cameraframegrabber.cpp 128 0x7ff6d7087f1b
    6. 6 CameraFrameGrabber::present cameraframegrabber.cpp 56 0x7ff6d7086e00
    7. 7 DSCameraSession::presentFrame dscamerasession.cpp 683 0x7ffc074ca264
    8. 8 DSCameraSession::qt_static_metacall moc_dscamerasession.cpp 111 0x7ffc074da2e6
    9. 9 QMetaCallEvent::placeMetaCall qobject.cpp 503 0x5d156c81
    10. 10 QObject::event qobject.cpp 1263 0x5d14f6df
    11. 11 QApplicationPrivate::notify_helper qapplication.cpp 3799 0x5d8a5e8e
    12. 12 QApplication::notify qapplication.cpp 3159 0x5d8a0713
    13. 13 QCoreApplication::notifyInternal2 qcoreapplication.cpp 988 0x5d0f78c6
    14. 14 QCoreApplication::sendEvent qcoreapplication.h 231 0x5d1027f2
    15. 15 QCoreApplicationPrivate::sendPostedEvents qcoreapplication.cpp 1649 0x5d0f9112
    16. 16 QEventDispatcherWin32::sendPostedEvents qeventdispatcher_win.cpp 1295 0x5d1b180a
    17. 17 QWindowsGuiEventDispatcher::sendPostedEvents qwindowsguieventdispatcher.cpp 82 0x7ffbfc70c204
    18. 18 qt_internal_proc qeventdispatcher_win.cpp 445 0x5d1af521
    19. 19 CallWindowProcW USER32 0x7ffc29f41c24
    20. 20 DispatchMessageW USER32 0x7ffc29f4156c
    21. 21 QEventDispatcherWin32::processEvents qeventdispatcher_win.cpp 845 0x5d1aff2b
    22. 22 QWindowsGuiEventDispatcher::processEvents qwindowsguieventdispatcher.cpp 74 0x7ffbfc70c1c4
    23. 23 QEventLoop::processEvents qeventloop.cpp 135 0x5d0f24e8
    24. 24 QEventLoop::exec qeventloop.cpp 210 0x5d0f272e
    25. 25 QCoreApplication::exec qcoreapplication.cpp 1261 0x5d0f55ff
    26. 26 QGuiApplication::exec qguiapplication.cpp 1640 0x7ffbfccf3208
    27. 27 QApplication::exec qapplication.cpp 2976 0x5d8a021a
    28. 28 main main.cpp 10 0x7ff6d7082749
    29. 29 WinMain qtmain_win.cpp 123 0x7ff6d708afbd
    30. 30 invoke_main exe_common.inl 109 0x7ff6d7088bed
    31. 31 __scrt_common_main_seh exe_common.inl 264 0x7ff6d7088a8e
    32. 32 __scrt_common_main exe_common.inl 309 0x7ff6d708894e
    33. 33 WinMainCRTStartup exe_winmain.cpp 17 0x7ff6d7088c09
    34. 34 BaseThreadInitThunk KERNEL32 0x7ffc2a4a8364
    35. 35 RtlUserThreadStart ntdll 0x7ffc2c1a5e91
    To copy to clipboard, switch view to plain text mode 

  7. #7
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,419
    Thanks
    37
    Thanked 1,545 Times in 1,495 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Replace Pixmap in GraphicsScene

    Very strange, the conversion to QPixmap should have consumed the original pixel data, anything afterwards should be fine.

    Can you try something like this?

    Qt Code:
    1. QImage imgCopy = img;
    2. imgCopy.detach();
    3. QPixmap frame = QPixmap::fromImage(imgCopy);
    To copy to clipboard, switch view to plain text mode 

    Cheers,
    _

  8. #8
    Join Date
    Dec 2012
    Posts
    13
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Replace Pixmap in GraphicsScene

    Woah! That worked!

    In my code the QPixmap frame is a member variable. So it is not falling out of scope. The QImage however, as a stack variable, is falling out of scope. So I guess we have to proceed from the supposition that a reference to the image was being held.

    Reviewing the documentation I see that the overload:

    Qt Code:
    1. QPixmap QPixmap::fromImage(QImage &&image, Qt::ImageConversionFlags flags = Qt::AutoColor)
    To copy to clipboard, switch view to plain text mode 

    says "...without copying if possible." I guess that actually applies to both overloads.

    I suppose the lesson learned is to look for detach()? If I see it I need to be mindful of the possibility that there may be lingering references if I don't call it?

    Anyway, thanks again. I can move forward with my project.

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

    Default Re: Replace Pixmap in GraphicsScene

    Maybe but I expect more a threading problem.

    Anyway, since it works,lets not dwell on that

    Cheers,
    _

  10. #10
    Join Date
    Dec 2012
    Posts
    13
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Replace Pixmap in GraphicsScene

    Hmm. It'd have to be an implicit thread. I don't start one and all crashes and break points show WinMain in the stack trace.

Similar Threads

  1. Pixmap transform: translate pixmap
    By DeepKling in forum Qt Programming
    Replies: 5
    Last Post: 23rd January 2015, 20:34
  2. Replies: 1
    Last Post: 19th April 2011, 11:17
  3. To find X, Y position of a pixmap item in Graphicsscene
    By augusbas in forum Qt Programming
    Replies: 2
    Last Post: 21st January 2011, 06:09
  4. transfer graphicsscene on form1 to graphicsscene on form2
    By rogerholmes in forum Qt Programming
    Replies: 2
    Last Post: 25th September 2009, 20:37
  5. GraphicsScene Question
    By QbelcorT in forum Qt Programming
    Replies: 3
    Last Post: 19th September 2008, 08:03

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.