- RGB-image plots now work properly with inverted axes (image is inverted, befor image was not shown at all)
- added example for simple RGB math image plot with RGB/CMY-color mapping - fixed some of the OpenCV examples (improved QMake-project files)
1
.gitignore
vendored
@ -92,3 +92,4 @@ moc_predefs.h
|
||||
/doc/*.tmp
|
||||
*.prl
|
||||
Sicherungskopie_*
|
||||
/examples/simpletest_rgbimageplot_opencv/opencv
|
||||
|
@ -64,6 +64,7 @@ addSimpleTest(symbols_and_errors)
|
||||
addSimpleTest(symbols_and_styles)
|
||||
addSimpleTest(filledgraphs)
|
||||
addSimpleTest(speed)
|
||||
addSimpleTest(rgbimageplot)
|
||||
addSimpleTest(rgbimageplot_qt)
|
||||
addSimpleTest(impulsesplot)
|
||||
addSimpleTest(paramscatterplot)
|
||||
|
@ -85,7 +85,7 @@ All test-projects are Qt-projects that use qmake to build. You can load them int
|
||||
<tr><th> Screenshot <th> Description <th> Notes
|
||||
<tr><td> \image html jkqtplotter_simpletest_rgbimageplot_qt_small.png
|
||||
<td> \subpage JKQTPlotterImagePlotQImageRGB
|
||||
<td> `JKQTPImage` <br> `QImage` drawn onto a plot with arbitrary scaling)
|
||||
<td> `JKQTPImage` <br> `QImage` drawn onto a plot with arbitrary scaling <br> inverted coordinate axes
|
||||
<tr><td> \image html jkqtplotter_simpletest_imageplot_small.png
|
||||
<td> \subpage JKQTPlotterImagePlot
|
||||
<td> `JKQTPColumnMathImage` <br> image data copied from C-style row-major array into a single column of the internal datastore <br> Describes several options of the image plotting classes (different ways of color coding, what to do with data above/below the limits etc.)
|
||||
@ -95,12 +95,15 @@ All test-projects are Qt-projects that use qmake to build. You can load them int
|
||||
<tr><td> \image html jkqtplotter_simpletest_imageplot_nodatastore_small.png
|
||||
<td> \subpage JKQTPlotterImagePlotNoDatastore
|
||||
<td> `JKQTPMathImage` <br> image data in a C-style row-major array, not using internal datastore
|
||||
<tr><td> \image html jkqtplotter_simpletest_rgbimageplot_small.png
|
||||
<td> \subpage JKQTPlotterRGBImagePlot
|
||||
<td> `JKQTPColumnRGBMathImage` <br> image data in a C-style row-major array, not using internal datastore <br> RGB/CMY color compositing
|
||||
<tr><td> \image html jkqtplotter_simpletest_imageplot_opencv_small.png
|
||||
<td> \subpage JKQTPlotterImagePlotOpenCV
|
||||
<td> `JKQTPColumnMathImage` <br> image data copied from OpenCV cv::Mat-structure into a single column of the internal datastore
|
||||
<tr><td> \image html jkqtplotter_simpletest_rgbimageplot_opencv_small.png
|
||||
<td> \subpage JKQTPlotterImagePlotRGBOpenCV
|
||||
<td> `JKQTPColumnRGBMathImage` <br> image data copied from OpenCV cv::Mat-structure into three columns of the internal datastore
|
||||
<td> `JKQTPColumnRGBMathImage` <br> image data copied from OpenCV cv::Mat-structure into three columns of the internal datastore <br> inverted coordinate axes
|
||||
</table>
|
||||
|
||||
|
||||
|
@ -38,6 +38,7 @@ Changes, compared to \ref WHATSNEW_V2018_08 "v2018.08" include:
|
||||
<li> new: frames (plot viewport, key/legend ...) may be rounded off at the corners</li>
|
||||
<li> new: diverse new styling options (default font name/size ...)</li>
|
||||
<li> new: additionl options for styling coordinate axes</li>
|
||||
<li> fixed: RGB-image plots now work properly with inverted axes (image is inverted, befor image was not shown at all) </li>
|
||||
</ul></li>
|
||||
<li> Updates to JKQTMathText:
|
||||
<ul>
|
||||
|
BIN
doc/images/jkqtplotter_inverted_yaxis.png
Normal file
After Width: | Height: | Size: 61 KiB |
@ -37,12 +37,13 @@ All test-projects are Qt-projects that use qmake to build. You can load them int
|
||||
|
||||
| Screenshot | Description | Notes |
|
||||
|:-------------:| ------------- | ------------- |
|
||||
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_rgbimageplot_qt_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_rgbimageplot_qt) | [`QImage` as a Graph](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_rgbimageplot_qt) | `JKQTPImage` <br> `QImage` drawn onto a plot with arbitrary scaling) |
|
||||
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_rgbimageplot_qt_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_rgbimageplot_qt) | [`QImage` as a Graph](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_rgbimageplot_qt) | `JKQTPImage` <br> `QImage` drawn onto a plot with arbitrary scaling <br> inverted coordinate axes |
|
||||
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_imageplot_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_imageplot) | [Basic 1-channel Raw C Image Plot](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_imageplot) | `JKQTPColumnMathImage` <br> image data copied from C-style row-major array into a single column of the internal datastore <br> Describes several options of the image plotting classes (different ways of color coding, what to do with data above/below the limits etc.) |
|
||||
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_imageplot_modifier_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_imageplot_modifier) | [Modifier-Feature of Image Plots](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_imageplot_modifier) | `JKQTPColumnMathImage` <br> image data copied from C-style row-major array into a single column of the internal datastore <br> Image is modified by a second image to display two data dimensions at the same time |
|
||||
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_imageplot_nodatastore_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_imageplot_nodatastore) | [Basic 1-channel Raw C Image Plot <br> without the internal datastore](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_imageplot_nodatastore) | `JKQTPMathImage` <br> image data in a C-style row-major array, not using internal datastore |
|
||||
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_rgbimageplot_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/jkqtplotter_simpletest_rgbimageplot) | [Simple 3-channel Math RGB/CMY Image Plot](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/jkqtplotter_simpletest_rgbimageplot) | `JKQTPColumnRGBMathImage` <br> image data in a C-style row-major array, not using internal datastore <br> RGB/CMY color compositing |
|
||||
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_imageplot_opencv_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_imageplot_opencv) | [1-channel OpenCV cv::Mat Image Plot](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_imageplot_opencv) | `JKQTPColumnMathImage` <br> image data copied from OpenCV cv::Mat-structure into a single column of the internal datastore |
|
||||
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_rgbimageplot_opencv_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_rgbimageplot_opencv) | [RGB OpenCV cv::Mat Image Plot](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_rgbimageplot_opencv) | `JKQTPColumnRGBMathImage` <br> image data copied from OpenCV cv::Mat-structure into three columns of the internal datastore |
|
||||
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_rgbimageplot_opencv_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_rgbimageplot_opencv) | [RGB OpenCV cv::Mat Image Plot](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_rgbimageplot_opencv) | `JKQTPColumnRGBMathImage` <br> image data copied from OpenCV cv::Mat-structure into three columns <br> inverted coordinate axesof the internal datastore |
|
||||
|
||||
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "jkqtplotter/jkqtpgraphs.h"
|
||||
#include "jkqtplotter/jkqtpgraphsimage.h"
|
||||
#include "jkqtplotter/jkqtpopencvinterface.h"
|
||||
#include <opencv/cv.h>
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
|
@ -9,23 +9,26 @@ greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport
|
||||
# output executable name
|
||||
TARGET = jkqtplotter_simpletest_imageplot_opencv
|
||||
|
||||
# add OpenCV-interface to JKQTPDatastore
|
||||
DEFINES += JKQTPLOTTER_OPENCV_INTERFACE
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# link agains OpenCV-3.4.1
|
||||
INCLUDEPATH += $$PWD/OpenCV-3.4.1/include/
|
||||
LIBS += -L$$PWD/OpenCV-3.4.1/bin/ -llibopencv_core341
|
||||
#INCLUDEPATH += $$PWD/../../../OpenCV-3.4.1/include/
|
||||
#LIBS += -L$$PWD/../../../OpenCV-3.4.1/bin/ -llibopencv_core341 -llibopencv_imgcodecs341
|
||||
#opencvdlls.files=$$PWD/../../../OpenCV-3.4.1/bin/*.dll
|
||||
#opencvdlls.path=$$OUT_PWD
|
||||
|
||||
# link agains OpenCV-4
|
||||
INCLUDEPATH += $$PWD/../../../OpenCV-4.0.1/include/
|
||||
LIBS += -L$$PWD/../../../OpenCV-4.0.1/x64/mingw/bin -L$$PWD/../../../OpenCV-4.0.1/x64/mingw/lib -llibopencv_core400.dll -llibopencv_imgcodecs400.dll
|
||||
opencvdlls.files=$$PWD/../../../OpenCV-4.0.1/x64/mingw/bin/*.dll
|
||||
opencvdlls.path=$$OUT_PWD
|
||||
|
||||
INCLUDEPATH+=../../lib
|
||||
|
||||
CONFIG (debug, debug|release) {
|
||||
LIBS += -L../../staticlib/jkqtplotterlib/debug -ljkqtplotterlib_debug
|
||||
} else {
|
||||
LIBS += -L../../staticlib/jkqtplotterlib/release -ljkqtplotterlib
|
||||
}
|
||||
message("LIBS = $$LIBS")
|
||||
message("LIBS = $$LIBS")
|
||||
|
||||
INSTALLS += opencvdlls
|
||||
|
@ -0,0 +1,8 @@
|
||||
TEMPLATE = subdirs
|
||||
|
||||
SUBDIRS += jkqtplotterlib jkqtplotter_simpletest_imageplot_opencv
|
||||
|
||||
jkqtplotterlib.file = ../../staticlib/jkqtplotterlib/jkqtplotterlib.pro
|
||||
|
||||
jkqtplotter_simpletest_imageplot_opencv.file=$$PWD/jkqtplotter_simpletest_imageplot_opencv.pro
|
||||
jkqtplotter_simpletest_imageplot_opencv.depends = jkqtplotterlib
|
129
examples/simpletest_rgbimageplot/README.md
Normal file
@ -0,0 +1,129 @@
|
||||
# Example (JKQTPlotter): Simple Math RGB/CMY Image Plot {#JKQTPlotterRGBImagePlot}
|
||||
This project (see `./examples/simpletest_imageplot/`) simply creates a JKQTPlotter widget (as a new window) and adds an image plot of a mathematical function (here the Airy disk). The function is calculated with different parameters and then the result for each parameter is mapped onto a separate color channel in the output. The image is stored as a simple C-array in row-major ordering and then copied into a single column of the internal datasdtore (JKQTPMathImage could be directly used without the internal datastore). This very simple interface can also be used to interface with many common image processing libraries, like CImg or OpenCV.
|
||||
|
||||
The source code of the main application is (see [`jkqtplotter_simpletest_rgbimageplot.cpp`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_imageplot/jkqtplotter_simpletest_rgbimageplot.cpp):
|
||||
```.cpp
|
||||
#include <QApplication>
|
||||
#include <cmath>
|
||||
#include "jkqtplotter/jkqtplotter.h"
|
||||
#include "jkqtplotter/jkqtpgraphsimagergb.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
JKQTPlotter plot;
|
||||
// 1. create a plotter window and get a pointer to the internal datastore (for convenience)
|
||||
plot.getPlotter()->setUseAntiAliasingForGraphs(true); // nicer (but slower) plotting
|
||||
plot.getPlotter()->setUseAntiAliasingForSystem(true); // nicer (but slower) plotting
|
||||
plot.getPlotter()->setUseAntiAliasingForText(true); // nicer (but slower) text rendering
|
||||
JKQTPDatastore* ds=plot.getDatastore();
|
||||
|
||||
// 2. now we create data for the charts (taken from https://commons.wikimedia.org/wiki/File:Energiemix_Deutschland.svg)
|
||||
const int NX=100; // image dimension in x-direction [pixels]
|
||||
const int NY=100; // image dimension in x-direction [pixels]
|
||||
const double dx=1e-2; // size of a pixel in x-direction [micrometers]
|
||||
const double dy=1e-2; // size of a pixel in x-direction [micrometers]
|
||||
const double w=static_cast<double>(NX)*dx;
|
||||
const double h=static_cast<double>(NY)*dy;
|
||||
double airydisk1[NX*NY]; // row-major image
|
||||
double airydisk2[NX*NY]; // row-major image
|
||||
|
||||
// 2.1 Parameters for airy disk plot (see https://en.wikipedia.org/wiki/Airy_disk)
|
||||
double NA=1.1; // numerical aperture of lens
|
||||
double wavelength1=540e-3; // wavelength of the light [micrometers]
|
||||
double wavelength2=450e-3; // wavelength of the light [micrometers]
|
||||
|
||||
// 2.2 calculate image of airy disk in a row-major array
|
||||
double x, y=-h/2.0;
|
||||
for (int iy=0; iy<NY; iy++ ) {
|
||||
x=-w/2.0;
|
||||
for (int ix=0; ix<NX; ix++ ) {
|
||||
const double r=sqrt(x*x+y*y);
|
||||
const double v1=2.0*M_PI*NA*r/wavelength1;
|
||||
airydisk1[iy*NX+ix] = sqrt(pow(2.0*j1(v1)/v1, 2));
|
||||
const double v2=2.0*M_PI*NA*r/wavelength2;
|
||||
airydisk2[iy*NX+ix] = sqrt(pow(2.0*j1(v2)/v2, 2));
|
||||
x+=dx;
|
||||
}
|
||||
y+=dy;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 3. make data available to JKQTPlotter by adding it to the internal datastore.
|
||||
// In this step the contents of C-array airydisk is copied into a column
|
||||
// of the datastore in row-major order
|
||||
size_t cAiryDisk1=ds->addCopiedImageAsColumn(airydisk1, NX, NY, "imagedata1");
|
||||
size_t cAiryDisk2=ds->addCopiedImageAsColumn(airydisk2, NX, NY, "imagedata2");
|
||||
|
||||
|
||||
// 4. create a graph (JKQTPColumnMathImage) with the column created above as data
|
||||
// The data is color-coded with the color-palette JKQTPMathImageMATLAB
|
||||
// the converted range of data is determined automatically because s etAutoImageRange(true)
|
||||
JKQTPColumnRGBMathImage* graph=new JKQTPColumnRGBMathImage(&plot);
|
||||
graph->setTitle("");
|
||||
// image column with the data (R/G/B or C/M/Y ...)
|
||||
graph->setImageGColumn(cAiryDisk1); // G/M channel
|
||||
graph->setImageBColumn(cAiryDisk2); // B/Y channel
|
||||
// set size of the data (the datastore does not contain this info, as it only manages 1D columns of data and this is used to assume a row-major ordering
|
||||
graph->setNx(NX);
|
||||
graph->setNy(NY);
|
||||
// where does the image start in the plot, given in plot-axis-coordinates (bottom-left corner)
|
||||
graph->setX(-w/2.0);
|
||||
graph->setY(-h/2.0);
|
||||
// width and height of the image in plot-axis-coordinates
|
||||
graph->setWidth(w);
|
||||
graph->setHeight(h);
|
||||
// get coordinate axis of color-bar and set its label
|
||||
graph->getColorBarRightAxisB()->setAxisLabel("blue light field strength [AU]");
|
||||
graph->getColorBarRightAxisG()->setAxisLabel("green light field strength [AU]");
|
||||
// determine min/max of data automatically and use it to set the range of the color-scale
|
||||
graph->setAutoImageRange(true);
|
||||
|
||||
|
||||
// 5. add the graphs to the plot, so it is actually displayed
|
||||
plot.addGraph(graph);
|
||||
|
||||
|
||||
// 6. set axis labels
|
||||
plot.getXAxis()->setAxisLabel("x [{\\mu}m]");
|
||||
plot.getYAxis()->setAxisLabel("y [{\\mu}m]");
|
||||
|
||||
|
||||
// 7. fix axis and plot aspect ratio to 1
|
||||
plot.getPlotter()->setMaintainAspectRatio(true);
|
||||
plot.getPlotter()->setMaintainAxisAspectRatio(true);
|
||||
|
||||
// 8 autoscale the plot so the graph is contained
|
||||
plot.zoomToFit();
|
||||
|
||||
// show plotter and make it a decent size
|
||||
plot.show();
|
||||
plot.resize(600,600);
|
||||
plot.setWindowTitle("JKQTPColumnRGBMathImage");
|
||||
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
```
|
||||
The result looks like this:
|
||||
|
||||
![jkqtplotter_simpletest_rgbimageplot](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_rgbimageplot.png)
|
||||
|
||||
In the example above, we calculated two airy disks for two wavelengths and assigned them to the R and G color channel of the output image. Alternatively you can also assign them to the CMY-channels of the output image:
|
||||
```.cpp
|
||||
// use (subtractive) CMY color model, not RGB
|
||||
graph->setRgbMode(JKQTPRGBMathImageModeCMYMode);
|
||||
```
|
||||
|
||||
The result will then look like this:
|
||||
|
||||
![jkqtplotter_simpletest_rgbimageplot](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_rgbimageplot_cmy.png)
|
||||
|
||||
Note that the CMY-color model is a subtractive color model, whereas RGB is an additive model. Therefore CMY-color-scales range from CMY to white, whereas the RGB-scales range from RGB to black!
|
@ -0,0 +1,116 @@
|
||||
/** \example jkqtplotter_simpletest_rgbimageplot.cpp
|
||||
* Shows how to plot colored math images with JKQTPlotter, where different images/matrices are assigned to different color channels
|
||||
*
|
||||
* \ref JKQTPlotterRGBImagePlot
|
||||
*/
|
||||
|
||||
#include <QApplication>
|
||||
#include <cmath>
|
||||
#include "jkqtplotter/jkqtplotter.h"
|
||||
#include "jkqtplotter/jkqtpgraphsimagergb.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
JKQTPlotter plot;
|
||||
// 1. create a plotter window and get a pointer to the internal datastore (for convenience)
|
||||
plot.getPlotter()->setUseAntiAliasingForGraphs(true); // nicer (but slower) plotting
|
||||
plot.getPlotter()->setUseAntiAliasingForSystem(true); // nicer (but slower) plotting
|
||||
plot.getPlotter()->setUseAntiAliasingForText(true); // nicer (but slower) text rendering
|
||||
JKQTPDatastore* ds=plot.getDatastore();
|
||||
|
||||
// 2. now we create data for the charts (taken from https://commons.wikimedia.org/wiki/File:Energiemix_Deutschland.svg)
|
||||
const int NX=100; // image dimension in x-direction [pixels]
|
||||
const int NY=100; // image dimension in x-direction [pixels]
|
||||
const double dx=1e-2; // size of a pixel in x-direction [micrometers]
|
||||
const double dy=1e-2; // size of a pixel in x-direction [micrometers]
|
||||
const double w=static_cast<double>(NX)*dx;
|
||||
const double h=static_cast<double>(NY)*dy;
|
||||
double airydisk1[NX*NY]; // row-major image
|
||||
double airydisk2[NX*NY]; // row-major image
|
||||
|
||||
// 2.1 Parameters for airy disk plot (see https://en.wikipedia.org/wiki/Airy_disk)
|
||||
double NA=1.1; // numerical aperture of lens
|
||||
double wavelength1=540e-3; // wavelength of the light [micrometers]
|
||||
double wavelength2=450e-3; // wavelength of the light [micrometers]
|
||||
|
||||
// 2.2 calculate image of airy disk in a row-major array
|
||||
double x, y=-h/2.0;
|
||||
for (int iy=0; iy<NY; iy++ ) {
|
||||
x=-w/2.0;
|
||||
for (int ix=0; ix<NX; ix++ ) {
|
||||
const double r=sqrt(x*x+y*y);
|
||||
const double v1=2.0*M_PI*NA*r/wavelength1;
|
||||
airydisk1[iy*NX+ix] = sqrt(pow(2.0*j1(v1)/v1, 2));
|
||||
const double v2=2.0*M_PI*NA*r/wavelength2;
|
||||
airydisk2[iy*NX+ix] = sqrt(pow(2.0*j1(v2)/v2, 2));
|
||||
x+=dx;
|
||||
}
|
||||
y+=dy;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 3. make data available to JKQTPlotter by adding it to the internal datastore.
|
||||
// In this step the contents of C-array airydisk is copied into a column
|
||||
// of the datastore in row-major order
|
||||
size_t cAiryDisk1=ds->addCopiedImageAsColumn(airydisk1, NX, NY, "imagedata1");
|
||||
size_t cAiryDisk2=ds->addCopiedImageAsColumn(airydisk2, NX, NY, "imagedata2");
|
||||
|
||||
|
||||
// 4. create a graph (JKQTPColumnMathImage) with the column created above as data
|
||||
// The data is color-coded with the color-palette JKQTPMathImageMATLAB
|
||||
// the converted range of data is determined automatically because s etAutoImageRange(true)
|
||||
JKQTPColumnRGBMathImage* graph=new JKQTPColumnRGBMathImage(&plot);
|
||||
graph->setTitle("");
|
||||
// image column with the data (R/G/B or C/M/Y ...)
|
||||
graph->setImageGColumn(cAiryDisk1); // G/M channel
|
||||
graph->setImageBColumn(cAiryDisk2); // B/Y channel
|
||||
// set size of the data (the datastore does not contain this info, as it only manages 1D columns of data and this is used to assume a row-major ordering
|
||||
graph->setNx(NX);
|
||||
graph->setNy(NY);
|
||||
// where does the image start in the plot, given in plot-axis-coordinates (bottom-left corner)
|
||||
graph->setX(-w/2.0);
|
||||
graph->setY(-h/2.0);
|
||||
// width and height of the image in plot-axis-coordinates
|
||||
graph->setWidth(w);
|
||||
graph->setHeight(h);
|
||||
// get coordinate axis of color-bar and set its label
|
||||
graph->getColorBarRightAxisB()->setAxisLabel("blue light field strength [AU]");
|
||||
graph->getColorBarRightAxisG()->setAxisLabel("green light field strength [AU]");
|
||||
// determine min/max of data automatically and use it to set the range of the color-scale
|
||||
graph->setAutoImageRange(true);
|
||||
// use (subtractive) CMY color model, not RGB
|
||||
//graph->setRgbMode(JKQTPRGBMathImageModeCMYMode);
|
||||
|
||||
|
||||
// 5. add the graphs to the plot, so it is actually displayed
|
||||
plot.addGraph(graph);
|
||||
|
||||
|
||||
// 6. set axis labels
|
||||
plot.getXAxis()->setAxisLabel("x [{\\mu}m]");
|
||||
plot.getYAxis()->setAxisLabel("y [{\\mu}m]");
|
||||
|
||||
|
||||
// 7. fix axis and plot aspect ratio to 1
|
||||
plot.getPlotter()->setMaintainAspectRatio(true);
|
||||
plot.getPlotter()->setMaintainAxisAspectRatio(true);
|
||||
|
||||
// 8 autoscale the plot so the graph is contained
|
||||
plot.zoomToFit();
|
||||
|
||||
// show plotter and make it a decent size
|
||||
plot.show();
|
||||
plot.resize(600,600);
|
||||
plot.setWindowTitle("JKQTPColumnRGBMathImage");
|
||||
|
||||
|
||||
return app.exec();
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
# source code for this simple demo
|
||||
SOURCES = jkqtplotter_simpletest_rgbimageplot.cpp
|
||||
|
||||
# configure Qt
|
||||
CONFIG += link_prl qt
|
||||
QT += core gui xml svg
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport
|
||||
|
||||
# output executable name
|
||||
TARGET = jkqtplotter_simpletest_rgbimageplot
|
||||
|
||||
# include JKQTPlotter source code
|
||||
DEPENDPATH += ../../lib ../../staticlib/jkqtplotterlib
|
||||
INCLUDEPATH += ../../lib
|
||||
CONFIG (debug, debug|release) {
|
||||
LIBS += -L../../staticlib/jkqtplotterlib/debug -ljkqtplotterlib_debug
|
||||
} else {
|
||||
LIBS += -L../../staticlib/jkqtplotterlib/release -ljkqtplotterlib
|
||||
}
|
||||
message("LIBS = $$LIBS")
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,8 @@
|
||||
TEMPLATE = subdirs
|
||||
|
||||
SUBDIRS += jkqtplotterlib jkqtplotter_simpletest_rgbimageplot
|
||||
|
||||
jkqtplotterlib.file = ../../staticlib/jkqtplotterlib/jkqtplotterlib.pro
|
||||
|
||||
jkqtplotter_simpletest_rgbimageplot.file=$$PWD/jkqtplotter_simpletest_rgbimageplot.pro
|
||||
jkqtplotter_simpletest_rgbimageplot.depends = jkqtplotterlib
|
@ -1,8 +1,8 @@
|
||||
# Example (JKQTPlotter): Simple RGB image plot, showing a 3-channel OpenCV cv::Mat {#JKQTPlotterImagePlotRGBOpenCV}
|
||||
This project (see `./examples/simpletest_imageplot_opencv/`) simply creates a JKQTPlotter widget (as a new window) and adds a color-coded image plot of a mathematical function (here the Airy disk). The image is generated as an OpenCV cv::Mat image and then copied into a single column of the internal datasdtore (JKQTPMathImage could be directly used without the internal datastore).
|
||||
To copy the data a special OpenCV Interface function `JKQTPCopyCvMatToColumn()` is used, that copies the data from a cv::Mat directly into a column.
|
||||
This project (see `./examples/simpletest_imageplot_opencv/`) simply creates a JKQTPlotter widget (as a new window) and shows an RGB image read from a BMP-file. The image is generated as an [OpenCV](https://opencv.org/) [`cv::Mat`](https://docs.opencv.org/4.0.0/d3/d63/classcv_1_1Mat.html) image and then copied into a single column of the internal datasdtore (JKQTPMathImage could be directly used without the internal datastore).
|
||||
To copy the data a special OpenCV Interface function `JKQTPCopyCvMatToColumn()` is used, that copies the data from a (https://opencv.org/) [`cv::Mat`](https://docs.opencv.org/4.0.0/d3/d63/classcv_1_1Mat.html) directly into a column.
|
||||
|
||||
The function `JKQTPCopyCvMatToColumn()` is available from the (non-default) header-only extension from `jkqtplotter/jkqtpopencvinterface.h`. This header provides facilities to interface JKQTPlotter with OPenCV.
|
||||
The function `JKQTPCopyCvMatToColumn()` is available from the (non-default) header-only extension from `jkqtplotter/jkqtpopencvinterface.h`. This header provides facilities to interface JKQTPlotter with OpenCV.
|
||||
|
||||
The source code of the main application is (see [`jkqtplotter_simpletest_imageplot_opencv.cpp`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_imageplot_opencv/jkqtplotter_simpletest_imageplot_opencv.cpp):
|
||||
```.cpp
|
||||
@ -99,4 +99,15 @@ The result looks like this:
|
||||
|
||||
The image is upside-down, because computer images use a coordinate system with 0 at the top-left (left-handed coordinate system) and the JKQTPlotter has its 0 at the bottom-left (right-handed coordinate system).
|
||||
|
||||
You can modify the program above to display the image in the correct orientation, by adding the line
|
||||
```.cpp
|
||||
// 5.1 invert y-axis, so image is oriented correctly
|
||||
plot.getYAxis()->setInverted(true);
|
||||
```
|
||||
This will reorient the y-axis to point from top to bottom (for increasing positive coordinates):
|
||||
|
||||
![jkqtplotter_simpletest_imageplot](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_rgbimageplot_opencv_updisdedown.png)
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "jkqtplotter/jkqtpgraphs.h"
|
||||
#include "jkqtplotter/jkqtpgraphsimagergb.h"
|
||||
#include "jkqtplotter/jkqtpopencvinterface.h"
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include <opencv2/imgcodecs.hpp>
|
||||
|
||||
|
||||
@ -30,6 +31,7 @@ int main(int argc, char* argv[])
|
||||
|
||||
// 2. now we open a BMP-file and load it into an OpenCV cv::Mat
|
||||
cv::Mat picture = cv::imread("example.bmp");
|
||||
qDebug()<<picture.rows<<"x"<<picture.cols<<"x"<<picture.channels();
|
||||
|
||||
|
||||
|
||||
@ -73,6 +75,8 @@ int main(int argc, char* argv[])
|
||||
// 6. set axis labels
|
||||
plot.getXAxis()->setAxisLabel("x [pixels]");
|
||||
plot.getYAxis()->setAxisLabel("y [pixels]");
|
||||
// 6.1 invert y-axis, so image is oriented correctly
|
||||
plot.getYAxis()->setInverted(true);
|
||||
|
||||
// 7. fix axis aspect ratio to width/height, so pixels are square
|
||||
plot.getPlotter()->setMaintainAspectRatio(true);
|
||||
|
@ -9,22 +9,29 @@ greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport
|
||||
# output executable name
|
||||
TARGET = jkqtplotter_simpletest_rgbimageplot_opencv
|
||||
|
||||
# add OpenCV-interface to JKQTPDatastore
|
||||
DEFINES += JKQTPLOTTER_OPENCV_INTERFACE
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
exampleimg.files=$$PWD/example.bmp
|
||||
exampleimg.path=$$OUT_PWD
|
||||
|
||||
|
||||
# link agains OpenCV-3.4.1
|
||||
INCLUDEPATH += $$PWD/OpenCV-3.4.1/include/
|
||||
LIBS += -L$$PWD/OpenCV-3.4.1/bin/ -llibopencv_core341 -llibopencv_imgcodecs341
|
||||
#INCLUDEPATH += $$PWD/../../../OpenCV-3.4.1/include/
|
||||
#LIBS += -L$$PWD/../../../OpenCV-3.4.1/bin/ -llibopencv_core341 -llibopencv_imgcodecs341
|
||||
#opencvdlls.files=$$PWD/../../../OpenCV-3.4.1/bin/*.dll
|
||||
#opencvdlls.path=$$OUT_PWD
|
||||
|
||||
# link agains OpenCV-4
|
||||
INCLUDEPATH += $$PWD/../../../OpenCV-4.0.1/include/
|
||||
LIBS += -L$$PWD/../../../OpenCV-4.0.1/x64/mingw/bin -L$$PWD/../../../OpenCV-4.0.1/x64/mingw/lib -llibopencv_core400.dll -llibopencv_imgcodecs400.dll
|
||||
opencvdlls.files=$$PWD/../../../OpenCV-4.0.1/x64/mingw/bin/*.dll
|
||||
opencvdlls.path=$$OUT_PWD
|
||||
|
||||
INCLUDEPATH+=../../lib
|
||||
|
||||
CONFIG (debug, debug|release) {
|
||||
LIBS += -L../../staticlib/jkqtplotterlib/debug -ljkqtplotterlib_debug
|
||||
} else {
|
||||
LIBS += -L../../staticlib/jkqtplotterlib/release -ljkqtplotterlib
|
||||
}
|
||||
message("LIBS = $$LIBS")
|
||||
message("LIBS = $$LIBS")
|
||||
|
||||
INSTALLS += opencvdlls exampleimg
|
||||
|
@ -0,0 +1,8 @@
|
||||
TEMPLATE = subdirs
|
||||
|
||||
SUBDIRS += jkqtplotterlib jkqtplotter_simpletest_rgbimageplot_opencv
|
||||
|
||||
jkqtplotterlib.file = ../../staticlib/jkqtplotterlib/jkqtplotterlib.pro
|
||||
|
||||
jkqtplotter_simpletest_rgbimageplot_opencv.file=$$PWD/jkqtplotter_simpletest_rgbimageplot_opencv.pro
|
||||
jkqtplotter_simpletest_rgbimageplot_opencv.depends = jkqtplotterlib
|
@ -28,4 +28,16 @@ The result looks like this:
|
||||
![jkqtplotter_simpletest_imageplot](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_rgbimageplot_qt.png)
|
||||
|
||||
|
||||
The image is upside-down, because computer images use a coordinate system with 0 at the top-left (left-handed coordinate system) and the JKQTPlotter has its 0 at the bottom-left (right-handed coordinate system).
|
||||
|
||||
You can modify the program above to display the image in the correct orientation, by adding the line
|
||||
```.cpp
|
||||
// 6.1 invert y-axis, so image is oriented correctly
|
||||
plot.getYAxis()->setInverted(true);
|
||||
```
|
||||
This will reorient the y-axis to point from top to bottom (for increasing positive coordinates):
|
||||
|
||||
![jkqtplotter_simpletest_imageplot](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_rgbimageplot_qt_updisdedown.png)
|
||||
|
||||
|
||||
|
||||
|
@ -51,6 +51,8 @@ int main(int argc, char* argv[])
|
||||
// 5. set axis labels
|
||||
plot.getXAxis()->setAxisLabel("x [pixels]");
|
||||
plot.getYAxis()->setAxisLabel("y [pixels]");
|
||||
// 5.1 invert y-axis, so image is oriented correctly
|
||||
plot.getYAxis()->setInverted(true);
|
||||
|
||||
// 6. fix axis aspect ratio to width/height, so pixels are square
|
||||
plot.getPlotter()->setMaintainAspectRatio(true);
|
||||
|
@ -105,6 +105,16 @@ class JKQTBasePlotter;
|
||||
are implemented in p2x(). They can be used to show the system coordinates of the current mouse position.
|
||||
|
||||
|
||||
\section jkqtplotter_coordinateaxes_inverted Inverted Coordinate Axes
|
||||
|
||||
In some cases it may be necessary to invert the direction of increasing coordinates on an axis. One such case is image analysis, as computer images usually
|
||||
have coordinates starting with (0,0) at the top left and increasing to the right (x) and down (y). You can invert any axis by setting \c setInverted(true).
|
||||
|
||||
\image html jkqtplotter_inverted_yaxis.png
|
||||
|
||||
\see You can find example here: \ref JKQTPlotterImagePlotQImageRGB and \ref JKQTPlotterImagePlotRGBOpenCV
|
||||
|
||||
|
||||
\section jkqtplotter_base_grids_baseelemenets Axis JKQTPCoordinateAxisStyle::Ticks and Grids
|
||||
|
||||
This section explains how this component draws the JKQTPCoordinateAxisStyle::ticks on coordinate axes and the grids that may be drawn below
|
||||
@ -708,7 +718,10 @@ class JKQTP_LIB_EXPORT JKQTPCoordinateAxis: public QObject {
|
||||
* \see calcPlotScaling(), calcTickSpacing()
|
||||
*/
|
||||
double offset;
|
||||
/** \brief indicates whether the axis is to be inverted or not */
|
||||
/** \brief indicates whether the axis is to be inverted or not
|
||||
*
|
||||
* \image html jkqtplotter_inverted_yaxis.png
|
||||
*/
|
||||
bool inverted;
|
||||
|
||||
/** \brief <b>calculated property:</b> x position of the first tick (calculated by calcPlotScaling() ). Given in system coordinates, not pixel coordinates.
|
||||
|
@ -34,9 +34,6 @@
|
||||
#include <QStringList>
|
||||
#include <QAbstractTableModel>
|
||||
#include <QObject>
|
||||
#ifdef JKQTPLOTTER_OPENCV_INTERFACE
|
||||
# include <opencv/cv.h>
|
||||
#endif
|
||||
#ifndef JKQTPDATASTORAGE_H
|
||||
#define JKQTPDATASTORAGE_H
|
||||
|
||||
|
@ -97,7 +97,7 @@ QColor JKQTPImageBase::getKeyLabelColor() {
|
||||
}
|
||||
|
||||
void JKQTPImageBase::plotImage(JKQTPEnhancedPainter& painter, QImage& image, double x, double y, double width, double height) {
|
||||
if ((!JKQTPIsOKFloat(x))||(!JKQTPIsOKFloat(y))||(!JKQTPIsOKFloat(width))||(!JKQTPIsOKFloat(height))||(width<=0) || (height<=0) || image.isNull() || (image.width()<=0) || (image.height()<=0)) {
|
||||
if ((!JKQTPIsOKFloat(x))||(!JKQTPIsOKFloat(y))||(!JKQTPIsOKFloat(width))||(!JKQTPIsOKFloat(height))||(width==0) || (height==0) || image.isNull() || (image.width()<=0) || (image.height()<=0)) {
|
||||
return;
|
||||
}
|
||||
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
||||
@ -110,13 +110,37 @@ void JKQTPImageBase::plotImage(JKQTPEnhancedPainter& painter, QImage& image, dou
|
||||
QPointF pp2=transform(xmax,ymin);
|
||||
QRectF pr(pp1, pp2);
|
||||
|
||||
bool mirrx=false;
|
||||
bool mirry=false;
|
||||
|
||||
QPointF p1=transform(x,y+height);
|
||||
QPointF p2=transform(x+width,y);
|
||||
if (p1.x()>p2.x()) {
|
||||
double tmp=p1.x();
|
||||
p1.setX(p2.x());
|
||||
p2.setX(tmp);
|
||||
tmp=pp1.x();
|
||||
pp1.setX(pp2.x());
|
||||
pp2.setX(tmp);
|
||||
mirrx=true;
|
||||
}
|
||||
if (p1.y()>p2.y()) {
|
||||
double tmp=p1.y();
|
||||
p1.setY(p2.y());
|
||||
p2.setY(tmp);
|
||||
tmp=pp1.y();
|
||||
pp1.setY(pp2.y());
|
||||
pp2.setY(tmp);
|
||||
mirry=true;
|
||||
}
|
||||
QRectF r(p1, p2);
|
||||
|
||||
|
||||
|
||||
if (image.width()>0 && image.height()>0 && !image.isNull()) {
|
||||
if (r.width()<2*pr.width() && r.height()<2*pr.height()) {
|
||||
//painter.drawImage(QRectF(p1.x(), p2.y(), fabs(p2.x()-p1.x()), fabs(p2.y()-p1.y())), image);
|
||||
painter.drawImage(QPoint(p1.x(), p1.y()), image.scaled(QSize(fabs(p2.x()-p1.x()), fabs(p2.y()-p1.y())), Qt::IgnoreAspectRatio, Qt::FastTransformation));
|
||||
painter.drawImage(QPoint(p1.x(), p1.y()), image.mirrored(mirrx, mirry).scaled(QSize(fabs(p2.x()-p1.x()), fabs(p2.y()-p1.y())), Qt::IgnoreAspectRatio, Qt::FastTransformation));
|
||||
//qDebug()<<"\nimage.size = "<<image.size() <<" SIMPLE!";
|
||||
} else {
|
||||
double pixwidth=fabs(p2.x()-p1.x())/static_cast<double>(image.width());
|
||||
@ -136,7 +160,7 @@ void JKQTPImageBase::plotImage(JKQTPEnhancedPainter& painter, QImage& image, dou
|
||||
QRectF target(p1.x()+ps1.x()*pixwidth, p1.y()+ps1.y()*pixheight, source.width()*pixwidth, source.height()*pixheight);
|
||||
//qDebug()<<"source = "<<source;
|
||||
//qDebug()<<"target = "<<target;
|
||||
painter.drawImage(target, image, source);
|
||||
painter.drawImage(target, image.mirrored(mirrx, mirry), source);
|
||||
}
|
||||
}
|
||||
|
||||
@ -212,7 +236,7 @@ void JKQTPImage::drawKeyMarker(JKQTPEnhancedPainter &painter, QRectF &rect)
|
||||
void JKQTPImage::setImage(const QImage &image)
|
||||
{
|
||||
clear_image();
|
||||
this->image=new QImage(image);
|
||||
this->image=new QImage(image.mirrored(false, true));
|
||||
image_owned=true;
|
||||
createImageActions();
|
||||
}
|
||||
|
@ -911,7 +911,14 @@ void JKQTPColumnRGBMathImage::ensureImageData()
|
||||
this->data=parent->getDatastore()->getColumn(imageRColumn).getPointer(0);
|
||||
this->dataG=parent->getDatastore()->getColumn(imageGColumn).getPointer(0);
|
||||
this->dataB=parent->getDatastore()->getColumn(imageBColumn).getPointer(0);
|
||||
this->Ny=parent->getDatastore()->getColumn(imageRColumn).getRows()/this->Nx;
|
||||
/*if (Nx*Ny==0 || Nx*Ny>parent->getDatastore()->getColumn(imageRColumn).getRows()) {
|
||||
if (Nx>0) {
|
||||
Ny=parent->getDatastore()->getColumn(imageRColumn).getRows()/this->Nx;
|
||||
} else {
|
||||
Nx=parent->getDatastore()->getColumn(imageRColumn).getRows();
|
||||
Ny=1;
|
||||
}
|
||||
}*/
|
||||
this->datatypeModifier=JKQTPMathImageBase::DoubleArray;
|
||||
this->dataModifier=parent->getDatastore()->getColumn(modifierColumn).getPointer(0);
|
||||
}
|
||||
|
@ -518,7 +518,12 @@ class JKQTP_LIB_EXPORT JKQTPRGBMathImage: public JKQTPMathImageBase {
|
||||
|
||||
|
||||
\image html rgbimageplots.png
|
||||
|
||||
\image html jkqtplotter_simpletest_rgbimageplot_opencv.png
|
||||
|
||||
\image html jkqtplotter_simpletest_rgbimageplot.png
|
||||
|
||||
\see Examples: \ref JKQTPlotterRGBImagePlot and \ref JKQTPlotterImagePlotRGBOpenCV
|
||||
*/
|
||||
class JKQTP_LIB_EXPORT JKQTPColumnRGBMathImage: public JKQTPRGBMathImage {
|
||||
Q_OBJECT
|
||||
|
@ -20,8 +20,8 @@
|
||||
|
||||
|
||||
#include "jkqtplottertools/jkqtp_imexport.h"
|
||||
#include "jkqtplotter/jkqtpdatastore.h"
|
||||
#include <opencv/cv.h>
|
||||
#include "jkqtplotter/jkqtpdatastorage.h"
|
||||
#include <opencv2/core.hpp>
|
||||
|
||||
#ifndef JKQTPOPENCVINTERFACE_H
|
||||
#define JKQTPOPENCVINTERFACE_H
|
||||
|
@ -164,12 +164,16 @@ enum JKQTPMathImageColorRangeFailAction {
|
||||
|
||||
/*! \brief modes available for RGB images
|
||||
\ingroup jkqtplotter_imagelots_tools
|
||||
|
||||
|
||||
\see Examples: \ref JKQTPlotterRGBImagePlot
|
||||
|
||||
*/
|
||||
enum JKQTPRGBMathImageRGBMode {
|
||||
JKQTPRGBMathImageModeRGBMode=0,
|
||||
JKQTPRGBMathImageModeHSVMode=1,
|
||||
JKQTPRGBMathImageModeHSLMode=2,
|
||||
JKQTPRGBMathImageModeCMYMode=3
|
||||
JKQTPRGBMathImageModeRGBMode=0, /*!< image channels are mapped to the R, G and B channel (red-green-blue) */
|
||||
JKQTPRGBMathImageModeHSVMode=1, /*!< image channels are mapped to the H, S and V channel (hue-saturation-value) */
|
||||
JKQTPRGBMathImageModeHSLMode=2, /*!< image channels are mapped to the H, S and L channel (bue-saturation-luminance) */
|
||||
JKQTPRGBMathImageModeCMYMode=3 /*!< image channels are mapped to the C, M and Y channel (subtractive color model!!!) */
|
||||
};
|
||||
|
||||
|
||||
|
BIN
screenshots/jkqtplotter_simpletest_rgbimageplot.png
Normal file
After Width: | Height: | Size: 80 KiB |
BIN
screenshots/jkqtplotter_simpletest_rgbimageplot_cmy.png
Normal file
After Width: | Height: | Size: 80 KiB |
Before Width: | Height: | Size: 326 KiB After Width: | Height: | Size: 331 KiB |
After Width: | Height: | Size: 318 KiB |
Before Width: | Height: | Size: 332 KiB After Width: | Height: | Size: 331 KiB |
After Width: | Height: | Size: 331 KiB |
BIN
screenshots/jkqtplotter_simpletest_rgbimageplot_small.png
Normal file
After Width: | Height: | Size: 18 KiB |