前言
利用OpenCV自带的函数line画粗直线时,发现一个问题,线的两个端点是圆角边,而不是直角边。如下图:
但是,我想画直角边的粗直线,在网上找了半天,没有相关的,所以就写了一个函数,分填充,和不填充的, 可以画水平,竖直、倾斜的粗直线,只用给出起点和终点两个坐标(中间)就行,效果还不错,分享给大家。
一、实现
不说废话,直接上代码:
void DrawLine(InputOutputArray src, Point startPoint, Point endPoint, int width, cv::Scalar color, bool fillFlag)
{
vector<Point> rectPoint(4);
int tempWidth = width / 2;
int offsetX = endPoint.x - startPoint.x;
int offsetY = endPoint.y - startPoint.y;
if (offsetX == 0 && offsetY == 0)
return;
else if (offsetX == 0) {
rectPoint[0].x = GetResult(startPoint.x, tempWidth, false, src.cols());
rectPoint[0].y = startPoint.y;
rectPoint[1].x = rectPoint[0].x;
rectPoint[1].y = endPoint.y;
rectPoint[2].x = GetResult(startPoint.x, tempWidth, true, src.cols());
rectPoint[2].y = endPoint.y;
rectPoint[3].x = rectPoint[2].x;
rectPoint[3].y = startPoint.y;
}
else if (offsetY == 0) {
rectPoint[0].x = startPoint.x;
rectPoint[0].y = GetResult(startPoint.y, tempWidth, false, src.rows());
rectPoint[1].x = endPoint.x;
rectPoint[1].y = rectPoint[0].y;
rectPoint[2].x = endPoint.x;
rectPoint[2].y = GetResult(startPoint.y, tempWidth, true, src.rows());
rectPoint[3].x = startPoint.x;
rectPoint[3].y = rectPoint[2].y;
}
else {
bool negFlag1, negFlag2;
negFlag1 = offsetX < 0 ? true : false;
negFlag2 = offsetY < 0 ? true : false;
int lineLength = sqrt(pow(offsetX, 2) + pow(offsetY, 2));
double sin = abs(offsetY) * 1.0 / lineLength;
double cos = abs(offsetX) * 1.0 / lineLength;
int dX = sin * tempWidth;
int dY = cos * tempWidth;
//从起点按照顺时针的方式获取顶点的坐标
if (negFlag1 && negFlag2) {
rectPoint[0].x = GetResult(startPoint.x, dX, false, src.cols());
rectPoint[0].y = GetResult(startPoint.y, dY, true, src.rows());
rectPoint[1].x = GetResult(endPoint.x, dX, false, src.cols());
rectPoint[1].y = GetResult(endPoint.y, dY, true, src.rows());
rectPoint[2].x = GetResult(endPoint.x, dX, true, src.cols());
rectPoint[2].y = GetResult(endPoint.y, dY, false, src.rows());
rectPoint[3].x = GetResult(startPoint.x, dX, true, src.cols());
rectPoint[3].y = GetResult(startPoint.y, dY, false, src.rows());
}
else if (!negFlag1 && !negFlag2) {
rectPoint[0].x = GetResult(startPoint.x, dX, true, src.cols());
rectPoint[0].y = GetResult(startPoint.y, dY, false, src.rows());
rectPoint[1].x = GetResult(endPoint.x, dX, true, src.cols());
rectPoint[1].y = GetResult(endPoint.y, dY, false, src.rows());
rectPoint[2].x = GetResult(endPoint.x, dX, false, src.cols());
rectPoint[2].y = GetResult(endPoint.y, dY, true, src.rows());
rectPoint[3].x = GetResult(startPoint.x, dX, false, src.cols());
rectPoint[3].y = GetResult(startPoint.y, dY, true, src.rows());
}
else if (negFlag1 && !negFlag2) {
rectPoint[0].x = GetResult(startPoint.x, dX, false, src.cols());
rectPoint[0].y = GetResult(startPoint.y, dY, false, src.rows());
rectPoint[1].x = GetResult(endPoint.x, dX, false, src.cols());
rectPoint[1].y = GetResult(endPoint.y, dY, false, src.rows());
rectPoint[2].x = GetResult(endPoint.x, dX, true, src.cols());
rectPoint[2].y = GetResult(endPoint.y, dY, true, src.rows());
rectPoint[3].x = GetResult(startPoint.x, dX, true, src.cols());
rectPoint[3].y = GetResult(startPoint.y, dY, true, src.rows());
}
else {
rectPoint[0].x = GetResult(startPoint.x, dX, true, src.cols());
rectPoint[0].y = GetResult(startPoint.y, dY, true, src.rows());
rectPoint[1].x = GetResult(endPoint.x, dX, true, src.cols());
rectPoint[1].y = GetResult(endPoint.y, dY, true, src.rows());
rectPoint[2].x = GetResult(endPoint.x, dX, false, src.cols());
rectPoint[2].y = GetResult(endPoint.y, dY, false, src.rows());
rectPoint[3].x = GetResult(startPoint.x, dX, false, src.cols());
rectPoint[3].y = GetResult(startPoint.y, dY, false, src.rows());
}
}
vector<vector<Point>> contours;
contours.push_back(rectPoint);
int lineWidth = fillFlag ? -1 : 1;
drawContours(src, contours, -1, color, lineWidth);
}
int GetResult(const int & first, const int & second, bool add, const int & max, int min)
{
int result;
if (add) {
result = first + second;
return result > max ? max : result;
}
else {
result = first - second;
return result < min ? min : result;
}
}