使用OpenCV计算图像的离散余弦变换

5 投票
6 回答
13938 浏览
提问于 2025-04-17 05:12

我正在尝试使用 OpenCV 2.3 的 Python 接口来计算一张图片的离散余弦变换(DCT)。我听说图片可以看作是 numpy 数组,也可以看作是 CV 矩阵,所以我觉得这样做应该没问题:

import cv2
img1 = cv2.imread('myimage.jpg', cv2.CV_LOAD_IMAGE_GRAYSCALE)
img2 = cv2.dct(img1)

但是,这样做却出现了错误:

cv2.error: /usr/local/lib/OpenCV-2.3.1/modules/core/src/dxt.cpp:2247: error: (-215) type == CV_32FC1 || type == CV_64FC1 in function dct

我明白这个错误的意思是,输入应该是一个 32 位或 64 位的单通道浮点矩阵。不过,我以为在指定为灰度图像时,我的图片应该就是这样加载的,或者至少应该接近这个标准,这样 CV2 应该能自动处理转换。

那么,使用 cv2 将图片转换为 DCT 的正确方法是什么呢?

6 个回答

2

这是我从openCV论坛上找到的一个解决方案,它有效。

img = cv2.imread(fn, 0)      # 1 chan, grayscale!
imf = np.float32(img)/255.0  # float conversion/scale
dst = cv2.dct(imf)           # the dct
img = np.uint8(dst)*255.0    # convert back
3

我本来不想写这个回答,但看到一些错误的回答却得到了很多赞,我决定还是写一下。

dct操作可以处理任何范围的输入,所以我不明白为什么其他人要把它缩放到[0, 1]。不过在opencv中,你需要传入numpy.float32类型的数字。

x = np.array([8, 16, 24 , 32, 40, 48, 56, 64])
cv2.dct(np.float32(x))

# output
array([[ 101.82337189],
       [ -51.53858566],
       [   0.        ],
       [  -5.38763857],
       [   0.        ],
       [  -1.60722351],
       [   0.        ],
       [  -0.40561762]], dtype=float32)

但是如果你缩放了,几乎所有的小值都会丢失。

这里有一个链接,里面有公式和例子: https://users.cs.cf.ac.uk/Dave.Marshall/Multimedia/node231.html#DCTbasis

3

看起来用cv2(一个常用的计算机视觉库)来做到这一点并没有简单的方法。我找到的最接近的解决方案是:

import cv, cv2
import numpy as np

img1 = cv2.imread('myimage.jpg', cv2.CV_LOAD_IMAGE_GRAYSCALE)
h, w = img1.shape[:2]
vis0 = np.zeros((h,w), np.float32)
vis0[:h, :w] = img1
vis1 = cv2.dct(vis0)
img2 = cv.CreateMat(vis1.shape[0], vis1.shape[1], cv.CV_32FC3)
cv.CvtColor(cv.fromarray(vis1), img2, cv.CV_GRAY2BGR)

cv.SaveImage('output.jpg', img2)

撰写回答