gpt4 book ai didi

python - 在 Python 中使用 OpenCV 将打包的 BGRA 图像缓冲区转换为 RGB 时出现问题

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:08:21 26 4
gpt4 key购买 nike

一些背景:
我有一个 packed BGRA我想将缓冲区中的图像转换为 RGB。

我使用以下代码通过 OpenCV 将其转换为 RGB:

np_a = np.array( image_buffer ) #image_buffer is an array of uint8
rgb_a = cv2.cvtColor( image_buffer, cv2.COLOR_BGRA2RGB )

但是:

OpenCV Error: Assertion failed (scn == 3 || scn == 4) in ipp_cvtColor,
file /home/username/opencv/opencv-3.1.0/modules/imgpro/src/color.cpp, line 7341

由于 OpenCV 是开源的,我已经深入研究了 source code弄清楚发生了什么。

    static bool ipp_cvtColor( Mat &src, OutputArray _dst, int code, int dcn )
{
int stype = src.type();
int scn = CV_MAT_CN(stype), depth = CV_MAT_DEPTH(stype);

Mat dst;
Size sz = src.size();

switch( code )
{
#if IPP_VERSION_X100 >= 700
case CV_BGR2BGRA: case CV_RGB2BGRA: case CV_BGRA2BGR:
case CV_RGBA2BGR: case CV_RGB2BGR: case CV_BGRA2RGBA:
CV_Assert( scn == 3 || scn == 4 );

和:

#define CV_MAT_CN (flags) ((((flags) & CV_MAT_CN_MASK) >> CV_CN_SHIFT) + 1)
#define CV_MAT_CN_MASK ((CV_CN_MAX - 1) << CV_CN_SHIFT)
#define CV_CN_MAX 512
#define CV_CN_SHIFT 3

我不确定是否理解这些代码行。
我假设 scn 是“源 channel 号”,它与数组的维数有关。然后断言会失败,因为该数组是作为一维数组创建的。
事实上,print np_a.ndim 输出 1print np_a.shape 输出 (422400,)

我尝试了很多东西。其中,用np_a.shape = (image_height, image_width)手动设置数组的shape,结果报错:

Program received signal SIGSEGV, Segmentation fault.
0x0000000000570558 in visit_decref ()

我错过了什么?
我应该在转换之前手动解压缩图像吗?怎么办?


第一次编辑:
使用 C API 填充缓冲区。应该是UINT8的数组。

另外,这个:

print type( np_a )
print type( np_a[ 0 ] )
print np_a.shape

输出:

<type 'numpy.ndarray'>
<type 'numpy.uint8'>
(422400,)

第二次编辑:

问题已经解决了,这只是为了更好地理解/另一种方式。

使用:

np_a           = np.array( image_buffer )
np_a_reshaped = np_a.reshape( height, width, depth )
np_a_converted = np_a_reshaped[ ...,:3 ][ ...,::-1 ]
print len( np_a_converted )

输出:480。

是的,我可能单独使用了 np_a.reshape( ... ) 并假设它会改变 np_a 的形状。为什么要更改缓冲区的形状创建一个新变量?

但是,np_a_converted 的大小仍然不正确。确实,在程序的后面,有如下代码:

img = wx.ImageFromBuffer( width, height, np_a_converted )
bmp = wx.Bitmap( img )

从缓冲区创建一个 wx.Bitmap,不复制数据。

来自 wx.ImageFromBuffer's documentation :

The dataBuffer object is expected to contain a series of RGB bytes and be width*height*3 bytes long.

它给出了这个错误:

File "/usr/local/lib/python2.7/dist-packages/wx/core.py", line 656, in ImageFromBuffer
img.SetDataBuffer(dataBuffer)
ValueError: Invalid data buffer size.

最佳答案

如果您的缓冲区是 8 位“打包”的,那么您所缺少的只是一个reshape:

image = image_buffer.reshape(height, width, 4)
rgb = cv2.cvtColor(image, cv2.COLOR_BGRA2RGB)

我不清楚 BGRA2RGB 在这里做了什么 - 没有“正确”的方法可以在不选择背景颜色的情况下删除 alpha channel 。如果 alpha 数据是垃圾,你可以选择更简单的

rgb = image[...,:3][...,::-1]

忽略alpha channel ,然后翻转字节顺序。这比使用 opencv 快 O(w*h) 倍!

请注意,如果您打算将此数组传回 opencv,您可能需要添加:

rgb = np.copy(rgb)

这使得数据在内存中是连续的,这是一些 opencv 函数的要求。这显然会让您失去上面提到的效率增益。

关于python - 在 Python 中使用 OpenCV 将打包的 BGRA 图像缓冲区转换为 RGB 时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37419586/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com