opencv 带有点线或虚线的开放矩形

t30tvxxf  于 2023-03-19  发布在  其他
关注(0)|答案(6)|浏览(198)

我这里有一行代码使用了opencv的python绑定:

cv2.rectangle(img, (box[1], box[0]), (box[3], box[2]), (255,0,0), 4)

这将在图像img上绘制一个厚度为4的红色矩形。
但是有没有办法让矩形的线条风格化呢?不用太多,点线或者虚线就行了。

u0sqgete

u0sqgete1#

import cv2
import numpy as np
def drawline(img,pt1,pt2,color,thickness=1,style='dotted',gap=20):
    dist =((pt1[0]-pt2[0])**2+(pt1[1]-pt2[1])**2)**.5
    pts= []
    for i in  np.arange(0,dist,gap):
        r=i/dist
        x=int((pt1[0]*(1-r)+pt2[0]*r)+.5)
        y=int((pt1[1]*(1-r)+pt2[1]*r)+.5)
        p = (x,y)
        pts.append(p)

    if style=='dotted':
        for p in pts:
            cv2.circle(img,p,thickness,color,-1)
    else:
        s=pts[0]
        e=pts[0]
        i=0
        for p in pts:
            s=e
            e=p
            if i%2==1:
                cv2.line(img,s,e,color,thickness)
            i+=1

def drawpoly(img,pts,color,thickness=1,style='dotted',):
    s=pts[0]
    e=pts[0]
    pts.append(pts.pop(0))
    for p in pts:
        s=e
        e=p
        drawline(img,s,e,color,thickness,style)

def drawrect(img,pt1,pt2,color,thickness=1,style='dotted'):
    pts = [pt1,(pt2[0],pt1[1]),pt2,(pt1[0],pt2[1])] 
    drawpoly(img,pts,color,thickness,style)

im = np.zeros((800,800,3),dtype='uint8')
s=(234,222)
e=(500,700)
drawrect(im,s,e,(0,255,255),1,'dotted')

cv2.imshow('im',im)
cv2.waitKey()
qnakjoqk

qnakjoqk2#

OpenCV(目前)不支持除粗细和抗锯齿之外的线属性。

qmelpv7a

qmelpv7a3#

  • openCV是一个开源库,因此您可以找到绘图的源代码并对其进行轻微修改
  • 您可以使用LineIterator并在几行代码中获得任何想要的样式
void lineDot(OutputArray img, const Point& pt1, const Point& pt2, const Scalar& color, const vector<bool>& pattern){
    LineIterator it(img.getMat(), pt1, pt2, LINE_8); // LINE_AA is not supported here
    for(auto i=0; i<it.count; i++, it++){
        if(pattern[i%pattern.size()]){ // use any pattern of any length, dotted is {0,0,1}, dashed is {0,0,0,1,1,1} etc
            (*it)[0] = color.val[0];
            (*it)[1] = color.val[1];
            (*it)[2] = color.val[2];
        }
    }
}
xmjla07d

xmjla07d4#

正如Adi Shavit和其他人所说的那样,OpenCV目前没有一个用于绘制虚线的内置方法。
不过,有一种变通方法可以用来使用cv2.line()函数绘制虚线。一种方法是绘制带有间隙的短线段,以给予虚线的外观。下面是演示此技术的示例代码片段:

import cv2

# Create a black image
img = np.zeros((512, 512, 3), np.uint8)

# Draw a dashed line
start_point = (100, 100)
end_point = (400, 100)
color = (0, 255, 0)
thickness = 2

# Define the length of the line segments and gaps
segment_length = 10
gap_length = 5

# Calculate the length and direction of the line
dx = end_point[0] - start_point[0]
dy = end_point[1] - start_point[1]
line_length = np.sqrt(dx*dx + dy*dy)
x_unit = dx / line_length
y_unit = dy / line_length

# Draw the line segments
current_point = start_point
while line_length >= segment_length:
    end_point = (int(current_point[0] + segment_length*x_unit), int(current_point[1] + segment_length*y_unit))
    cv2.line(img, current_point, end_point, color, thickness)
    current_point = (int(end_point[0] + gap_length*x_unit), int(end_point[1] + gap_length*y_unit))
    line_length -= segment_length + gap_length

# Display the image
cv2.imshow('Dashed Line', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

在本例中,从点在黑色图像上绘制绿色虚线(100,100)到点(400,100),厚度为2个像素。segment_length和gap_length变量分别控制线段和间隙的长度。代码计算直线的长度和方向,然后迭代地绘制短线段,在它们之间留有间隙,直到绘制完整条线。可以根据需要调整此方法以生成不同的虚线样式和长度。
另一种方法是使用其他库,如PIL或Pillow,例如:

from PIL import Image, ImageDraw

# Create a black image
img = Image.new('RGB', (512, 512), (0, 0, 0))

# Draw a dashed line
draw = ImageDraw.Draw(img)
start_point = (100, 100)
end_point = (400, 100)
color = (0, 255, 0)
dash_length = 10
gap_length = 5
dash = [dash_length, gap_length]
draw.line((start_point, end_point), fill=color, width=2, joint='curve', dash=dash)

# Display the image
img.show()
ct2axkht

ct2axkht5#

下面是在Python/OpenCV中绘制虚线的一种方法。
在黑色上画一个白色线条的矩形作为蒙版,然后在蒙版上画一个黑色线条(水平和垂直线条)的网格,在白色线条中放置间隙。线条的粗细将控制间隙。然后使用蒙版在图像上白色线条的地方画黑色
输入:

import cv2
import numpy as np

# read the image
img = cv2.imread('lena.jpg')

# draw white lines on black as mask
mask = np.zeros_like(img)
cv2.rectangle(mask, (50,50), (200,200), (255,255,255), 4)

# draw grid of black lines on white
grid = np.full_like(img, (255,255,255))
dx, dy = 23, 23    # spacing cannot be evenly divisible with dimensions of rectangle
grid[:,::dx,:] = [0,0,0]
grid[::dy,:,:] = [0,0,0]

# thicken grid lines
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
grid2 = cv2.morphologyEx(grid, cv2.MORPH_ERODE, kernel)

# multiply grid with mask
mask2 = cv2.multiply(mask, grid2)
mask2 = cv2.cvtColor(mask2, cv2.COLOR_BGR2GRAY)

# use mask to draw blue dashed rectangle on image
result = img.copy()
result[mask2==255] = [255,0,0]

# save results
cv2.imwrite('lena_mask.jpg', mask)
cv2.imwrite('lena_grid.jpg', grid)
cv2.imwrite('lena_grid2.jpg', grid2)
cv2.imwrite('lena_mask2.jpg', mask2)
cv2.imwrite('lena_dashed_lines.jpg', result)

# show results
cv2.imshow('mask', mask)
cv2.imshow('grid', grid)
cv2.imshow('grid2', grid2)
cv2.imshow('mask2', mask2)
cv2.imshow('result', result)
cv2.waitKey(0)

矩形蒙版:

黑色网格:

网格加厚:

虚线掩码:

结果:

sf6xfgos

sf6xfgos6#

试试这样的方法:

cv::Point P1, P2;

P1.y = 50;
P2.y = 50;

int dot_gap = 50;
int dot_width = 50;

for( int i=0 ; i < in_img.cols; (i = i+d_width) ) {

    P1.x = i;
    P2.x = i + dot_width;
    cv::line(in_img, P1, P2, cv::Scalar(0, 255, 255), 2, cv::LINE_8);
}

相关问题