web-dev-qa-db-fra.com

dessin rectangle en openCV python

J'essaie de dessiner un rectangle en utilisant la souris comme entrée avec Opencv en python. J'ai fait ce code à partir de la documentation opencv. Lorsque vous dessinez un rectangle, le problème est que vous essayez de faire glisser depuis le point de départ, le rectangle est tracé jusqu’au point final. Comme je l'ai montré dans Images.

Comment puis-je dessiner un rectangle non rempli propre? où je peux voir dessiner un rectangle réel. Comme nous le faisons dans Paint

import cv2
import numpy as np

drawing = False 
ix,iy = -1,-1

def draw_rect(event,x,y,flags,param):
global ix,iy,drawing,mode

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

Elif event == cv2.EVENT_MOUSEMOVE:
    if drawing == True:
            cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),1)


Elif event == cv2.EVENT_LBUTTONUP:
    drawing = False
    cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),1)



img = np.zeros((512,512,3), np.uint8)
cv2.namedWindow('image')
cv2.setMouseCallback('image',draw_rect)

while(1):
cv2.imshow('image',img)
k = cv2.waitKey(1) & 0xFF
if k == 27:
    break

cv2.destroyAllWindows()

 This what happening after executing above code

Quelqu'un peut-il me dire pourquoi cela se produit? Toute solution à ce sujet?

4

Lorsque vous déplacez la souris pendant event == cv2.EVENT_MOUSEMOVE, vous dessinez également le changement de code en même temps cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),1)

Essayez de suivre le morceau de code.

import cv2
import numpy as np

drawing = False # true if mouse is pressed
mode = True # if True, draw rectangle.
ix,iy = -1,-1

# mouse callback function
def draw_circle(event,x,y,flags,param):
  global ix,iy,drawing,mode

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

  Elif event == cv2.EVENT_MOUSEMOVE:
    if drawing == True:
        if mode == True:
            cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),3)
            a=x
            b=y
            if a != x | b != y:
                 cv2.rectangle(img,(ix,iy),(x,y),(0,0,0),-1)
        else:
            cv2.circle(img,(x,y),5,(0,0,255),-1)

  Elif event == cv2.EVENT_LBUTTONUP:
    drawing = False
    if mode == True:
        cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),2)

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

img = np.zeros((512,512,3), np.uint8)
cv2.namedWindow('image')
cv2.setMouseCallback('image',draw_circle)

while(1):
 cv2.imshow('image',img)
 k = cv2.waitKey(1) & 0xFF
 if k == ord('m'):
    mode = not mode
 Elif k == 27:
    break

cv2.destroyAllWindows()   

J'espère que ça résoudra votre problème. À votre santé.

Production attendue:

 Rectangle Unfilled Draw


Mettre à jour


Le morceau de code ci-dessus fonctionnera uniquement avec une image d’arrière-plan noire. Mais nous pouvons dessiner un rectangle sur n'importe quelle image pour -

Essayez de suivre le morceau de code.

# import the necessary packages
import cv2
import argparse

# now let's initialize the list of reference point
ref_point = []

def shape_selection(event, x, y, flags, param):
    # grab references to the global variables
    global ref_point, crop

    # if the left mouse button was clicked, record the starting
    # (x, y) coordinates and indicate that cropping is being performed
    if event == cv2.EVENT_LBUTTONDOWN:
        ref_point = [(x, y)]

    # check to see if the left mouse button was released
    Elif event == cv2.EVENT_LBUTTONUP:
        # record the ending (x, y) coordinates and indicate that
        # the cropping operation is finished
        ref_point.append((x, y))

        # draw a rectangle around the region of interest
        cv2.rectangle(image, ref_point[0], ref_point[1], (0, 255, 0), 2)
        cv2.imshow("image", image)


# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True, help="Path to the image")
args = vars(ap.parse_args())

# load the image, clone it, and setup the mouse callback function
image = cv2.imread(args["image"])
clone = image.copy()
cv2.namedWindow("image")
cv2.setMouseCallback("image", shape_selection)


# keep looping until the 'q' key is pressed
while True:
    # display the image and wait for a keypress
    cv2.imshow("image", image)
    key = cv2.waitKey(1) & 0xFF

    # press 'r' to reset the window
    if key == ord("r"):
        image = clone.copy()

    # if the 'c' key is pressed, break from the loop
    Elif key == ord("c"):
        break

# close all open windows
cv2.destroyAllWindows() 


Enregistrez le fichier sous le nom capture_events.py. Pour le tester, nous avons sélectionné une image de démonstration située dans le même répertoire. Maintenant, lancez le code en suivant -

python capture_events.py --image demo.jpg

Production attendue:

 enter image description here

Si une raison quelconque veut que nous sélectionnions à nouveau une partie de l'image, nous pouvons simplement appuyer sur "r" pour supprimer la mauvaise sélection et en essayer une nouvelle. 

J'espère que ça va aider plus. Cochez cette Gist , vous pouvez implémenter plus de fonctionnalités à ce sujet. À votre santé.

4
SkyNet

vous pouvez changer votre événement de souris de presse en quelque chose comme ça

Elif event == cv2.EVENT_MOUSEMOVE:
if drawing==True:
    copy = image.copy()
    cv2.rectangle(copy,(ix,iy),(x,y),(0,255,0),1)
    cv2.imshow("image", copy)

le script créera des copies de l'image avec des rectangles basés sur les x et les y actuels et affichera l'effet en temps réel

0
Lynx