首页 > 解决方案 > 使用 OpenCV 在 python 中创建橡皮擦工具

问题描述

我正在尝试使用opencv在python中的pycharm中编写一个程序。我在使用鼠标功能擦除图像时遇到问题。

我尝试仅在单击鼠标左键并且释放左键时橡皮擦停止时才使用鼠标移动功能擦除图像。但是在输出屏幕上没有任何动作

import cv2
screen="Drawing"
img=cv2.imread("12.jpg")
cv2.namedWindow(screen)

橡皮擦=假 x_start, y_start, x_end, y_end = 0, 0, 0, 0

 def draw_circle(event,x,y,flags,param):
      if (event==cv2.EVENT_LBUTTONDOWN):
            x_start, y_start, x_end, y_end = x, y, x, y
            eraser=True
      elif (event==cv2.EVENT_MOUSEHWHEEL):
            if eraser==True:
                  x_end, y_end = x, y

      elif event == cv2.EVENT_LBUTTONUP:
            x_end, y_end = x, y
            eraser = False

   cv2.setMouseCallback(screen,draw_circle)
   while True:

    i = img.copy()
    if not eraser:
         cv2.imshow("image", img)

    elif eraser:
         cv2.circle(img, (x, y), 20, (255, 255, 255), -1)
         cv2.imshow(screen,img)

 if cv2.waitKey(1)==13:
     break

cv2.destroyAllWindows()

程序显示图像,但我无法通过单击鼠标按钮将其删除

标签: pythonnumpyopencvpycharm

解决方案


正如@api55 所述,eraser需要声明为全局变量。但是,您要“擦除”的圆的 x 和 y 坐标也是如此。您当前的代码为此使用了不正确的变量,也从不更新它们。这就是橡皮擦不起作用的原因。

通过更改代码,您还可以使用更少的变量和没有 while 循环,从而提高效率。我冒昧地重构了您的代码并实现了橡皮擦大小。

import cv2
screen="Drawing"
img=cv2.imread("12.jpg")
cv2.namedWindow(screen)
eraser=False 
radius = 20

def draw_circle(x,y):
        # 'erase' circle
        cv2.circle(img, ( x, y), radius, (255, 255, 255), -1)
        cv2.imshow(screen,img)

def handleMouseEvent(event,x,y,flags,param):
      global eraser , radius     
      if (event==cv2.EVENT_MOUSEMOVE):
              # update eraser position
            if eraser==True:
                  draw_circle(x,y)
      elif (event==cv2.EVENT_MOUSEWHEEL):
              # change eraser radius
            if flags > 0:
                radius +=   5
            else:
                    # prevent issues with < 0
                if radius > 10:
                    radius -=   5
      elif event == cv2.EVENT_LBUTTONUP:
              # stop erasing
            eraser = False
      elif (event==cv2.EVENT_LBUTTONDOWN):
              # start erasing
            eraser=True
            draw_circle(x,y)


cv2.setMouseCallback(screen,handleMouseEvent)
# show initial image
cv2.imshow(screen,img)
cv2.waitKey(0)
cv2.destroyAllWindows()

推荐阅读