简体   繁体   English

Python cv2 90:90 纵横比矩形裁剪图像

[英]Python cv2 90:90 aspect ratio rectangle to crop images

I'm writing a Programm to crop inmages and my problem is I want that rectangle to have a specific aspect ratio (90:90) and is it possible to make the rectangle instead of the mouse, change its size with mousewheel and confirm with mouse click?我正在编写一个程序来裁剪图像,我的问题是我希望该矩形具有特定的纵横比(90:90),是否可以制作矩形而不是鼠标,用鼠标滚轮更改其大小并用鼠标确认点击?

import cv2
import numpy as np

cropping = False

x_start, y_start, x_end, y_end = 0, 0, 0, 0

image = cv2.imread('example.jpg')
oriImage = image.copy()


def mouse_crop(event, x, y, flags, param):
    # grab references to the global variables
    global x_start, y_start, x_end, y_end, cropping

    # if the left mouse button was DOWN, start RECORDING
    # (x, y) coordinates and indicate that cropping is being
    if event == cv2.EVENT_LBUTTONDOWN:
        x_start, y_start, x_end, y_end = x, y, x, y
        cropping = True

    # Mouse is Moving
    elif event == cv2.EVENT_MOUSEMOVE:
        if cropping == True:
            x_end, y_end = x, y

    # if the left mouse button was released
    elif event == cv2.EVENT_LBUTTONUP:
        # record the ending (x, y) coordinates
        x_end, y_end = x, y
        cropping = False # cropping is finished

        refPoint = [(x_start, y_start), (x_end, y_end)]

        if len(refPoint) == 2: #when two points were found
            roi = oriImage[refPoint[0][1]:refPoint[1][1], refPoint[0][0]:refPoint[1][0]]
            cv2.imshow("Cropped", roi)

cv2.namedWindow("image")
cv2.setMouseCallback("image", mouse_crop)

while True:

    i = image.copy()

    if not cropping:
        cv2.imshow("image", image)

    elif cropping:
        cv2.rectangle(i, (x_start, y_start), (x_end, y_end), (255, 0, 0), 2)
        cv2.imshow("image", i)

    cv2.waitKey(1)

# close all open windows
cv2.destroyAllWindows()

This is the basic structure you could use to do this.这是您可以用来执行此操作的基本结构。 Create an initial rectangle on first click, resize the rectangle by scrolling up or down, then finalize the cropping by clicking again.第一次单击时创建一个初始矩形,通过向上或向下滚动调整矩形的大小,然后再次单击完成裁剪。 You would need to add some checks to limit the rectangle when it goes out of the image bounds and when it goes "smaller than zero".您需要添加一些检查以限制矩形超出图像边界和“小于零”时的矩形。

# if the left mouse button was released
if event == cv2.EVENT_LBUTTONUP:
    # create rectangle
    if not cropping:
        x_start, y_start = x-20, y-20
        x_end, y_end = x+20, y+20
        cropping = True # cropping is finished
    # finish cropping
    else:
        refPoint = [(x_start, y_start), (x_end, y_end)]

        if len(refPoint) == 2: #when two points were found
            roi = oriImage[refPoint[0][1]:refPoint[1][1], refPoint[0][0]:refPoint[1][0]]
            cv2.imshow("Cropped", roi)

elif event == cv2.EVENT_MOUSEWHEEL:
    print(flags)
    # scroll up
    if flags > 0:
        x_start, y_start = x_start-2, y_start-2
        x_end, y_end = x_end+2, y_end+2
    # scroll down
    else:
        x_start, y_start = x_start+2, y_start+2
        x_end, y_end = x_end-2, y_end-2

Thank you :) but i have still one problem my code looks now like this:谢谢 :) 但我还有一个问题,我的代码现在看起来像这样:

import cv2
import numpy as np

cropping = False

x_start, y_start, x_end, y_end = 0, 0, 0, 0

image = cv2.imread('example.jpg')
oriImage = image.copy()


def mouse_crop(event, x, y, flags, param):
    # grab references to the global variables
    global x_start, y_start, x_end, y_end, cropping

    # if the left mouse button was DOWN, start RECORDING
    # (x, y) coordinates and indicate that cropping is being
    if event == cv2.EVENT_MOUSEMOVE:
        x_start, y_start, x_end, y_end = x, y, x+96, y+96
        cropping = True

    # Mouse is Moving
 #   elif event == cv2.EVENT_MOUSEMOVE:
 #       if cropping == True:
 #           x_end, y_end = x, y

    # if the left mouse button was released
    elif event == cv2.EVENT_LBUTTONUP:
        # record the ending (x, y) coordinates
#        x_end, y_end = x, y
        cropping = False # cropping is finished

        refPoint = [(x_start, y_start), (x_end, y_end)]

        if len(refPoint) == 2: #when two points were found
            roi = oriImage[refPoint[0][1]:refPoint[1][1], refPoint[0][0]:refPoint[1][0]]
            cv2.imshow("Cropped", roi)

    elif event == cv2.EVENT_MOUSEWHEEL:
        print(flags)
        # scroll up
        if flags > 0:
            x_start, y_start = x_start-15, y_start-15
            x_end, y_end = x_end+15, y_end+15
        # scroll down
        else:
            x_start, y_start = x_start+15, y_start+15
            x_end, y_end = x_end-15, y_end-15

cv2.namedWindow("image")
cv2.setMouseCallback("image", mouse_crop)

while True:

    i = image.copy()

    if not cropping:
        cv2.imshow("image", image)

    elif cropping:
        cv2.rectangle(i, (x_start, y_start), (x_end, y_end), (255, 0, 0), 2)
        cv2.imshow("image", i)

    cv2.waitKey(1)

# close all open windows
cv2.destroyAllWindows()

my problem is: the rectangle follows my mouse, I can make it bigger and smaller with the mousewheel but if I made it bigger and the mouse moves, it gets small again我的问题是:矩形跟随我的鼠标,我可以用鼠标滚轮让它越来越小,但是如果我把它变大并且鼠标移动,它又变小了

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM