opencv:如何在方向图像上绘制箭头
opencv: how to draw arrows on orientation image
我正在尝试在 OpenCV 中对输入图像执行方向估计。我使用 sobel 函数来获取图像的梯度,并使用我在互联网上找到的另一个名为 calculateOrientations
的函数来计算方向。
代码如下:
void computeGradient(cv::Mat inputImg)
{
// Gradient X
cv::Sobel(inputImg, grad_x, CV_16S, 1, 0, 5, 1, 0, cv::BORDER_DEFAULT);
cv::convertScaleAbs(grad_x, abs_grad_x);
// Gradient Y
cv::Sobel(inputImg, grad_y, CV_16S, 0, 1, 5, 1, 0, cv::BORDER_DEFAULT);
cv::convertScaleAbs(grad_y, abs_grad_y);
// convert from CV_8U to CV_32F
abs_grad_x.convertTo(abs_grad_x2, CV_32F, 1. / 255);
abs_grad_y.convertTo(abs_grad_y2, CV_32F, 1. / 255);
// calculate orientations
calculateOrientations(abs_grad_x2, abs_grad_y2);
}
void calculateOrientations(cv::Mat gradientX, cv::Mat gradientY)
{
// Create container element
orientation = cv::Mat(gradientX.rows, gradientX.cols, CV_32F);
// Calculate orientations of gradients --> in degrees
// Loop over all matrix values and calculate the accompagnied orientation
for (int i = 0; i < gradientX.rows; i++){
for (int j = 0; j < gradientX.cols; j++){
// Retrieve a single value
float valueX = gradientX.at<float>(i, j);
float valueY = gradientY.at<float>(i, j);
// Calculate the corresponding single direction, done by applying the arctangens function
float result = cv::fastAtan2(valueX, valueY);
// Store in orientation matrix element
orientation.at<float>(i, j) = result;
}
}
}
现在,我需要确定获取的方向是否正确。为此,我想在方向矩阵上为每个大小为 5x5 的块绘制箭头。有人可以建议我如何在上面画箭头吗?谢谢你。
OpenCV区分方向最简单的方法就是在直线的起点或终点画一个小圆圈或正方形。箭头 afaik 没有功能。如果你需要箭头,你必须写这个(这很简单但也需要时间)。一旦我这样做了(不是openCV,但我希望你转换它):
double arrow_pos = 0.5; // 0.5 = at the center of line
double len = sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
double co = (x2-x1)/len, si = (y2-y1)/len; // line coordinates are (x1,y1)-(x2,y2)
double const l = 15, sz = linewidth*2; // l - arrow length
double x0 = x2 - len*arrow_pos*co;
double y0 = y2 - len*arrow_pos*si;
double x = x2 - (l+len*arrow_pos)*co;
double y = y2 - (l+len*arrow_pos)*si;
TPoint tp[4] = {TPoint(x+sz*si, y-sz*co), TPoint(x0, y0), TPoint(x-sz*si, y+sz*co), TPoint(x+l*0.3*co, y+0.3*l*si)};
Polygon(tp, 3);
Canvas->Polyline(tp, 2);
更新:自 OpenCV 2.4.10 和 3.0 以来添加的 arrowedLine(...) 函数
在opencv中绘制箭头最简单的方法是:
arrowedLine(img, pointStart, pointFinish, colorScalar, thickness, line_type, shift, tipLength);
厚度、line_type、偏移和 tipLength已经有默认值,可以省略
我正在尝试在 OpenCV 中对输入图像执行方向估计。我使用 sobel 函数来获取图像的梯度,并使用我在互联网上找到的另一个名为 calculateOrientations
的函数来计算方向。
代码如下:
void computeGradient(cv::Mat inputImg)
{
// Gradient X
cv::Sobel(inputImg, grad_x, CV_16S, 1, 0, 5, 1, 0, cv::BORDER_DEFAULT);
cv::convertScaleAbs(grad_x, abs_grad_x);
// Gradient Y
cv::Sobel(inputImg, grad_y, CV_16S, 0, 1, 5, 1, 0, cv::BORDER_DEFAULT);
cv::convertScaleAbs(grad_y, abs_grad_y);
// convert from CV_8U to CV_32F
abs_grad_x.convertTo(abs_grad_x2, CV_32F, 1. / 255);
abs_grad_y.convertTo(abs_grad_y2, CV_32F, 1. / 255);
// calculate orientations
calculateOrientations(abs_grad_x2, abs_grad_y2);
}
void calculateOrientations(cv::Mat gradientX, cv::Mat gradientY)
{
// Create container element
orientation = cv::Mat(gradientX.rows, gradientX.cols, CV_32F);
// Calculate orientations of gradients --> in degrees
// Loop over all matrix values and calculate the accompagnied orientation
for (int i = 0; i < gradientX.rows; i++){
for (int j = 0; j < gradientX.cols; j++){
// Retrieve a single value
float valueX = gradientX.at<float>(i, j);
float valueY = gradientY.at<float>(i, j);
// Calculate the corresponding single direction, done by applying the arctangens function
float result = cv::fastAtan2(valueX, valueY);
// Store in orientation matrix element
orientation.at<float>(i, j) = result;
}
}
}
现在,我需要确定获取的方向是否正确。为此,我想在方向矩阵上为每个大小为 5x5 的块绘制箭头。有人可以建议我如何在上面画箭头吗?谢谢你。
OpenCV区分方向最简单的方法就是在直线的起点或终点画一个小圆圈或正方形。箭头 afaik 没有功能。如果你需要箭头,你必须写这个(这很简单但也需要时间)。一旦我这样做了(不是openCV,但我希望你转换它):
double arrow_pos = 0.5; // 0.5 = at the center of line
double len = sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
double co = (x2-x1)/len, si = (y2-y1)/len; // line coordinates are (x1,y1)-(x2,y2)
double const l = 15, sz = linewidth*2; // l - arrow length
double x0 = x2 - len*arrow_pos*co;
double y0 = y2 - len*arrow_pos*si;
double x = x2 - (l+len*arrow_pos)*co;
double y = y2 - (l+len*arrow_pos)*si;
TPoint tp[4] = {TPoint(x+sz*si, y-sz*co), TPoint(x0, y0), TPoint(x-sz*si, y+sz*co), TPoint(x+l*0.3*co, y+0.3*l*si)};
Polygon(tp, 3);
Canvas->Polyline(tp, 2);
更新:自 OpenCV 2.4.10 和 3.0 以来添加的 arrowedLine(...) 函数
在opencv中绘制箭头最简单的方法是:
arrowedLine(img, pointStart, pointFinish, colorScalar, thickness, line_type, shift, tipLength);
厚度、line_type、偏移和 tipLength已经有默认值,可以省略