v2.0.0
Loading...
Searching...
No Matches
tfplot.cpp
Go to the documentation of this file.
1//=============================================================================================================
14
15//=============================================================================================================
16// INCLUDES
17//=============================================================================================================
18
19#include "tfplot.h"
20
21#include "helpers/colormap.h"
22
23//=============================================================================================================
24// QT INCLUDES
25//=============================================================================================================
26
27#include <QGridLayout>
28#include <QGraphicsView>
29#include <QGraphicsPixmapItem>
30#include <QDebug>
31
32//=============================================================================================================
33// EIGEN INCLUDES
34//=============================================================================================================
35
36//=============================================================================================================
37// USED NAMESPACES
38//=============================================================================================================
39
40using namespace DISPLIB;
41
42//=============================================================================================================
43// DEFINE MEMBER METHODS
44//=============================================================================================================
45
46TFplot::TFplot(Eigen::MatrixXd tf_matrix,
47 qreal sample_rate,
48 qreal lower_frq,
49 qreal upper_frq,
50 ColorMaps cmap = Jet)
51{
52 qreal max_frq = sample_rate / 2.0;
53 qreal frq_per_px = max_frq / tf_matrix.rows();
54
55 if (upper_frq > max_frq || upper_frq <= 0)
56 upper_frq = max_frq;
57 if (lower_frq < 0 || lower_frq >= max_frq)
58 lower_frq = 0;
59 if (upper_frq < lower_frq) {
60 qreal temp = upper_frq;
61 upper_frq = lower_frq;
62 lower_frq = temp;
63 }
64
65 qint32 lower_px = floor(lower_frq / frq_per_px);
66 qint32 upper_px = floor(upper_frq / frq_per_px);
67
68 Eigen::MatrixXd zoomed_tf_matrix = Eigen::MatrixXd::Zero(upper_px - lower_px, tf_matrix.cols());
69 //How to print to console here
70 //printf(("fff "+QString::number(zoomed_tf_matrix(12,12))).toUtf8().data());// << "; " << zoomed_tf_matrix.rows(2) << "; ";
71
72 qint32 pxls = 0;
73 for (qint32 it = lower_px; it < upper_px; it++) {
74 zoomed_tf_matrix.row(pxls) = tf_matrix.row(it);
75 pxls++;
76 }
77
78 //zoomed_tf_matrix = tf_matrix.block(tf_matrix.rows() - upper_px, 0, upper_px-lower_px, tf_matrix.cols());
79
80 calc_plot(zoomed_tf_matrix, sample_rate, cmap, lower_frq, upper_frq);
81}
82
83//=============================================================================================================
84
85TFplot::TFplot(Eigen::MatrixXd tf_matrix,
86 qreal sample_rate,
87 ColorMaps cmap = Jet)
88{
89 calc_plot(tf_matrix, sample_rate, cmap, 0, 0);
90}
91
92//=============================================================================================================
93
94void TFplot::calc_plot(Eigen::MatrixXd tf_matrix,
95 qreal sample_rate,
96 ColorMaps cmap,
97 qreal lower_frq = 0,
98 qreal upper_frq = 0)
99{
100 //normalisation of the tf-matrix
101 qreal norm1 = tf_matrix.maxCoeff();
102 qreal mnorm = tf_matrix.minCoeff();
103 if (std::fabs(mnorm) > norm1)
104 norm1 = mnorm;
105 tf_matrix /= norm1;
106
107 //setup image
108 QImage* image_to_tf_plot = new QImage(tf_matrix.cols(), tf_matrix.rows(), QImage::Format_RGB32);
109
110 //setup pixelcolors in image
111 QColor color;
112 for (qint32 y = 0; y < tf_matrix.rows(); y++) {
113 for (qint32 x = 0; x < tf_matrix.cols(); x++) {
114 switch (cmap) {
115 case Jet:
116 color.setRgb(ColorMap::valueToJet(std::fabs(tf_matrix(y, x))));
117 break;
118 case Hot:
119 color.setRgb(ColorMap::valueToHot(std::fabs(tf_matrix(y, x))));
120 break;
121 case HotNeg1:
122 color.setRgb(ColorMap::valueToHotNegative1(std::fabs(tf_matrix(y, x))));
123 break;
124 case HotNeg2:
125 color.setRgb(ColorMap::valueToHotNegative2(std::fabs(tf_matrix(y, x))));
126 break;
127 case Bone:
128 color.setRgb(ColorMap::valueToBone(std::fabs(tf_matrix(y, x))));
129 break;
130 case RedBlue:
131 color.setRgb(ColorMap::valueToRedBlue(std::fabs(tf_matrix(y, x))));
132 break;
133 }
134 image_to_tf_plot->setPixel(x, tf_matrix.rows() - 1 - y, color.rgb());
135 }
136 }
137
138 *image_to_tf_plot = image_to_tf_plot->scaled(tf_matrix.cols(), tf_matrix.cols() / 2, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
139 *image_to_tf_plot = image_to_tf_plot->scaledToWidth(/*0.9 **/ 1026, Qt::SmoothTransformation);
140 //image to pixmap
141 QGraphicsPixmapItem* tf_pixmap = new QGraphicsPixmapItem(QPixmap::fromImage(*image_to_tf_plot));
142 //tf_pixmap->setScale(100);
143 QGraphicsScene* tf_scene = new QGraphicsScene();
144 tf_scene->addItem(tf_pixmap);
145
146 QImage* coeffs_image = new QImage(10, tf_matrix.rows(), QImage::Format_RGB32);
147 qreal norm = tf_matrix.maxCoeff();
148 for (qint32 it = 0; it < tf_matrix.rows(); it++) {
149 for (qint32 x = 0; x < 10; x++) {
150 switch (cmap) {
151 case Jet:
152 color.setRgb(ColorMap::valueToJet(it * norm / tf_matrix.rows()));
153 break;
154 case Hot:
155 color.setRgb(ColorMap::valueToHot(it * norm / tf_matrix.rows()));
156 break;
157 case HotNeg1:
158 color.setRgb(ColorMap::valueToHotNegative1(it * norm / tf_matrix.rows()));
159 break;
160 case HotNeg2:
161 color.setRgb(ColorMap::valueToHotNegative2(it * norm / tf_matrix.rows()));
162 break;
163 case Bone:
164 color.setRgb(ColorMap::valueToBone(it * norm / tf_matrix.rows()));
165 break;
166 case RedBlue:
167 color.setRgb(ColorMap::valueToRedBlue(it * norm / tf_matrix.rows()));
168 break;
169 }
170 coeffs_image->setPixel(x, tf_matrix.rows() - 1 - it, color.rgb());
171 }
172 }
173
174 *coeffs_image = coeffs_image->scaled(10, tf_matrix.cols() / 2, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
175 *coeffs_image = coeffs_image->scaledToHeight(image_to_tf_plot->height(), Qt::SmoothTransformation);
176
177 QLayout* layout = new QGridLayout();
178 QGraphicsView* view = new QGraphicsView();
179 view->setObjectName("tf_view");
180 view->setScene(tf_scene);
181 QLinearGradient lgrad(tf_scene->sceneRect().topLeft(), tf_scene->sceneRect().bottomRight());
182 lgrad.setColorAt(0.0, Qt::white);
183 lgrad.setColorAt(1.0, Qt::lightGray);
184
185 tf_scene->setBackgroundBrush(lgrad); //Qt::white);
186
187 //setup x-axis
188 QGraphicsTextItem* x_axis_name = new QGraphicsTextItem("time [sec]", tf_pixmap);
189 x_axis_name->setFont(QFont("arial", 14));
190
191 QList<QGraphicsItem*> x_axis_values;
192 QList<QGraphicsItem*> x_axis_lines;
193
194 qreal scaleXText = (tf_matrix.cols() - 1) / sample_rate / 20.0; // divide signallength
195
196 for (qint32 j = 0; j < 21; j++) {
197 QGraphicsTextItem* text_item = new QGraphicsTextItem(QString::number(j * scaleXText, 'f', 2), tf_pixmap);
198 text_item->setFont(QFont("arial", 10));
199 x_axis_values.append(text_item); // scalevalue as string
200 QGraphicsLineItem* x_line_item = new QGraphicsLineItem(tf_pixmap);
201 x_line_item->setLine(0, -3, 0, 3);
202 x_line_item->setPen(QPen(Qt::darkGray, 2, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin));
203 x_axis_lines.append(x_line_item); // scalelines
204 }
205
206 x_axis_name->setPos(tf_pixmap->boundingRect().width() / 2 - x_axis_name->boundingRect().width() / 2,
207 tf_pixmap->boundingRect().height() + 0.8 * x_axis_values.at(0)->boundingRect().height());
208
209 qreal scale_x = qreal(tf_pixmap->boundingRect().width()) / qreal(x_axis_values.length() - 1);
210
211 for (qint32 i = 0; i < x_axis_values.length(); i++) {
212 x_axis_values.at(i)->setPos(qreal(i) * scale_x - x_axis_values.at(0)->boundingRect().width() / 2,
213 tf_pixmap->boundingRect().height());
214 x_axis_lines.at(i)->setPos(qreal(i) * scale_x,
215 tf_pixmap->boundingRect().height());
216
217 } //end x axis
218
219 //y-axis
220 QGraphicsTextItem* y_axis_name = new QGraphicsTextItem("frequency [Hz]", tf_pixmap);
221 y_axis_name->setFont(QFont("arial", 14));
222
223 QList<QGraphicsItem*> y_axis_values;
224 QList<QGraphicsItem*> y_axis_lines;
225
226 qreal scale_y_text = 0;
227
228 if (lower_frq == 0 && upper_frq == 0) {
229 scale_y_text = 0.5 * sample_rate / 10.0; // divide signallength
230 } else {
231 scale_y_text = (upper_frq - lower_frq) / 10.0;
232 }
233
234 for (qint32 j = 0; j < 11; j++) {
235 QGraphicsTextItem* text_item = new QGraphicsTextItem(QString::number(lower_frq + j * scale_y_text, //pow(10, j)/pow(10, 11) /*(j+1)/log(12)*/ * max_frequency,//scale_y_text,
236 'f', 0),
237 tf_pixmap);
238 text_item->setFont(QFont("arial", 10));
239 y_axis_values.append(text_item); // scalevalue as string
240 QGraphicsLineItem* y_line_item = new QGraphicsLineItem(tf_pixmap);
241 y_line_item->setLine(-3, 0, 3, 0);
242 y_line_item->setPen(QPen(Qt::darkGray, 2, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin));
243 y_axis_lines.append(y_line_item); // scalelines
244 }
245
246 y_axis_name->setPos(-x_axis_values.at(0)->boundingRect().width() - y_axis_name->boundingRect().height(),
247 tf_pixmap->boundingRect().height() / 2 + y_axis_name->boundingRect().height() / 2);
248 y_axis_name->setRotation(-90);
249
250 qreal scale_y = qreal(tf_pixmap->boundingRect().height()) / qreal(y_axis_values.length() - 1);
251
252 for (qint32 i = 0; i < y_axis_values.length(); i++) {
253 y_axis_values.at(i)->setPos(-y_axis_values.last()->boundingRect().width() - 0.5 * y_axis_lines.last()->boundingRect().width() - 1, tf_pixmap->boundingRect().height() - y_axis_values.last()->boundingRect().height() / 2 - qreal(i) * scale_y);
254 y_axis_lines.at(i)->setPos(0, qreal(i) * scale_y);
255 }
256 //end y axis
257
258 QGraphicsPixmapItem* coeffs_item = tf_scene->addPixmap(QPixmap::fromImage(*coeffs_image)); //addItem();
259 coeffs_item->setParentItem(tf_pixmap);
260 coeffs_item->setPos(tf_pixmap->boundingRect().width() + 5, 0);
261
262 QGraphicsSimpleTextItem* axis_name_item = new QGraphicsSimpleTextItem("coefficients", coeffs_item);
263 QGraphicsSimpleTextItem* axis_zero_item = new QGraphicsSimpleTextItem("0", coeffs_item);
264 QGraphicsSimpleTextItem* axis_one_item = new QGraphicsSimpleTextItem("1", coeffs_item);
265 axis_name_item->setFont(QFont("arial", 14));
266 axis_zero_item->setFont(QFont("arial", 10));
267 axis_one_item->setFont(QFont("arial", 10));
268
269 axis_name_item->setPos(coeffs_item->boundingRect().width() + 1,
270 coeffs_item->boundingRect().height() / 2 + axis_name_item->boundingRect().height() / 2);
271 axis_name_item->setRotation(-90);
272 axis_zero_item->setPos(1 + coeffs_item->boundingRect().width(),
273 coeffs_item->boundingRect().height() - axis_zero_item->boundingRect().height());
274 axis_one_item->setPos(1 + coeffs_item->boundingRect().width(), 0);
275 //end coeffs picture
276
277 view->fitInView(layout->contentsRect(), Qt::KeepAspectRatio);
278 layout->addWidget(view);
279 this->setLayout(layout);
280}
281
282//=============================================================================================================
283
284void TFplot::resizeEvent(QResizeEvent* event)
285{
286 Q_UNUSED(event);
287
288 QWidget* widget = this->layout()->itemAt(0)->widget();
289 if (widget != nullptr) {
290 QGraphicsView* view = (QGraphicsView*)widget;
291 view->fitInView(view->sceneRect(), Qt::KeepAspectRatio);
292 }
293}
Static scalar-to-colour lookup helpers (Jet, Hot, Bone, Viridis, Cool, RedBlue, MNE) used by every pl...
Time-frequency spectrogram widget rendering an Eigen matrix as a colour image.
2-D display widgets and visualisation helpers (charts, topography, colour maps).
ColorMaps
Definition tfplot.h:62
@ Jet
Definition tfplot.h:66
@ RedBlue
Definition tfplot.h:68
@ HotNeg1
Definition tfplot.h:64
@ Hot
Definition tfplot.h:63
@ Bone
Definition tfplot.h:67
@ HotNeg2
Definition tfplot.h:65
static QRgb valueToBone(double v)
Definition colormap.h:755
static QRgb valueToJet(double v)
Definition colormap.h:723
static QRgb valueToRedBlue(double v)
Definition colormap.h:763
static QRgb valueToHotNegative2(double v)
Definition colormap.h:747
static QRgb valueToHot(double v)
Definition colormap.h:731
static QRgb valueToHotNegative1(double v)
Definition colormap.h:739
void calc_plot(Eigen::MatrixXd tf_matrix, qreal sample_rate, ColorMaps cmap, qreal lower_frq, qreal upper_frq)
Definition tfplot.cpp:94
virtual void resizeEvent(QResizeEvent *event)
Definition tfplot.cpp:284
TFplot(Eigen::MatrixXd tf_matrix, qreal sample_rate, qreal lower_frq, qreal upper_frq, ColorMaps cmap)
Definition tfplot.cpp:46