指定大于1的线条粗细时,cv2.line()绘制的线宽比指定的宽。指定厚度1,2,3,4,5,6分别产生1,3,5,5,7,7的线宽。我尝试使用不同的lineType值(4,8,16)和子像素点位置与shift参数,但不影响线宽。我做错了吗?
例如:
import numpy as np
import cv2
a = np.zeros((10,10), dtype=np.uint8)
cv2.line(a, (0,4), (9,4), 1, 2)
print(a)
产生
[[0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0]
[1 1 1 1 1 1 1 1 1 1]
[1 1 1 1 1 1 1 1 1 1]
[1 1 1 1 1 1 1 1 1 1]
[0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0]]
答案 0 :(得分:3)
你的问题很简单,答案也很简单:不,你没有做错任何事。在OpenCV中实现线条图似乎是非常基础的。
我尝试了几个线宽,还有小数的开始和结束位置。线宽参数不起作用。简单的Brezenham线(整数像素位置的单像素线)很好,但较粗的线条不好。
请参阅此测试代码:
import numpy as np
import cv2
a = np.zeros((200,200),dtype=np.uint8)
for u in np.exp(np.linspace(0,1j*2*np.pi,25)):
cv2.line(a, (100, 100), (int(100+100*u.real+.5), int(100+100*u.imag+.5)), 255, 2)
cv2.imwrite('lines.png', a)
你得到的是:
线条厚度在很大程度上取决于角度;对角线比水平或垂直线粗得多。而且,正如你所注意到的那样,线条的粗细无论如何都是错误的(最薄处为3)。使用反锯齿不会发生重大变化。
然而,如果这是用分数坐标完成的,厚度变化较小(但厚度仍然是错误的):
import numpy as np
import cv2
a = np.zeros((200,200),dtype=np.uint8)
for u in np.exp(np.linspace(0,1j*2*np.pi,25)):
cv2.line(a, (1600, 1600), (int(1600+1600*u.real+.5), int(1600+1600*u.imag+.5)), 255, 2, shift=4)
cv2.imwrite('lines_shift.png', a)
此外,问题似乎随着粗线消失(厚度设置为5,实际厚度为7,没有分数坐标)。这表明旋转相关误差是加性的:
然后让我们尝试绘制宽度为10,11和12且具有不同灰度的重叠文件:
import numpy as np
import cv2
a = np.zeros((200,200),dtype=np.uint8)
for u in np.exp(np.linspace(0,1j*2*np.pi,25)):
cv2.line(a, (100, 100), (int(100+100*u.real+.5), int(100+100*u.imag+.5)), 255, 12)
cv2.line(a, (100, 100), (int(100+100*u.real+.5), int(100+100*u.imag+.5)), 128, 11)
cv2.line(a, (100, 100), (int(100+100*u.real+.5), int(100+100*u.imag+.5)), 64, 10)
cv2.imwrite('lines_variation.png', a)
原则上应该看到三种颜色,但实际上只有两种颜色可见。这意味着宽度为11和12的线条以相同的宽度绘制(13)。任何具有小数坐标的技巧都会产生相同的结果。
摘要:只有奇数行宽可用。如果不使用分数(移位)坐标,则窄线具有较大的相对宽度误差。如果需要更多控制,请以更高的分辨率绘制更粗的线,然后进行下采样。 (笨拙,我知道。)
上述测试已在OpenCV 2.4.9版本中进行。