OpenCV不仅提供了绘制线段、矩形、圆等方法,还提供了一个绘制箭头线段的函数arrowedLine(),OpenCV官方文档介绍:
https://docs.opencv.org/4.4.0/d6/d6e/group__imgproc__draw.html#ga0a165a3ca093fd488ac709fdf10c05b2
以OpenCV4.4.0为例,使用此函数需要包含头文件imgproc.hpp --> #include <opencv2/imgproc.hpp>
参数也比较容易理解:
img: 需要绘制箭头的图像
pt1, pt2:绘制箭头线段的起点和终点坐标
color: 绘制箭头线段的颜色
thickness: 箭头线段的线宽(线的粗细)
line_type: 绘制线的类型参考定义LineTypes
shitf: 坐标系中的小数位数?没明白有什么用,一般设置默认为0,改了可能会乱
tipLength: 箭头笔尖的长度(相对于线段长度的比例),默认0.1,比例越大箭头越长
下面是C OpenCV代码演示:
代码语言:javascript复制#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
Mat img = Mat::zeros(300, 300, CV_8UC3);
arrowedLine(img, Point(10, 30), Point(200, 30), Scalar(0, 255, 0), 2, 8, 0, 0.1);
arrowedLine(img, Point(10, 100), Point(200, 100), Scalar(255, 0, 0), 2, 8, 0, 0.2);
arrowedLine(img, Point(10, 170), Point(200, 170), Scalar(255, 0, 255), 2, 8, 0, 0.3);
imshow("绘制箭头", img);
waitKey(0);
return 0;
}
效果:
下面是Python OpenCV代码演示:
代码语言:javascript复制import numpy as np
import cv2
img = np.zeros((300,300,3),np.uint8)
cv2.arrowedLine(img, (10, 30), (200, 30), (0, 255, 0),
thickness=3, line_type=cv2.LINE_4, shift=0, tipLength=0.1)
cv2.arrowedLine(img, (10, 100), (200, 100), (255, 0, 0),
thickness=3, line_type=cv2.LINE_4, shift=0, tipLength=0.2)
cv2.arrowedLine(img, (10, 170), (200, 170), (255, 0, 255),
thickness=3, line_type=cv2.LINE_4, shift=0, tipLength=0.3)
cv2.imshow('LineArrows', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
这里有一个优化版的C OpenCV绘制带箭头线段的函数:
http://tmjfzy.blog.163.com/blog/static/664470252012225101017794/
代码语言:javascript复制
void drawArrow(cv::Mat& img, cv::Point pStart, cv::Point pEnd, int len, int alpha, cv::Scalar color, int thickness, int lineType)
{
const double PI = 3.1415926;
Point arrow;
//计算 θ 角(最简单的一种情况在下面图示中已经展示,关键在于 atan2 函数,详情见下面)
double angle = atan2((double)(pStart.y - pEnd.y), (double)(pStart.x - pEnd.x));
line(img, pStart, pEnd, color, thickness, lineType);
//计算箭角边的另一端的端点位置(上面的还是下面的要看箭头的指向,也就是pStart和pEnd的位置)
arrow.x = pEnd.x len * cos(angle PI * alpha / 180);
arrow.y = pEnd.y len * sin(angle PI * alpha / 180);
line(img, pEnd, arrow, color, thickness, lineType);
arrow.x = pEnd.x len * cos(angle - PI * alpha / 180);
arrow.y = pEnd.y len * sin(angle - PI * alpha / 180);
line(img, pEnd, arrow, color, thickness, lineType);
}
相对于OpenCV这个绘制方法更佳,可以设置箭头的角度,OpenCV绘制的箭头角度看起来都是45°有些呆板,调用实例:
代码语言:javascript复制//自定义函数绘制
drawArrow(img, Point(10, 30), Point(200, 30), 30, 30, Scalar(0, 255, 0), 2, 8);
drawArrow(img, Point(10, 100), Point(200, 100), 30, 50, Scalar(255, 0, 0), 2, 8);
drawArrow(img, Point(10, 170), Point(200, 170), 30, 60, Scalar(255, 0, 255), 2, 8);
绘制效果(个人比较喜欢角度为30°的箭头,看起来更美观):