Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python OpenCV-绘制一个适当的大小调整矩形_Python_Opencv - Fatal编程技术网

Python OpenCV-绘制一个适当的大小调整矩形

Python OpenCV-绘制一个适当的大小调整矩形,python,opencv,Python,Opencv,我一直在尝试这个代码,我有一个图像,然后我可以画一个矩形的基础上,当我点击并拖动鼠标。在鼠标按下事件中,我将x和y坐标标记为矩形的初始角点。在鼠标移动时,我从保存的旧x和y坐标绘制矩形,到鼠标所在的新坐标。最后,在鼠标上,我画了一个矩形作为最终的 以下是我正在使用的代码: import cv2 import numpy as np drawing = False # True if mouse is pressed mode = True # if True, draw rectangle.

我一直在尝试这个代码,我有一个图像,然后我可以画一个矩形的基础上,当我点击并拖动鼠标。在鼠标按下事件中,我将x和y坐标标记为矩形的初始角点。在鼠标移动时,我从保存的旧x和y坐标绘制矩形,到鼠标所在的新坐标。最后,在鼠标上,我画了一个矩形作为最终的

以下是我正在使用的代码:

import cv2
import numpy as np

drawing = False # True if mouse is pressed
mode = True # if True, draw rectangle. Press 'm' to toggle to curve
ix, iy = -1, -1

# mouse callback function
def draw_circle(event, x, y, flags, param):
    global ix, iy, drawing, mode, overlay, output, alpha
    overlay = img.copy()
    output = img.copy()
    alpha = 0.5

    if event == cv2.EVENT_LBUTTONDOWN:
        drawing = True
        ix, iy = x, y

    elif event == cv2.EVENT_MOUSEMOVE:
        if drawing == True:
            if mode == True:
                cv2.rectangle(overlay, (ix, iy), (x, y), (0, 255, 0), -1)
                cv2.addWeighted(overlay, alpha, output, 1 - alpha, 0, img)
                cv2.imshow('image', img)
            else:
                cv2.circle(overlay, (x,y),5,(0,0,255),-1)

    elif event == cv2.EVENT_LBUTTONUP:
        drawing = False
        if mode == True:
            cv2.rectangle(overlay, (ix, iy), (x, y), (0, 255, 0), -1)
            cv2.addWeighted(overlay, alpha, output, 1 - alpha, 0, img)

        else:
            cv2.circle(overlay, (x, y), 5, (0, 0, 255), -1)


##img = np.zeros((512, 512, 3), np.uint8)
# Get our image
img = cv2.imread("bed_cv.jpg", 1)

#make cv2 windows, set mouse callback
cv2.namedWindow('image')
cv2.setMouseCallback('image', draw_circle)

while(1):
    cv2.imshow('image', img)

    # This is where we get the keyboard input
    # Then check if it's "m" (if so, toggle the drawing mode)
    k = cv2.waitKey(1) & 0xFF
    if k == ord('m'):
        mode = not mode
    elif k == 27:
        break

cv2.destroyAllWindows()
当然这里的问题是,如果我从中心开始,然后拖动到右下角,然后再回到左下角,第一个矩形不会被删除。当然,这是因为我实际上是在图像上绘制矩形,而不是清除它,所以在鼠标移动事件中创建的每个矩形都会被绘制

当你在桌面上画一个盒子时,我想要达到的效果是相似的,你可以在没有矩形的情况下改变方向


我的问题是,是否可以直观地绘制一个矩形,但不将其写入图像?

这个想法是制作一个图像副本(在本例中为img2),然后在鼠标移动事件中将其用作覆盖的输出。然后在button up事件中使用原始图像(在本例中为img):

import cv2
import numpy as np

drawing = False # True if mouse is pressed
mode = True # if True, draw rectangle. Press 'm' to toggle to curve
ix, iy = -1, -1

# mouse callback function
def draw_circle(event, x, y, flags, param):
    global ix, iy, drawing, mode, overlay, output, alpha
    overlay = img.copy()
    output = img.copy()
    alpha = 0.5

    if event == cv2.EVENT_LBUTTONDOWN:
        drawing = True
        ix, iy = x, y

    elif event == cv2.EVENT_MOUSEMOVE:
        if drawing == True:
            if mode == True:
                cv2.rectangle(overlay, (ix, iy), (x, y), (0, 255, 0), -1)
                cv2.addWeighted(overlay, alpha, output, 1 - alpha, 0, img2)
                cv2.imshow('image', img2)
            else:
                cv2.circle(overlay, (x,y),5,(0,0,255),-1)

    elif event == cv2.EVENT_LBUTTONUP:
        drawing = False
        if mode == True:
            cv2.rectangle(overlay, (ix, iy), (x, y), (0, 255, 0), -1)
            cv2.addWeighted(overlay, alpha, output, 1 - alpha, 0, img)

        else:
            cv2.circle(overlay, (x, y), 5, (0, 0, 255), -1)


##img = np.zeros((512, 512, 3), np.uint8)
# Get our image
img = cv2.imread("bed_cv.jpg", 1)
img2 = img.copy()

#make cv2 windows, set mouse callback
cv2.namedWindow('image')
cv2.setMouseCallback('image', draw_circle)

while(1):
    cv2.imshow('image', img2)

    # This is where we get the keyboard input
    # Then check if it's "m" (if so, toggle the drawing mode)
    k = cv2.waitKey(1) & 0xFF
    if k == ord('m'):
        mode = not mode
    elif k == 27:
        break

cv2.destroyAllWindows()

看见我通常保留一份原始图像的副本,一份已经绘制了所有矩形的图像(图层副本)和一份图层副本,其中我绘制了我现在正在创建的“部分矩形”(工作副本),并且只在工作副本上绘制矩形。在鼠标上,我将工作副本保存为新层copy@Miki谢谢你的提示!我设法做到了。我很快就会发布代码。另一个选择是使用一些可逆操作。如果它是一个大纲,那么您可以使用XOR操作来绘制它(尽管使用OpenCV,您可能需要使用行迭代器来完成)。对于填充矩形,可以反转ROI。当然,这看起来不一样,但这是一种避免保留图像副本的方法。