opencv线条加粗
时间: 2024-12-30 08:32:40 浏览: 7
### 使用 OpenCV 实现线条加粗功能
为了实现线条的加粗并确保端点为直角边而非圆角,可以采用自定义方法来替代默认的 `cv2.line()` 函数。这种方法不仅能够控制线条宽度,还能精确调整线条两端形状。
#### 自定义绘制带直角边的粗直线函数
下面是一个 Python 代码示例,展示了如何创建一个带有直角边的粗直线:
```python
import cv2
import numpy as np
def draw_thick_line(img, pt1, pt2, color, thickness, is_filled=False):
"""
绘制具有直角边缘的厚实线段
参数:
img (numpy.ndarray): 输入图像数组
pt1 (tuple): 起始点坐标(x,y)
pt2 (tuple): 结束点坐标(x,y)
color (tuple): BGR颜色值
thickness (int): 线条厚度
is_filled (bool): 是否填充,默认False表示仅描边
"""
# 计算方向向量
dx = pt2[0] - pt1[0]
dy = pt2[1] - pt1[1]
# 如果是垂直或水平线,则简单扩展边界矩形区域即可
if abs(dx) <= 1 or abs(dy) <= 1:
top_left = (
min(pt1[0], pt2[0]) - int(thickness / 2),
min(pt1[1], pt2[1]) - int(thickness / 2))
bottom_right = (
max(pt1[0], pt2[0]) + int(thickness / 2),
max(pt1[1], pt2[1]) + int(thickness / 2))
rect_points = [
top_left,
(bottom_right[0], top_left[1]),
bottom_right,
(top_left[0], bottom_right[1])
]
pts = np.array([rect_points], dtype=np.int32)
if not is_filled:
cv2.polylines(img, [pts], True, color=color, thickness=thickness//2)
else:
cv2.fillPoly(img, [pts], color=color)
else:
angle = np.arctan2(-dy, dx)*180/np.pi
# 创建旋转矩阵用于变换角度
M = cv2.getRotationMatrix2D(((pt1[0]+pt2[0])/2,(pt1[1]+pt2[1])/2),angle,-1)
h,w,_ = img.shape
rotated_img = cv2.warpAffine(np.zeros_like(img),M,(w,h))
thickened_rect_pts = []
half_thickness = thickness // 2
for offset in [-half_thickness,+half_thickness]:
new_pt1 = tuple(map(sum, zip(pt1, (-offset*np.sin(angle*np.pi/180),-offset*np.cos(angle*np.pi/180)))))
new_pt2 = tuple(map(sum, zip(pt2, (+offset*np.sin(angle*np.pi/180),+offset*np.cos(angle*np.pi/180)))))
thickened_rect_pts.append(new_pt1)
thickened_rect_pts.append(new_pt2)
poly_pts = np.array([thickened_rect_pts],dtype=int)
if not is_filled:
cv2.polylines(rotated_img,[poly_pts],True,color=color,thickness=max(1,int(thickness*0.7)))
else:
cv2.fillPoly(rotated_img,poly_pts,color=color)
inv_M = cv2.invertAffineTransform(M)
result = cv2.warpAffine(rotated_img,inv_M,(w,h)).astype(bool).astype(int)*color+(~rotated_img.astype(bool)).astype(int)*img
return result
# 测试用法
image = np.ones((500, 500, 3), dtype="uint8") * 255
start_point = (100, 100)
end_point = (400, 400)
draw_color = (0, 0, 255)
line_width = 20
result_image = draw_thick_line(image.copy(), start_point, end_point, draw_color, line_width)
cv2.imshow('Thick Line with Square Ends', result_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
此代码片段实现了对任意给定两点之间连线的操作,并允许用户指定线条的颜色、宽度以及是否要填充整个图形[^1]。
对于更简单的场景下(比如只需要延长现有线条),也可以考虑先获取原始线条参数再基于这些信息构建新的延长后的线条对象[^2]。
此外,在某些情况下可能还需要结合其他预处理操作如高斯模糊等来优化最终视觉效果[^3]。
阅读全文