我在OpenCV
中使用Python
制作程序将图片裁剪成方块。
它绘制一个正方形以显示所选区域,因此我必须在绘制新正方形之前用图像清除屏幕,但除非我再次读取图像,否则代码不会清除屏幕
# 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)
# 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)
如何制作,以便每次要清除屏幕时都不必阅读图像?
答案 0 :(得分:2)
由于@Micka和@Miki建议我将DEFAULT = cv2.imread(path,-1)
更改为DEFAULT = img.copy
,需要注意的一点是,您必须以两种方式将其工作(img = DEFAULT
不会工作,因为现在img
具有与DEFAULT
相同的指针),您必须提供默认图像的副本才能使其正常工作。
我的解决方案是(它有一些额外的代码,它不能很好地工作,但清除屏幕确实):
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()