Opencv Clear Screen

Problem

I'm using OpenCV in Python make a program to crop images into squares.

It draws a square to show the selected area so I have to clear the screen with the image before drawing a new square, but unless I read the image again the code doesn't clear the screen.

This code doesn't work:

# Get Image
img = cv2.imread(path,-1)
DEFAULT = cv2.imread(path,-1)

# Draw Function
def draw(event,x,y,flags,param):
    if event == cv2.EVENT_LBUTTONDOWN:
        drawing = True
        # Set initial points
        ix,iy = x,y

    elif event == cv2.EVENT_MOUSEMOVE:
        if drawing == True:
            # Clear Screen
            img = DEFAULT

            # Draw Square
            if (abs(ix - x) < abs(iy -y)):
                cv2.rectangle(img,(ix,iy),(y,y),(0,255,0),1)
            else:
                cv2.rectangle(img,(ix,iy),(x,x),(0,255,0),1)

    elif event == cv2.EVENT_LBUTTONUP:
        drawing = False
        crop(x,y)

This one does work:

# Get Image
img = cv2.imread(path,-1)

# Draw Function
def draw(event,x,y,flags,param):
    if event == cv2.EVENT_LBUTTONDOWN:
        drawing = True
        # Set initial points
        ix,iy = x,y

    elif event == cv2.EVENT_MOUSEMOVE:
        if drawing == True:
            # Clear Screen
            img = cv2.imread(path,-1)

            # Draw Square
            if (abs(ix - x) < abs(iy -y)):
                cv2.rectangle(img,(ix,iy),(y,y),(0,255,0),1)
            else:
                cv2.rectangle(img,(ix,iy),(x,x),(0,255,0),1)

    elif event == cv2.EVENT_LBUTTONUP:
        drawing = False
        crop(x,y)

Question

How do I make it so I don't have to read the image each time I want to clear the screen?

11

1 Answer

As @Micka and @Miki suggested I changed DEFAULT = cv2.imread(path,-1) to DEFAULT = img.copy, one thing to note is that you have to do it both ways for it to work (img = DEFAULT won't work because now img has the same pointers as DEFAULT), you have to give a copy of your default image for it to work.

My solution was (it has some extra code and it doesn't work perfectly, but the clearing of the screen does):

import numpy as np
import cv2, os, sys, getopt

# Global Variables
helpMessage = 'Usage:\n\tcrop.py <command> [argument]\n\nCommands:\n\t-h --help\t\tDisplay this help message\n\t-i --image [path]\tInput image\n\t-f --folder [path]\tImage Folder\n\t-r --regex [regex]\tNaming of output files [WIP]\n\t-s --save [path]\tPath to Save'

# Arguments
pathIMG = ''
pathDIR = ''
pathSAV = ''
regex = ''

# Graphical
drawing = False # true if mouse is pressed
cropped = False
ix,iy = -1,-1

# MISC
img_index = 0

# Mouse callback function
def draw(event,x,y,flags,param):
    global ix, iy, drawing, img, DEFAULT, cropped

    cropped = False

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

    elif event == cv2.EVENT_MOUSEMOVE:
        if drawing == True:
            img = DEFAULT.copy()
            cv2.imshow(pathIMG,img)
            if (abs(ix - x) < abs(iy -y)):
                cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),1)
            else:
                cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),1)

    elif event == cv2.EVENT_LBUTTONUP:
        drawing = False
        crop(ix,iy,x,y)

# Get Arguments
def getArgvs(argv):
    try:
        opts, args = getopt.getopt(argv,"hi:f:r:s:",["help","image=","folder=","regex=","save="])
    except getopt.GetoptError:
        print(helpMessage)
        sys.exit(2)

    for opt, arg in opts:
        if opt in ('-h', "--help"):
            print(helpMessage)
            sys.exit()
        elif opt in ("-i", "--image"):
            global pathIMG
            pathIMG = arg
            #print("img: " + arg)
        elif opt in ("-f", "--folder"):
            global pathDIR
            pathDIR = arg
            #print("dir: " + arg)
        elif opt in ("-r","--regex"):
            global regex
            regex = arg
            #print("regex: " + arg)
        elif opt in ("-s","--save"):
            global pathSAV
            pathSAV = arg

# Crop Image
def crop(ix,iy,x,y):
    global img, DEFAULT, cropped

    img = DEFAULT.copy()
    cv2.imshow(pathIMG,img)

    if (abs(ix - x) < abs(iy -y)):
        img = img[iy:y, ix:x]
    else:
        img = img[iy:y, ix:x]

# Save image
def save(crop_img):
    # Set name
    name = pathSAV + "img" + str(img_index) + ".png"

    # Resize
    dst = cv2.resize(crop_img, (32,32))

    # Save
    cv2.imwrite(name,dst)
    print("Saved image sucsessfully")

# Main Loop
def loop():
    global img

    cv2.namedWindow(pathIMG)
    cv2.setMouseCallback(pathIMG,draw)

    while (1):
        cv2.imshow(pathIMG,img)
        k = cv2.waitKey(1) & 0xFF
        if (k == 27):
            print("Cancelled Crop")
            break
        elif (k == ord('s')):# and cropped):
            print("Image Saved")

            save(img)
            break

    print("Done!")
    cv2.destroyAllWindows()

# Iterate through images in path
def getIMG(path):
    global img, DEFAULT
    directory = os.fsencode(path)
    for filename in os.listdir(directory):
        # Get Image Path
        pathIMG = path + filename.decode("utf-8")
        print(pathIMG)

        # Read Image
        img = cv2.imread(pathIMG,-1)
        DEFAULT = img.copy()

        # Draw image
        loop()

    return 0

# Main Function
def main():
    getArgvs(sys.argv[1:])
    global img, DEFAULT

    if (pathDIR != ''):
        # Print Path
        print("dir: " + pathDIR)

        # Cycle through files
        getIMG(pathDIR)

    elif (pathIMG != ''):
        # Print Path
        print("img: " + pathIMG)

        # Load Image
        img = cv2.imread(pathIMG,-1)
        DEFAULT = img.copy()

        # Draw Image
        loop()

# Run Main
if __name__ == "__main__":
    main()
    cv2.destroyAllWindows()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Chloe Bennett

Chloe Bennett

Culture, Media & Entertainment Columnist

Chloe Bennett explores the intersection of pop culture, streaming entertainment, digital trends, and contemporary lifestyle. Her weekly commentary reaches thousands of culture enthusiasts.

Share this article
Twitter Facebook Pinterest