"3.95.131.208 - 3.95.131.208"

Как обрезать изображение в OpenCV с помощью Python

Как я могу обрезать изображения, как я делал это раньше в 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. Если это так, объясните, как я могу правильно использовать эту функцию.

+173
источник поделиться
7 ответов

Это очень просто. Используйте numpy slicing.

import cv2
img = cv2.imread("lenna.png")
crop_img = img[y:y+h, x:x+w]
cv2.imshow("cropped", crop_img)
cv2.waitKey(0)
+417
источник

у меня был этот вопрос и я нашел другой ответ здесь: скопируйте область интереса

Если мы рассмотрим (0,0) как верхний левый угол изображения, называемый im с слева направо как направление x и сверху вниз как направление y. и мы имеем (x1, y1) как верхнюю левую вершину и (x2, y2) как нижнюю правую вершину области прямоугольника в этом изображении, тогда:

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

Вот исчерпывающий ресурс по индексированию и разрезанию массива, который может рассказать вам больше о таких вещах, как обрезка части изображения. Изображения будут храниться в виде массива в opencv2.

:)

+102
источник
другие ответы

Связанные вопросы


Похожие вопросы

Обратите внимание, что нарезка изображения не создает копию cropped image, но создает pointer для roi. Если вы загружаете так много изображений, обрезаете соответствующие части изображений с нарезкой, а затем добавляете их в список, это может привести к огромным потерям памяти.

Предположим, что вы загружаете N изображений, каждое из которых представляет собой >1MP, и вам нужен только регион 100x100 из верхнего левого угла.

Slicing:

X = []
for i in range(N):
    im = imread('image_i')
    X.append(im[0:100,0:100]) # This will keep all N images in the memory. 
                              # Because they are still used.

Кроме того, вы можете скопировать соответствующую часть с помощью .copy(), поэтому сборщик мусора удалит im.

X = []
for i in range(N):
    im = imread('image_i')
    X.append(im[0:100,0:100].copy()) # This will keep only the crops in the memory. 
                                     # im will be deleted by gc.

Узнав об этом, я понял, что один из комментариев user1270710 упомянул это, но мне потребовалось довольно много времени, чтобы выяснить это (т.е. отладка и т.д.). Так что, думаю, стоит упомянуть.

+11
источник

этот код обрезает изображение с позиции 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) 
+5
источник
from PIL import Image
def crop(image_path, coords, saved_location):
    image_obj = Image.open("Path of the image to be cropped")
    cropped_image = image_obj.crop(coords)
    cropped_image.save(saved_location)
    cropped_image.show()


if __name__ == '__main__':
    image = "image.jpg"
    crop(image, (100, 210, 710,380 ), 'cropped.jpg')

image_path: Путь к изображению для редактирования

координаты: кортеж координат x/y (x1, y1, x2, y2) [открыть изображение в mspaint и проверьте "линейку" на вкладке просмотра, чтобы увидеть координаты]

save_location: путь для сохранения обрезанного изображения

+3
источник

вот некоторый код для более надежного 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
+2
источник

Надежная обрезка с функцией копирования границы opencv:

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 = cv2.copyMakeBorder(img, - min(0, y1), max(y2 - img.shape[0], 0),
                            -min(0, x1), max(x2 - img.shape[1], 0),cv2.BORDER_REPLICATE)
   y2 += -min(0, y1)
   y1 += -min(0, y1)
   x2 += -min(0, x1)
   x1 += -min(0, x1)
   return img, x1, x2, y1, y2
+2
источник

Посмотрите другие вопросы по меткам или Задайте вопрос