使用Python和OpenCV通过切片从图像中提取区域

62

我有一张图片,想要从中提取一个区域。我有这个区域左上角和右下角的坐标。在灰度模式下,我可以这样做:

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;从每个通道中切割出此区域,然后将它们合并在一起,但肯定有更简单的方法。

@Abid Rahman K 我试过了,这是效果 颜色不对。我怀疑只是一个通道的问题。 - Booyaches
1
也许你可以使用 GetRectSubPix() 来获取区域,而不是切片。 - martineau
2
我刚刚测试了一下,我得到了彩色图像本身。使用cv2.imshow()函数显示图像,而不是任何pylab或matplotlib函数,在它们中只会以不同的颜色映射显示。 - Abid Rahman K
1
如果你有疑问,检查一下region.shape并确保其格式为[rows,cols,3] - Abid Rahman K
@AbidRahmanK 你说得对!我被不同的颜色搞混了。感谢你的帮助! - Booyaches
显示剩余3条评论
3个回答

147

在OpenCV和Matplotlib中,像素排序有轻微的差异。

OpenCV遵循BGR顺序,而Matplotlib可能遵循RGB顺序。

因此,当您使用pylab函数显示在OpenCV中加载的图像时,您可能需要将其转换为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()

请查看下面@Amro的评论,以获取更好的BGR和RGB之间转换方法。img2 = img[:,:,::-1]。非常简单。
运行此代码并自行查看结果差异。下面是我得到的:
使用Matplotlib:

enter image description here

使用OpenCV:

enter image description here


89
您可以使用以下代码将图像的颜色维度从BGR翻转为RGB(仅使用NumPy索引):img2 = img[:,:,::-1] - Amro
3
+1 - 是的,你说得对,这样会比我的答案更快。感谢您的评论。(我只是想特别展示一下R和B通道的翻转。) - Abid Rahman K
16
另一种实现该结果的方法是使用带有cv2.COLOR_BGR2RGB标志的cv2.cvtColor函数。 - vahid abdi
1
这个怎么样?cv2.imshow = lambda _, y: plt.imshow(y[:,:,::-1]).figure - Hatshepsut
它的翻译是:img2 = img[::,::-1] - bluedroid

50

还有两个选项尚未提到:

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

同时也非常多才多艺的

cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

1
最好的方法是使用以下代码:
img2 = cv2.cvtColor(img , cv2.COLOR_BGR2RGB)

这将把BGR格式的'img'数组转换为RGB格式的'img2'数组。现在,您可以使用img2数组作为matplotlib的imshow()函数的参数。

参考链接:cvtColor


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接