如何使用Python在OpenCV中裁剪图像

时间:2021-11-17 00:33:53

How can I crop images, like I've done before in PIL, using OpenCV.

我怎么能裁剪图像,就像我以前在PIL,使用OpenCV。

Working example on PIL

在公益诉讼工作示例

im = Image.open('0.png').convert('L')
im = im.crop((1, 1, 98, 33))
im.save('_0.png')

But how I can do it on OpenCV?

但是我怎么在OpenCV上做呢?

This is what I tried:

这就是我所尝试的:

im = cv.imread('0.png', cv.CV_LOAD_IMAGE_GRAYSCALE)
(thresh, im_bw) = cv.threshold(im, 128, 255, cv.THRESH_OTSU)
im = cv.getRectSubPix(im_bw, (98, 33), (1, 1))
cv.imshow('Img', im)
cv.waitKey(0)

But it doesn't work.

但它不工作。

I think I incorrectly used getRectSubPix. If this is the case, please explain how I can correctly use this function.

我想我用错了getRectSubPix。如果是这样的话,请解释我如何正确地使用这个函数。

3 个解决方案

#1


241  

It's very simple. Use numpy slicing.

很简单。使用numpy切片。

import cv2
img = cv2.imread("lenna.png")
crop_img = img[y:y+h, x:x+w]
cv2.imshow("cropped", crop_img)
cv2.waitKey(0)

#2


64  

i had this question and found another answer here: copy region of interest

我有了这个问题,找到了另一个答案:复制感兴趣的区域

If we consider (0,0) as top left corner of image called im with left-to-right as x direction and top-to-bottom as y direction. and we have (x1,y1) as the top-left vertex and (x2,y2) as the bottom-right vertex of a rectangle region within that image, then:

如果我们考虑(0,0)作为图像的左上角称为im,从左到右为x方向,从上到下为y方向。我们有(x1,y1)作为左上角的顶点,(x2,y2)作为图像中矩形区域的右下角顶点,然后:

roi = im[y1:y2, x1:x2]

here is a comprehensive resource on numpy array indexing and slicing which can tell you more about things like cropping a part of an image. images would be stored as a numpy array in opencv2.

这里有一个关于numpy数组索引和切片的综合资源,它可以告诉您更多关于剪切图像的信息。图像将作为一个numpy数组存储在opencv2中。

:)

:)

#3


0  

here is some code for more robust imcrop ( a bit like in matlab )

下面是一些更健壮的imcrop的代码(有点像matlab)

    def imcrop(img, bbox): 
        x1,y1,x2,y2 = bbox
        if x1 < 0 or y1 < 0 or x2 > img.shape[1] or y2 > img.shape[0]:
            img, x1, x2, y1, y2 = pad_img_to_fit_bbox(img, x1, x2, y1, y2)
        return img[y1:y2, x1:x2, :]

    def pad_img_to_fit_bbox(img, x1, x2, y1, y2):
        img = np.pad(img, ((np.abs(np.minimum(0, y1)), np.maximum(y2 - img.shape[0], 0)),
                   (np.abs(np.minimum(0, x1)), np.maximum(x2 - img.shape[1], 0)), (0,0)), mode="constant")
        y1 += np.abs(np.minimum(0, y1))
        y2 += np.abs(np.minimum(0, y1))
        x1 += np.abs(np.minimum(0, x1))
        x2 += np.abs(np.minimum(0, x1))
        return img, x1, x2, y1, y2

#1


241  

It's very simple. Use numpy slicing.

很简单。使用numpy切片。

import cv2
img = cv2.imread("lenna.png")
crop_img = img[y:y+h, x:x+w]
cv2.imshow("cropped", crop_img)
cv2.waitKey(0)

#2


64  

i had this question and found another answer here: copy region of interest

我有了这个问题,找到了另一个答案:复制感兴趣的区域

If we consider (0,0) as top left corner of image called im with left-to-right as x direction and top-to-bottom as y direction. and we have (x1,y1) as the top-left vertex and (x2,y2) as the bottom-right vertex of a rectangle region within that image, then:

如果我们考虑(0,0)作为图像的左上角称为im,从左到右为x方向,从上到下为y方向。我们有(x1,y1)作为左上角的顶点,(x2,y2)作为图像中矩形区域的右下角顶点,然后:

roi = im[y1:y2, x1:x2]

here is a comprehensive resource on numpy array indexing and slicing which can tell you more about things like cropping a part of an image. images would be stored as a numpy array in opencv2.

这里有一个关于numpy数组索引和切片的综合资源,它可以告诉您更多关于剪切图像的信息。图像将作为一个numpy数组存储在opencv2中。

:)

:)

#3


0  

here is some code for more robust imcrop ( a bit like in matlab )

下面是一些更健壮的imcrop的代码(有点像matlab)

    def imcrop(img, bbox): 
        x1,y1,x2,y2 = bbox
        if x1 < 0 or y1 < 0 or x2 > img.shape[1] or y2 > img.shape[0]:
            img, x1, x2, y1, y2 = pad_img_to_fit_bbox(img, x1, x2, y1, y2)
        return img[y1:y2, x1:x2, :]

    def pad_img_to_fit_bbox(img, x1, x2, y1, y2):
        img = np.pad(img, ((np.abs(np.minimum(0, y1)), np.maximum(y2 - img.shape[0], 0)),
                   (np.abs(np.minimum(0, x1)), np.maximum(x2 - img.shape[1], 0)), (0,0)), mode="constant")
        y1 += np.abs(np.minimum(0, y1))
        y2 += np.abs(np.minimum(0, y1))
        x1 += np.abs(np.minimum(0, x1))
        x2 += np.abs(np.minimum(0, x1))
        return img, x1, x2, y1, y2