以下是一个使用OpenCV 2绘制向量曲线图的C ++函数的示例代码。假设向量x和y包含要绘制的数据点:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
void plotCurve(vector<double> x, vector<double> y) {
// 创建一个黑色的图像
Mat plot = Mat::zeros(Size(500, 500), CV_8UC3);
// 绘制坐标轴
line(plot, Point(50, 450), Point(450, 450), Scalar(255, 255, 255), 2, 8, 0);
line(plot, Point(50, 450), Point(50, 50), Scalar(255, 255, 255), 2, 8, 0);
// 计算数据的范围
double minX = *min_element(x.begin(), x.end());
double maxX = *max_element(x.begin(), x.end());
double minY = *min_element(y.begin(), y.end());
double maxY = *max_element(y.begin(), y.end());
// 将数据点转换为像素坐标
vector<Point> points;
for (int i = 0; i < x.size(); i++) {
int px = (x[i] - minX) / (maxX - minX) * 400 + 50;
int py = 450 - (y[i] - minY) / (maxY - minY) * 400;
points.push_back(Point(px, py));
}
// 绘制曲线
polylines(plot, points, false, Scalar(255, 0, 0), 2, 8, 0);
// 显示图像
imshow("Plot", plot);
waitKey(0);
}
该函数创建一个大小为500x500像素的黑色图像,并在图像上绘制坐标轴。然后,函数计算数据的范围,并将每个数据点转换为像素坐标。最后,使用polylines函数绘制数据点的曲线,并使用imshow函数显示图像。函数将等待按下任意键才会关闭显示窗口。
要使用该函数,只需将要绘制的数据点存储在vector<double>类型的向量x和y中,并将它们传递给plotCurve函数即可。例如:
int main() {
vector<double> x = {0, 1, 2, 3, 4, 5};
vector<double> y = {0, 1, 4, 9, 16, 25};
plotCurve(x, y);
return 0;
}
简化改造,不用输入x轴数据
以下是将前面的函数修改后,可以只输入y数据,x数据使用自动生成的刻度的C ++函数示例代码:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
void plotCurve(vector<double> y) {
// 创建一个黑色的图像
Mat plot = Mat::zeros(Size(500, 500), CV_8UC3);
// 绘制坐标轴
line(plot, Point(50, 450), Point(450, 450), Scalar(255, 255, 255), 2, 8, 0);
line(plot, Point(50, 450), Point(50, 50), Scalar(255, 255, 255), 2, 8, 0);
// 计算数据的范围和刻度
double minY = *min_element(y.begin(), y.end());
double maxY = *max_element(y.begin(), y.end());
double rangeY = maxY - minY;
double stepY = rangeY / 10;
// 绘制刻度和标签
for (int i = 0; i <= 10; i++) {
int py = 450 - i * 40;
double labelY = minY + i * stepY;
putText(plot, format("%.1f", labelY), Point(10, py + 5), FONT_HERSHEY_SIMPLEX, 0.4, Scalar(255, 255, 255), 1);
line(plot, Point(45, py), Point(55, py), Scalar(255, 255, 255), 2, 8, 0);
}
// 将数据点转换为像素坐标
vector<Point> points;
for (int i = 0; i < y.size(); i++) {
int px = (i + 0.5) / y.size() * 400 + 50;
int py = 450 - (y[i] - minY) / rangeY * 400;
points.push_back(Point(px, py));
}
// 绘制曲线
polylines(plot, points, false, Scalar(255, 0, 0), 2, 8, 0);
// 显示图像
imshow("Plot", plot);
waitKey(0);
}
该函数与前面的函数类似,但是在绘制坐标轴之后,它计算y数据的范围和步长,然后绘制y轴的刻度和标签。函数将自动生成x数据,并将每个数据点转换为像素坐标。最后,使用polylines函数绘制数据点的曲线,并使用imshow函数显示图像。函数将等待按下任意键才会关闭显示窗口。
要使用该函数,只需将要绘制的y数据点存储在vector<double>类型的向量y中,并将其传递给plotCurve函数即可。例如
int main() {
vector<double> y = {0, 1, 4, 9, 16, 25};
plotCurve(y);
return 0;
}
改进:允许输入任意数值类型变量
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
template<typename T>
void plotCurve(vector<T> x, vector<T> y) {
// 创建一个黑色的图像
Mat plot = Mat::zeros(Size(500, 500), CV_8UC3);
// 绘制坐标轴
line(plot, Point(50, 450), Point(450, 450), Scalar(255, 255, 255), 2, 8, 0);
line(plot, Point(50, 450), Point(50, 50), Scalar(255, 255, 255), 2, 8, 0);
// 计算数据的范围和刻度
double minY = *min_element(y.begin(), y.end());
double maxY = *max_element(y.begin(), y.end());
double rangeY = maxY - minY;
double stepY = rangeY / 10;
// 绘制刻度和标签
for (int i = 0; i <= 10; i++) {
int py = 450 - i * 40;
double labelY = minY + i * stepY;
putText(plot, format("%.1f", labelY), Point(10, py + 5), FONT_HERSHEY_SIMPLEX, 0.4, Scalar(255, 255, 255), 1);
line(plot, Point(45, py), Point(55, py), Scalar(255, 255, 255), 2, 8, 0);
}
// 将数据点转换为像素坐标
vector<Point> points;
for (int i = 0; i < y.size(); i++) {
int px = (x[i] - x[0]) / (x[x.size()-1] - x[0]) * 400 + 50;
int py = 450 - (y[i] - minY) / rangeY * 400;
points.push_back(Point(px, py));
}
// 绘制曲线
polylines(plot, points, false, Scalar(255, 0, 0), 2, 8, 0);
// 显示图像
imshow("Plot", plot);
waitKey(0);
}
还可以在内部加入类型校对进行类型限制,单变量的输入参数写法类似上面的代码,改一下就好了