QCustomPlot draw residuum between two functions - c++

I want to draw the residuum between two functions at discrete points with qcustomplot.
I know the position (x), the starting value y.at(x) and the height.at(x).
what I have so far is an error bar with y+-error:
QCPErrorBars *errorBars = new QCPErrorBars(customPlot->xAxis, customPlot->yAxis);
errorBars->setDataPlottable(customPlot->graph(0));
QVector<double> y1err(x.size());
for (int i = 0; i<x.size(); ++i)
{
y1err[i] = y.at(i) * error;
}
customPlot->graph(0)->setData(QVector<double>::fromStdVector(x), QVector<double>::fromStdVector(y));
errorBars->setData(y1err);
or a bar starting from zero:
QCPBars *newBars = new QCPBars(customPlot->xAxis, customPlot->yAxis);
std::vector<double> xData, yData;
for (auto i = 0; i < x.size(); ++i)
{
xData.push_back(i+1);
yData.push_back(y.at(i));
}
newBars->setData(QVector<double>::fromStdVector(x), QVector<double>::fromStdVector(y));
but what I really want is some kind of a plot starting at the value y.at(x) with the height of the residuum at the point x in addition to the two x-y plots.
How can I plot a bar or error bar starting at the y.at(x) with height.at(x)?
Thank you

For other people facing this problem I found some kind of a solution.
void QLinePlot::AddResiduumData(std::vector<double> x, std::vector<double> y_mid, std::vector<double> y_res)
{
customPlot->addGraph();
++graphCountI;
QCPErrorBars *errorBars = new QCPErrorBars(customPlot->xAxis, customPlot->yAxis);
errorBars->setDataPlottable(customPlot->graph(graphCountI - 1));
customPlot->graph(graphCountI - 1)->setData(QVector<double>::fromStdVector(x), QVector<double>::fromStdVector(y_mid));
customPlot->graph(graphCountI - 1)->setVisible(false);
errorBars->setData(QVector<double>::fromStdVector(y_res));
customPlot->replot();
}
The idea behind this is adding a new invisible graph between both plots and give the error as half the distance between both.

Related

QCustomPlot add scatter points on top of existing plot

After creating a plot using qcustomplot, how can I, based on existing X values, retrieve the Y values, and then plot points at these locations?
My attempt is below:
Create plot:
This function creates a plot, adds some data (dates) on the x-axis and some values on the y axis:
void Qt_PlotTest::createPlot(){
QCustomPlot* customPlot = ui.widget;
customPlot->setLocale(QLocale(QLocale::English, QLocale::UnitedKingdom));
//Set some data:
double now = QDateTime::currentDateTime().toTime_t();
QVector<double> yData, xData;
for (int i = 0; i < 100; i++){
xData.push_back(now + i*24.0 * 3600.0);
yData.push_back(pow(double(i), 2) + 550.0*sin(double(i)/4.0));
}
// create graph and assign data to it:
customPlot->addGraph();
customPlot->graph(0)->setData(xData, yData);
//Fix axes:
//Set date axis:
QSharedPointer<QCPAxisTickerDateTime> dateTicker(new QCPAxisTickerDateTime);
dateTicker->setDateTimeFormat("d. MMMM\nyyyy");
customPlot->xAxis->setTicker(dateTicker);
customPlot->xAxis->setLabel("Time");
customPlot->yAxis->setLabel("Value");
customPlot->rescaleAxes();
customPlot->replot();
//Set interations:
customPlot->setInteraction(QCP::iRangeDrag, true);
customPlot->setInteraction(QCP::iRangeZoom, true);
}
Which results in:
Set scatter points:
This functions should plot a few scatter points at correct x/y locations based on x values. (I need to read the corresponding Y value from the existing plot).
void Qt_PlotTest::setScatterPoints(){
QCustomPlot* customPlot = ui.widget;
//The locations where scatter points should be plotted:
QDate qd1(2018, 03, 26), qd2(2018, 03, 30), qd3(2018, 05, 11), qd4(2018, 06, 15);
QVector<double> dates = { (double)QDateTime(qd1).toTime_t(), (double)QDateTime(qd2).toTime_t(), (double)QDateTime(qd3).toTime_t(), (double)QDateTime(qd4).toTime_t() };
//Use tracer to find data at these dates:
QVector<double> values;
QCPItemTracer *tracer = new QCPItemTracer(customPlot);
tracer->setGraph(customPlot->graph(0));
tracer->setInterpolating(true);
for (int i = 0; i < 4; i++){
tracer->setGraphKey(dates[i]);
values.push_back(tracer->position->coords().y());
}
//Plot points at these locations:
QCPGraph* dwPoints = new QCPGraph(customPlot->xAxis, customPlot->yAxis);
dwPoints->setAdaptiveSampling(false);
dwPoints->setLineStyle(QCPGraph::lsNone);
dwPoints->setScatterStyle(QCPScatterStyle::ssCircle);
dwPoints->setPen(QPen(QBrush(Qt::red), 2));
dwPoints->addData(dates, values);
customPlot->replot();
}
Which results in:
So obviously the QCPItemTracer didn't find the correct Y values. (I also got some additional axes which I don't want.)
Is QCPItemTracer what I want to use to achieve what I want? I also saw some example using QCPDataMap to find Y-values based on X-values. But as far as I understand, QCPDataMap, is no longer in qcustomplot.
I solved my own problem:
I had to call tracer->updatePosition() to actually get the coordinates in the coordinate system in which the tracer is placed.
The axes I didn't want were actually the visualization of the tracer at the final tracer location. I just had to call tracer->setVisibile(false) to hide it.
So in void Qt_PlotTest::setScatterPoints I have this:
QCPItemTracer *tracer = new QCPItemTracer(customPlot);
tracer->setGraph(customPlot->graph(0));
tracer->setInterpolating(true);
tracer->setVisible(false);
for (int i = 0; i < 4; i++){
tracer->setGraphKey(dates[i]);
tracer->updatePosition();
values.push_back(tracer->position->coords().y());
}
Result:

How to color cells of Voronoi diagram

I have created a vector of points. Each point can have any of the specified 16 colors. I am able to create a Voronoi diagram using the Boost library but am unable to color the cells efficiently. The Boost documentation says that there is a function as below :
void color(color_type color) const
to set color of the cells but I am unable to find any implementation example of it. The way Voronoi diagram is created, I um unable to do it. Please point in the right direction. This is what I have till now.
struct Point {
double a;
double b;
Point(double x, double y) : a(x), b(y) {}
};
// This point is mapped to Point concept of Boost.Code omitted
std::vector<Point_Collection> *points_info_vector;
points_info_vector = new std::vector<Point_Collection>();
for (int i = 0; i < 5000; i++) {
Point_Collection xy_color = { Point(rand() % 1000, rand() % 1000), rand() % 16 };
points_info_vector->push_back(xy_color);
}
std::vector<Point> *points;
points = new std::vector<Point>();
for (int i = 0; i < points_info_vector->size(); i++) {
points->push_back(points_info_vector->at(i).xy);
}
voronoi_diagram<double> vd;
construct_voronoi(points->begin(), points->end(), &vd);
Also, is there a more efficient way of using the construct_voronoi() with our Point_Collection structure without making a temporary structure just for points?
Found a partial answer : We can iterate over the cells and find out the index of the input geometry that is given by the builder library. Quoting the documentation :
Source index corresponds to the unique id, issued to each input geometry (e.g. incremental counter, used by the Voronoi builder).
So, I can do :
for (voronoi_diagram<double>::const_cell_iterator it = vd.cells().begin(); it!= vd.cells().end(); it++ )
{
std::cout << it->source_index() << "\n" ;
it->color(points_info_vector->at(it->source_index()).color);
}
So, from this index I can use the void color(color_type color) const to set the color of the cell from my earlier vector index.
Still, I would like to know an efficient way to create Voronoi diagram with the custom structure iterator as the function parameter, without having to copy the points to other vector.

C++ code for Microsoft Kinect - trying to dynamically allocate array of target positions

So I'm trying to modify the Kinect BodyBasicsD2D code so that a fixed number of "target positions" appear on the screen (as ellipses) for the user to move his hand toward. I'm having trouble creating the initial target positions.
This is my code in the header file for the allocation of the array of target positions (these are a public field of the CBodyBasics class, already built into the original BodyToBasics program):
D2D1_POINT_2F* targetPositions = NULL;
int numTargets = 3;
Then I have a function "GenerateTargetPositions" which is supposed to generate 3, in this case, target positions to be passed into the "DrawTargetPositions" function.
void CBodyBasics::GenerateTargetPositions(D2D1_POINT_2F * targetPositions, int numTargets)
{
targetPositions = new D2D1_POINT_2F[numTargets];
RECT rct;
GetClientRect(GetDlgItem(m_hWnd, IDC_VIDEOVIEW), &rct);
int width = rct.right;
int height = rct.bottom;
FLOAT x;
FLOAT y;
D2D1_POINT_2F tempPoint;
for (int i = 0; i < numTargets; i++) {
x = 1.0f*i*width / numTargets;
y = 1.0f*i*height / numTargets;
tempPoint = D2D1::Point2F(x, y);
targetPositions[i] = tempPoint;
}
}
My DrawTargetPositions function is:
void CBodyBasics::DrawTargetPositions(D2D1_POINT_2F * targetPositions, int numTargets)
{
D2D1_ELLIPSE ellipse;
for (int i = 0; i < numTargets; i++)
{
ellipse = D2D1::Ellipse(targetPositions[i], 50.f, 50.f);
m_pRenderTarget->FillEllipse(ellipse, m_pSilverBrush);
}
}
When I try to run my code, I get the error that both "targetPositions" and "targetPositions[i]" is NULL (and thus my GenerateTargetPositions function must not be working properly). I believe that targetPositions[i] is a struct (a point with x and y values) so I am wondering if this may be the reason for my errors.
I call GenerateTargetPositions and DrawTargetPositions before the main "while" loop in my code so that each function is not being called on each iteration (there are many iterations of through the while loop because this is an interactive Microsoft Kinect, recording one's movements).
Any suggestions and advice would be greatly appreciated. Thanks so much!

vtk 6.x, Qt: 3D (line, surface, scatter) plotting

I am working on a Qt (4.7.4) project and need to plot data in 2D and 3D coordinate systems. I've been looking into vtk 6.1 because it seems very powerful overall and I will also need to visualize image data at a later point. I basically got 2D plots working but am stuck plotting data in 3D.
Here's what I tried: I'm using the following piece of code that I took from one of vtk's tests ( Charts / Core / Testing / Cxx / TestSurfacePlot.cxx ). The only thing I added is the QVTKWidget that I use in my GUI and its interactor:
QVTKWidget vtkWidget;
vtkNew<vtkChartXYZ> chart;
vtkNew<vtkPlotSurface> plot;
vtkNew<vtkContextView> view;
view->GetRenderWindow()->SetSize(400, 300);
vtkWidget.SetRenderWindow(view->GetRenderWindow());
view->GetScene()->AddItem(chart.GetPointer());
chart->SetGeometry(vtkRectf(75.0, 20.0, 250, 260));
// Create a surface
vtkNew<vtkTable> table;
float numPoints = 70;
float inc = 9.424778 / (numPoints - 1);
for (float i = 0; i < numPoints; ++i)
{
vtkNew<vtkFloatArray> arr;
table->AddColumn(arr.GetPointer());
}
table->SetNumberOfRows(numPoints);
for (float i = 0; i < numPoints; ++i)
{
float x = i * inc;
for (float j = 0; j < numPoints; ++j)
{
float y = j * inc;
table->SetValue(i, j, sin(sqrt(x*x + y*y)));
}
}
// Set up the surface plot we wish to visualize and add it to the chart.
plot->SetXRange(0, 9.424778);
plot->SetYRange(0, 9.424778);
plot->SetInputData(table.GetPointer());
chart->AddPlot(plot.GetPointer());
view->GetRenderWindow()->SetMultiSamples(0);
view->SetInteractor(vtkWidget.GetInteractor());
view->GetInteractor()->Initialize();
view->GetRenderWindow()->Render();
Now, this produces a plot but I can neither interact with it not does it look 3D. I would like to do some basic stuff like zoom, pan, or rotate about a pivot. A few questions that come to my mind about this are:
Is it correct to assign the QVTKWidget interactor to the view in the third line from the bottom?
In the test, a vtkChartXYZ is added to the vtkContextView. According to the documentation, the vtkContextView is used to display a 2D scene but here is used with a 3D chart (XYZ). How does this fit together?
The following piece of code worked for me. No need to explicitly assign an interactor because that's already been taken care of by QVTKWidget.
QVTKWidget vtkWidget;
vtkSmartPointer<vtkContextView> view = vtkSmartPointer<vtkContextView>::New();
vtkSmartPointer<vtkChartXYZ> chart = vtkSmartPointer<vtkChartXYZ>::New();
// Create a surface
vtkSmartPointer<vtkTable> table = vtkSmartPointer<vtkTable>::New();
float numPoints = 70;
float inc = 9.424778 / (numPoints - 1);
for (float i = 0; i < numPoints; ++i)
{
vtkSmartPointer<vtkFloatArray> arr = vtkSmartPointer<vtkFloatArray>::New();
table->AddColumn(arr.GetPointer());
}
table->SetNumberOfRows(numPoints);
for (float i = 0; i < numPoints; ++i)
{
float x = i * inc;
for (float j = 0; j < numPoints; ++j)
{
float y = j * inc;
table->SetValue(i, j, sin(sqrt(x*x + y*y)));
}
}
view->SetRenderWindow(vtkWidget.GetRenderWindow());
chart->SetGeometry(vtkRectf(200.0, 200.0, 300, 300));
view->GetScene()->AddItem(chart.GetPointer());
vtkSmartPointer<vtkPlotSurface> plot = vtkSmartPointer<vtkPlotSurface>::New();
// Set up the surface plot we wish to visualize and add it to the chart.
plot->SetXRange(0, 10.0);
plot->SetYRange(0, 10.0);
plot->SetInputData(table.GetPointer());
chart->AddPlot(plot.GetPointer());
view->GetRenderWindow()->SetMultiSamples(0);
view->GetRenderWindow()->Render();
You might want read the detailed description in vtkRenderViewBase
QVTKWidget *widget = new QVTKWidget;
vtkContextView *view = vtkContextView::New();
view->SetInteractor(widget->GetInteractor());
widget->SetRenderWindow(view->GetRenderWindow());

Finding Local Maxima Grayscale Image opencv

I am trying to create my personal Blob Detection algorithm
As far as I know I first must create different Gaussian Kernels with different sigmas (which I am doing using Mat kernel= getGaussianKernel(x,y);) Then get the Laplacian of that kernel and then filter the Image with that so I create my scalespace. Now I need to find the Local Maximas in each result Image of the scalespace. But I cannot seem to find a proper way to do so.... my Code so far is
vector <Point> GetLocalMaxima(const cv::Mat Src,int MatchingSize, int Threshold)
{
vector <Point> vMaxLoc(0);
if ((MatchingSize % 2 == 0) ) // MatchingSize has to be "odd" and > 0
{
return vMaxLoc;
}
vMaxLoc.reserve(100); // Reserve place for fast access
Mat ProcessImg = Src.clone();
int W = Src.cols;
int H = Src.rows;
int SearchWidth = W - MatchingSize;
int SearchHeight = H - MatchingSize;
int MatchingSquareCenter = MatchingSize/2;
uchar* pProcess = (uchar *) ProcessImg.data; // The pointer to image Data
int Shift = MatchingSquareCenter * ( W + 1);
int k = 0;
for(int y=0; y < SearchHeight; ++y)
{
int m = k + Shift;
for(int x=0;x < SearchWidth ; ++x)
{
if (pProcess[m++] >= Threshold)
{
Point LocMax;
Mat mROI(ProcessImg, Rect(x,y,MatchingSize,MatchingSize));
minMaxLoc(mROI,NULL,NULL,NULL,&LocMax);
if (LocMax.x == MatchingSquareCenter && LocMax.y == MatchingSquareCenter)
{
vMaxLoc.push_back(Point( x+LocMax.x,y + LocMax.y ));
// imshow("W1",mROI);cvWaitKey(0); //For gebug
}
}
}
k += W;
}
return vMaxLoc;
}
which I found in this thread here, which it supposedly returns a vector of points where the maximas are. it does return a vector of points but all the x and y coordinates of each point are always -17891602... What to do???
Please if you are to lead me in something else other than correcting my code be informative because I know nothing about opencv. I am just learning
The problem here is that your LocMax point is declared inside the inner loop and never initialized, so it's returning garbage data every time. If you look back at the StackOverflow question you linked, you'll see that their similar variable Point maxLoc(0,0) is declared at the top and constructed to point at the middle of the search window. It only needs to be initialized once. Subsequent loop iterations will replace the value with the minMaxLoc function result.
In summary, remove this line in your inner loop:
Point LocMax; // delete this
And add a slightly altered version near the top:
vector <Point> vMaxLoc(0); // This was your original first line
Point LocMax(0,0); // your new second line
That should get you started anyway.
I found it guys. The problem was my threshold was too high. I do not understand why it gave me negative points instead of zero points but lowering the threshold worked