如何裁剪图像,就像我以前在PIL中所做的那样,使用OpenCV。

PIL工作示例

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

但是我怎么在OpenCV上做呢?

这就是我所尝试的:

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)

但这并不奏效。

我想我错误地使用了getRectSubPix。如果是这样,请解释我如何正确使用这个功能。


当前回答

以裁剪或感兴趣的区域(ROI)用于下面的代码

import cv2 
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
image=cv2.imread("ronaldo.jpg")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in faces:
     cv2.rectangle(img,(x,y),(x+w,y+h),(255,255,0),2) 
     roi_image = gray[y:y+h, x:x+w]
cv2.imshow("crop/region of interset image",roi_image) 
cv2.waitKey(0)
cv2.destroyAllWindows()

查阅参考资料

其他回答

这很简单。使用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)

或者,你可以使用tensorflow进行裁剪,使用openCV从图像中生成数组。

import cv2
img = cv2.imread('YOURIMAGE.png')

img是一个(imageheight, imagewidth, 3)形状数组。用tensorflow裁剪数组:

import tensorflow as tf
offset_height=0
offset_width=0
target_height=500
target_width=500
x = tf.image.crop_to_bounding_box(
    img, offset_height, offset_width, target_height, target_width
)

用tf重新组装图像。Keras,所以我们可以看看它是否有效:

tf.keras.preprocessing.image.array_to_img(
    x, data_format=None, scale=True, dtype=None
)

这将在笔记本中打印出图片(在谷歌Colab中测试)。


整个代码放在一起:

import cv2
img = cv2.imread('YOURIMAGE.png')

import tensorflow as tf
offset_height=0
offset_width=0
target_height=500
target_width=500
x = tf.image.crop_to_bounding_box(
    img, offset_height, offset_width, target_height, target_width
)

tf.keras.preprocessing.image.array_to_img(
    x, data_format=None, scale=True, dtype=None
)

这段代码将图像从x=0,y=0裁剪到h=100,w=200。

import numpy as np
import cv2

image = cv2.imread('download.jpg')
y=0
x=0
h=100
w=200
crop = image[y:y+h, x:x+w]
cv2.imshow('Image', crop)
cv2.waitKey(0) 

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

如果我们把(0,0)看作图像的左上角,叫做im,从左到右是x方向,从上到下是y方向。我们有(x1,y1)作为图像中一个矩形区域的左上角顶点(x2,y2)作为右下角顶点,那么:

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

这里有一个关于numpy数组索引和切片的综合资源,它可以告诉你更多关于裁剪图像部分的事情。图像将在opencv2中存储为numpy数组。

:)

通过使用这个函数,你可以很容易地裁剪图像

def cropImage(Image, XY: tuple, WH: tuple, returnGrayscale=False):
    # Extract the x,y and w,h values
    (x, y) = XY
    (w, h) = WH
    # Crop Image with numpy splitting
    crop = Image[y:y + h, x:x + w]
    # Check if returnGrayscale Var is true if is then convert image to grayscale
    if returnGrayscale:
        crop = cv2.cvtColor(crop, cv2.COLOR_BGR2GRAY)
    # Return cropped image
    return crop

希望这能有所帮助