Извлечение области из изображения с использованием среза в Python, OpenCV

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

I = cv2.imread("lena.png")
I = cv2.cvtColor(I, cv2.COLOR_RGB2GRAY)
region = I[248:280,245:288]
tools.show_1_image_pylab(region)

Я не могу понять, как это сделать в цвете. Я думал об извлечении каждого канала R, G, B; срезая эту область с каждого из каналов и объединяя их вместе, но нужно быть более коротким способом.

Ответ 1

В OpenCV и Matplotlib существует небольшая разница в упорядочении пикселей.

OpenCV следует за порядком BGR, в то время как matplotlib, вероятно, следует за порядком RGB.

Поэтому, когда вы показываете изображение, загруженное в OpenCV, используя функции pylab, вам может потребоваться преобразовать его в режим RGB. (Я не уверен, есть ли какой-либо простой метод). Ниже продемонстрируйте это:

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('messi4.jpg')
b,g,r = cv2.split(img)
img2 = cv2.merge([r,g,b])
plt.subplot(121);plt.imshow(img) # expects distorted color
plt.subplot(122);plt.imshow(img2) # expect true color
plt.show()

cv2.imshow('bgr image',img) # expects true color
cv2.imshow('rgb image',img2) # expects distorted color
cv2.waitKey(0)
cv2.destroyAllWindows()

NB: Пожалуйста, отметьте комментарий @Amro ниже для лучшего способа преобразования между BGR и RGB. img2 = img[:,:,::-1]. Очень просто.

Запустите этот код и просмотрите разницу в результатах самостоятельно. Ниже я получил:

Использование Matplotlib:

enter image description here

Использование OpenCV:

enter image description here

Ответ 2

Еще 2 варианта:

img[..., ::-1] # same as the mentioned img[:, :, ::-1] but slightly shorter

и универсальный

cv2.cvtColor(img, cv2.COLOR_BGR2RGB)