首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将Python数据编组到imageData>imageData结构中

如何将Python数据编组到imageData>imageData结构中
EN

Stack Overflow用户
提问于 2014-03-22 23:46:01
回答 1查看 786关注 0票数 0

这个问题的根源是: OpenCV IplImage->imageData属性的逐位格式是什么?

背景:我使用Python的ctype来允许使用OpenCV的低级别C库访问pythonic。我已经能够从python获得几乎所有可访问的函数,但我仍然停留在这个函数上,它需要被称为OpenCV的旧IplImage结构的数据,特别是imageData属性。我不知道IplImage->imageData是如何组织的,而python的cv2.cv.LoadImage的iplimage类型,它表面上具有与C结构相同的数据,但它的组织方式似乎不同。

例如,我有一个4像素的图像,是2x2像素。左上角像素为100%红色。右上角像素为100%绿色。左下角像素为100%蓝色,右下角像素为100%白色。

在python中,信息如下所示:

代码语言:javascript
复制
import cv2

img = cv2.cv.LoadImage('rgbw.png')
pixels = []
for ch in img.tostring():
  pixels.append(ord(ch))
print pixels

[0, 0, 255, 0, 255, 0, 255, 0, 0, 255, 255, 255]

这对我来说很有意义:前三个值0,0,255代表B:0,G:0,R:255,红色像素。第二个是绿色,第三个是左下角,蓝色,最后一个右下角是白色。

我将其编组到库中,它运行良好,但它似乎没有“看到”imageData中的任何内容(当我使用C将数据直接传递到库时,返回代码意味着“我没有看到任何东西”)。

当然,我怀疑cvLoadImage>imageData有完全不同的数据组织方式,所以我在调试器中发现不仅数据不同,而且我无法理解它:这里是一个cvLoadImage("rgbw.png"),将它分配给一个名为‘IplImage’的IplImage结构。

代码语言:javascript
复制
Breakpoint 1, main (argc=2, argv=0x7fffffffe418) at IplImageInfo.cpp:44
44          printf("imageData %s\n", image->imageData);
(gdb) x/16ub image->imageData
0x618c90:   0   0   255 0   255 0   0   0
0x618c98:   255 0   0   255 255 255 0   0
(gdb)

因此,将其逐字节进行比较,添加零以便于比较:

Python:

代码语言:javascript
复制
000 000 255 | 000 255 000 | 255 000 000 | 255 255 255

C:(打印前16个字节,而不是12个字节,这正是我所期望的,见下文)

代码语言:javascript
复制
000 000 255 | 000 255 000 | 000 000 255 | 000 000 255 | 255 255 000 | 000

注意,前六个字节在这两个字节中都是相同的。但是,到底怎么回事?我们还有两个红色像素然后..。一个青色像素?另外,这个文件的大小是12个字节(4个像素,每个3个字节)。当我从C打印出图像->imageSize属性时,我得到16,而不是12。所以有些东西坏了,我不明白。显然,我的imageData模型有问题。你能解释一下吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-03-23 22:58:17

我使用的python代码缺少一些所需的逻辑。这个逻辑不适用于Python接口,在Python中也不知道它是如何在C库中工作的。基本上,IplImage (我也相信Mat;旧IplImage结构的C++继承者)通过添加空(0-值)字节数,将imageData属性中的一行像素除以4。所以我的代码,就是:

代码语言:javascript
复制
import cv2

img = cv2.cv.LoadImage('rgbw.png')
pixels = []
for ch in img.tostring():
  pixels.append(ord(ch))
print pixels

[0, 0, 255, 0, 255, 0, 255, 0, 0, 255, 255, 255]

错过了这个逻辑。我解决了以下问题:

代码语言:javascript
复制
import cv2

img = cv2.cv.LoadImage('rgbw.png')
height = img.height
width = img.width
raw_data = img.tostring()

# iplImage->imageData requires rows to be padded with zero bytes at the end 
# so they be divisible by 4
pad_bytes_per_row = width % 4

# create the ctypes structure
ubyte_array_type = c_ubyte * (len(raw_data) + (height * pad_bytes_per_row))
ubyte_array = ubyte_array_type()
index = 0
for ch in raw_data:
    ubyte_array[index] = ord(ch)
    index += 1
    if 0 == index % width: # end of row
        pad_index = 0
        while pad_index < pad_bytes_per_row:
            ubyte_array[index] = 0
            pad_index += 1
            index += 1

现在,ubyte_array中填充了opencv的python中的正确信息。注意,如果您对数据使用numpy_array.tostring()方法,并且希望使用该方法填充Mat对象,则这将是相同的。希望这能帮上忙。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22585184

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档