如何在Python中删除图像上绘制的线条?
我已经用python(使用opencv包)在现有图像的顶部使用鼠标单击(每次鼠标单击都是一个连接点)绘制了几条线,您可以将其视为允许用户在图像上选择某些内容 如何允许用户通过单击鼠标右键删除图像上的最后一点?这是我当前的代码:如何在Python中删除图像上绘制的线条?,python,opencv,Python,Opencv,我已经用python(使用opencv包)在现有图像的顶部使用鼠标单击(每次鼠标单击都是一个连接点)绘制了几条线,您可以将其视为允许用户在图像上选择某些内容 如何允许用户通过单击鼠标右键删除图像上的最后一点?这是我当前的代码: import numpy import cv2 points = [] def draw_point(event, x, y, flags, param): if event == cv2.EVENT_LBUTTONDOWN: cv2.circ
import numpy
import cv2
points = []
def draw_point(event, x, y, flags, param):
if event == cv2.EVENT_LBUTTONDOWN:
cv2.circle(image, (x,y), 1, (255,0,0),-1)
points.append((x,y))
pts = numpy.array(points, numpy.int32)
cv2.polylines(image,[pts],False,(255,0,0))
elif event == cv2.EVENT_RBUTTONDOWN:
# HOW TO DELETE?
del points[-1]
pts = numpy.array(points, numpy.int32)
cv2.polylines(image,[pts],True,(255,0,0))
image = cv2.imread('simple_tattoo.jpg', cv2.IMREAD_UNCHANGED)
cv2.namedWindow('example', cv2.WINDOW_AUTOSIZE)
cv2.setMouseCallback('example', draw_point)
while(1):
cv2.imshow('example',image)
if cv2.waitKey(20) & 0xFF == 27:
break
cv2.destroyAllWindows()
print (points)
是否有更简单的方法在图像上画线(任何东西)?因此,如果其他人对此有问题,保持一个while循环以刷新img也很重要-没有它就无法工作
def click_event(event, x, y, flags, param):
global img
if event == cv2.EVENT_LBUTTONDOWN:
print(x,y)
cv2.circle(img, (x, y), 10, (0, 0, 255), -1)
cv2.imshow('image', img)
if event == cv2.EVENT_RBUTTONDBLCLK:
img = cv2.imread(img_path)
print("cleaned")
cv2.imshow('image', img)
img_path = "my_img.jpg"
global img
img = cv2.imread(img_path)
while(1):
cv2.setMouseCallback('image', click_event)
cv2.imshow('image', img)
k=cv2.waitKey(1) & 0xFF
if k==27: #Escape KEY
break
cv2.imshow('image', img)
cv2.destroyAllWindows()
在每次操作后保留图像的缓存,然后只要在需要时恢复到缓存状态即可。像撤销
def draw_circle(event,x,y,flags,param):
global img
global cache
if event == cv2.EVENT_LBUTTONDBLCLK:
cache = copy.deepcopy(img)
cv2.circle(img,(x,y),40,(255,0,0),5)
if event == cv2.EVENT_MBUTTONDBLCLK:
img = copy.deepcopy(cache)
cv2.imshow('image', img)
img_path = "my_img.jpg"
global img
global cache
img = cv2.imread(img_path)
cache = copy.deepcopy(img)
cv2.namedWindow('image')
while(1):
cv2.setMouseCallback('image', draw_circle)
cv2.imshow('image', img)
k=cv2.waitKey(1) & 0xFF
if k==27: #Escape KEY
break
cv2.imshow('image', img)
cv2.destroyAllWindows()
一旦在原始图像上画了线或其他任何东西,就无法重建原始图像。你应该有两张图片:1。原始图像。2.你画线的原始图像的副本。哇,谢谢你,我一点都没想到。它帮助我完成了这项工作!OP不希望删除完整的图像,只是重点。@PradeepSingh很抱歉听到它不适合你。现在刚刚测试过,它对我有效。。(你有没有注意到它是一个双击的R按钮?它也不会擦除整个图像,而是它上面的所有点..你能更具体地描述一下你的问题,这样我就可以尝试帮助你吗?这就是它将抛出的东西…OpenCV(4.2.0)/io/OpenCV/modules/highgui/src/window_QT.cpp:714:错误:(-27:空指针)函数“cvSetMouseCallback”中的空窗口处理程序…。这是因为您没有在cv2.setMouseCallback(…)行之前指定cv2.namedWindow('image')。我在cv2.setMouseCallback('image'行之前指定了cv2.namedWindow('image'),单击事件)..它没有出错。但正如你所说,它仍然是一个逻辑错误。它清除了我和提问者都不想要的所有要点。虽然,我已经编写了自己的脚本来解决所有这些问题。谢谢…我想在任何情况下提前命名windows都是很好的做法,但对我来说,这在没有它的情况下是可行的。这可能与O有关S和CV版本..很高兴听到你解决了删除所有点的问题-也许你想与我们分享你的脚本,作为对原始问题的更好回答:)你认为你应该解释什么是复制,什么是深度复制。。。我认为没有理由导入额外的库—img.copy()和cache.copy()工作正常。做得好