Opencv... 获取IPLImage或CvMat中的数据

4 投票
3 回答
7328 浏览
提问于 2025-04-16 18:19

我正在用Python做一些简单的程序,使用的是opencv这个库。我想自己写几个算法,所以需要获取图像内部的“原始”图像数据。比如,我不能直接用image[i,j]这样的方式,那我该怎么获取这些数字呢?

谢谢!

3 个回答

0

我对opencv的python接口不太了解,但在C或C++中,你需要获取存储在IplImage中的缓冲区指针。这个缓冲区是根据图像格式编码的(这个格式也存储在IplImage中)。对于RGB格式来说,每个颜色通道都有一个字节,红色用一个字节,绿色用一个字节,蓝色也用一个字节,依此类推。

你可以查看python接口的API文档,里面会告诉你如何访问这个缓冲区,然后你就可以获取到像素的信息了。

我的两分钱

1

CvMat和IplImage都有一个叫做tostring的方法,这个方法可以把原始数据转成字符串。通过这些图像数据,你可以弄明白怎么把这个字符串当作一个矩阵来理解。

你可以使用fromarray把数据字符串转换回图像对象。

如果想把字符串转换成数组,可以考虑使用Python里的array模块。例如:

array.array('B', CvMat.tostring()) # 'B' is unsigned char, for rgb8 images

要获取像素之间的“步幅”,可以使用:

stride = CvMat.step / CvMat.cols

然后用常规的数组索引方法来获取单个像素。你可能想把这些复杂的操作封装到一个类里,这样就能隐藏那些麻烦的细节。

5

这里有个简单的例子,教你如何用 LoadImageM 直接把一个图片文件加载到 cvmat 里:

import cv

path = 'stack.png'
mat = cv.LoadImageM(path, cv.CV_LOAD_IMAGE_UNCHANGED)
x, y = 42, 6
print type(mat)
print mat[y, x]

输出结果:

<type 'cv.cvmat'>
(21.0, 122.0, 254.0)

再来一个简单的例子,演示如何把一个或多个颜色通道乘以 0.5

for x in xrange(mat.cols):
    for y in xrange(mat.rows):
        # multiply all 3 components by 0.5
        mat[y, x] = tuple(c*0.5 for c in mat[y, x])

        # or multiply only the red component by 0.5
        b, g, r = mat[y, x]
        mat[y, x] = (b, g, r * 0.5)

撰写回答