使用OpenCV计算图像的离散余弦变换
我正在尝试使用 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)