Commit cd6ad90ac3f508fdf36afd9c0d74f304a5dc2809

Authored by Charles Otto
1 parent 0fc6c503

Fix a crash in Show2 transform

Send a deep copy of the current image to the GUI thread, copy must be called
explicitly or a shallow copy will be done, and subsequent modifications to the
buffer will cause crashes when the GUI thread tries to draw it.
Showing 1 changed file with 16 additions and 15 deletions
sdk/plugins/gui.cpp
... ... @@ -7,7 +7,6 @@ using namespace cv;
7 7  
8 8 namespace br
9 9 {
10   -
11 10 QImage toQImage(const Mat &mat)
12 11 {
13 12 // Convert to 8U depth
... ... @@ -53,28 +52,26 @@ QImage toQImage(const Mat &mat)
53 52 class GUIProxy : public QObject
54 53 {
55 54 Q_OBJECT
56   -
  55 +public:
57 56 QLabel * window;
58 57  
59   -public:
60 58 GUIProxy()
61 59 {
62   - window =NULL;
  60 + window = NULL;
63 61 }
64 62  
65 63 public slots:
66   - void showImage(QPixmap pixmap)
  64 +
  65 + void showImage(const QPixmap & input)
67 66 {
68   - window->show();
69   - window->setPixmap(pixmap);
70   - window->setFixedSize(pixmap.size());
71   - window->update();
  67 + window->setPixmap(input);
  68 + window->setFixedSize(input.size());
  69 + window->setVisible(true);
72 70 }
73 71  
74 72 void createWindow()
75 73 {
76 74 delete window;
77   - window = NULL;
78 75 window = new QLabel();
79 76 }
80 77 };
... ... @@ -99,7 +96,7 @@ public:
99 96 gui->moveToThread(QApplication::instance()->thread());
100 97 // Connect our signals to the proxy's slots
101 98 connect(this, SIGNAL(needWindow()), gui, SLOT(createWindow()), Qt::BlockingQueuedConnection);
102   - connect(this, SIGNAL(updateImage(QPixmap)), gui, SLOT(showImage(QPixmap)));
  99 + connect(this, SIGNAL(updateImage(QPixmap)), gui,SLOT(showImage(QPixmap)));
103 100 }
104 101  
105 102 ~Show2Transform()
... ... @@ -124,9 +121,12 @@ public:
124 121  
125 122 foreach (const Template & t, src) {
126 123 foreach(const cv::Mat & m, t) {
127   - QImage qImageBuffer = toQImage(m);
  124 + qImageBuffer = toQImage(m);
128 125 displayBuffer.convertFromImage(qImageBuffer);
129   - emit updateImage(displayBuffer);
  126 + // Emit an explicit copy of our pixmap so that the pixmap used
  127 + // by the main thread isn't damaged when we update displayBuffer
  128 + // later.
  129 + emit updateImage(displayBuffer.copy(displayBuffer.rect()));
130 130 }
131 131 }
132 132 }
... ... @@ -134,7 +134,7 @@ public:
134 134 void finalize(TemplateList & output)
135 135 {
136 136 (void) output;
137   - // todo: hide ui?
  137 + // todo: hide window?
138 138 }
139 139  
140 140 void init()
... ... @@ -144,11 +144,12 @@ public:
144 144  
145 145 protected:
146 146 GUIProxy * gui;
  147 + QImage qImageBuffer;
147 148 QPixmap displayBuffer;
148 149  
149 150 signals:
150 151 void needWindow();
151   - void updateImage(QPixmap input);
  152 + void updateImage(const QPixmap & input);
152 153 };
153 154  
154 155 BR_REGISTER(Transform, Show2Transform)
... ...