怎么画重复的斜线
How to draw repeated slanted lines
我需要使用 opencv-python 以编程方式绘制这样的斜线,并且它必须在倾斜角度和线之间的距离方面相似:
如果使用 OpenCV cv.line()
我需要为函数提供线的起点和终点。
按照 this Whosebug 接受的答案,我想我就能知道这两点,但首先我需要计算线方程本身。
所以我所做的是首先我使用 ai 中的测量工具计算线的倾斜角度(实际图像由平面设计师作为 ai(adobe illustrator)文件给出),我得到 67deg 和我解决了线的梯度。但问题是我不知道如何在行之间获得水平 spacing/distance 。我需要它,所以我可以提供 start.X。我用了illustrator,试着测量线之间的距离,但是如何将它映射到opencv坐标?
总的来说我的想法可行吗?或者有更好的方法来实现这个目标吗?
更新 1:
我设法绘制了这个实验图像:
这是代码:
def show_image_scaled(window_name,image,height,width):
cv2.namedWindow(window_name,cv2.WINDOW_NORMAL)
cv2.resizeWindow(window_name,width,height)
cv2.imshow(window_name,image)
cv2.waitKey(0)
cv2.destroyAllWindows()
def slanted_lines_background():
canvas = np.ones((200,300)) * 255
end_x = 0
start_y = 0
m = 2.35
end_x = 0
for x in range(0,canvas.shape[1],10):
start_x = x
end_y = start_y + compute_length(m,start_x,start_y,end_x)
cv2.line(canvas,(start_x,start_y),(end_x,end_y),(0,0,0),2)
show_image_scaled("Slant",canvas,200,300)
def compute_length(m,start_x,start_y,end_x=0):
c = start_y - (m * start_x)
length_square = (end_x - start_x)**2 + ((m *end_x) + c - start_y) ** 2
length = math.sqrt(length_square)
return int(length)
仍在努力填充矩形的左侧部分
此代码“着色”给定图像中的每个像素以生成您的阴影图案。不用担心数学。 大部分是正确的。我已经检查了细线和宽线的边缘情况。采样并不完全正确,但无论如何没人会注意到,因为缺陷只占像素的一小部分。而且我使用了 numba 来让它变得更快。
import numpy as np
from numba import njit, prange
@njit(parallel=True)
def hatch(im, angle=45, stride=10, dc=None):
stride = float(stride)
if dc is None:
dc = stride * 0.5
assert 0 <= dc <= stride
stride2 = stride / 2
dc2 = dc / 2
angle = angle / 180 * np.pi
c = np.cos(angle)
s = np.sin(angle)
(height, width) = im.shape[:2]
for y in prange(height):
for x in range(width):
# distance to origin along normal
dist_origin = c*x - s*y
# distance to center of nearest line
dist_center = stride2 - abs((dist_origin % stride) - stride2)
# distance to edge of nearest line
dist_edge = dist_center - dc2
# shade pixel, with antialiasing
# use edge-0.5 to edge+0.5 as "gradient" <=> 1-sized pixel straddles edge
# for thick/thin lines, needs hairline handling
# thin line -> gradient hits far edge of line / pixel may span both edges of line
# thick line -> gradient hits edge of adjacent line / pixel may span adjacent line
if dist_edge > 0.5: # background
val = 0
else: # pixel starts covering line
val = 0.5 - dist_edge
if dc < 1: # thin line, clipped to line width
val = min(val, dc)
elif stride - dc < 1: # thick line, little background
val = max(val, 1 - (stride - dc))
im[y,x] = val
canvas = np.zeros((128, 512), 'f4')
hatch(canvas, angle=-23, stride=5, dc=2.5)
# mind the gamma mapping before imshow
我需要使用 opencv-python 以编程方式绘制这样的斜线,并且它必须在倾斜角度和线之间的距离方面相似:
如果使用 OpenCV cv.line()
我需要为函数提供线的起点和终点。
按照 this Whosebug 接受的答案,我想我就能知道这两点,但首先我需要计算线方程本身。
所以我所做的是首先我使用 ai 中的测量工具计算线的倾斜角度(实际图像由平面设计师作为 ai(adobe illustrator)文件给出),我得到 67deg 和我解决了线的梯度。但问题是我不知道如何在行之间获得水平 spacing/distance 。我需要它,所以我可以提供 start.X。我用了illustrator,试着测量线之间的距离,但是如何将它映射到opencv坐标?
总的来说我的想法可行吗?或者有更好的方法来实现这个目标吗?
更新 1:
我设法绘制了这个实验图像:
这是代码:
def show_image_scaled(window_name,image,height,width):
cv2.namedWindow(window_name,cv2.WINDOW_NORMAL)
cv2.resizeWindow(window_name,width,height)
cv2.imshow(window_name,image)
cv2.waitKey(0)
cv2.destroyAllWindows()
def slanted_lines_background():
canvas = np.ones((200,300)) * 255
end_x = 0
start_y = 0
m = 2.35
end_x = 0
for x in range(0,canvas.shape[1],10):
start_x = x
end_y = start_y + compute_length(m,start_x,start_y,end_x)
cv2.line(canvas,(start_x,start_y),(end_x,end_y),(0,0,0),2)
show_image_scaled("Slant",canvas,200,300)
def compute_length(m,start_x,start_y,end_x=0):
c = start_y - (m * start_x)
length_square = (end_x - start_x)**2 + ((m *end_x) + c - start_y) ** 2
length = math.sqrt(length_square)
return int(length)
仍在努力填充矩形的左侧部分
此代码“着色”给定图像中的每个像素以生成您的阴影图案。不用担心数学。 大部分是正确的。我已经检查了细线和宽线的边缘情况。采样并不完全正确,但无论如何没人会注意到,因为缺陷只占像素的一小部分。而且我使用了 numba 来让它变得更快。
import numpy as np
from numba import njit, prange
@njit(parallel=True)
def hatch(im, angle=45, stride=10, dc=None):
stride = float(stride)
if dc is None:
dc = stride * 0.5
assert 0 <= dc <= stride
stride2 = stride / 2
dc2 = dc / 2
angle = angle / 180 * np.pi
c = np.cos(angle)
s = np.sin(angle)
(height, width) = im.shape[:2]
for y in prange(height):
for x in range(width):
# distance to origin along normal
dist_origin = c*x - s*y
# distance to center of nearest line
dist_center = stride2 - abs((dist_origin % stride) - stride2)
# distance to edge of nearest line
dist_edge = dist_center - dc2
# shade pixel, with antialiasing
# use edge-0.5 to edge+0.5 as "gradient" <=> 1-sized pixel straddles edge
# for thick/thin lines, needs hairline handling
# thin line -> gradient hits far edge of line / pixel may span both edges of line
# thick line -> gradient hits edge of adjacent line / pixel may span adjacent line
if dist_edge > 0.5: # background
val = 0
else: # pixel starts covering line
val = 0.5 - dist_edge
if dc < 1: # thin line, clipped to line width
val = min(val, dc)
elif stride - dc < 1: # thick line, little background
val = max(val, 1 - (stride - dc))
im[y,x] = val
canvas = np.zeros((128, 512), 'f4')
hatch(canvas, angle=-23, stride=5, dc=2.5)
# mind the gamma mapping before imshow