2011-11-09 392 views
3

我试图在OpenCV中使用dct()函数来计算离散余弦变换,但我得到了奇怪的结果。用OpenCV计算DCT

我的脚本是:

import os, sys 
import cv, cv2 
import numpy as np 

fn1 = 'original.jpg' 
img1 = cv2.imread(fn1, 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.ShowImage('',img2) 
cv2.waitKey() 
cv.SaveImage('saved.jpg', img2) 

这似乎运行没有错误,但()由ShowImage显示的图像,并通过SaveImage()保存的图像出现很大的差异。不幸的是,我似乎无法找到DCT处理过的图像的任何样本图像,所以我不确定哪个是正确的。

原始图像: original

所示出的DCT图像: shown

保存的DCT图像: saved

为什么会出现的示出和保存的DCT的图像之间的这种差异?哪个是对的?

+2

只是一个猜测,但保存的DCT在我看来是正确的,并表示DCT看起来莫名其妙地失去了大部分的该信息(如果所有像素> epsilon已被映射为1,出于某种原因)。也许保存的图像在0-255的范围内,并且显示的图像被错误地裁剪为0-1。 – wim

回答

2

您似乎显示了DCT的复杂输出。而且,由于您试图保存2通道图像(DCT输出2个通道 - 一个用于实数,一个用于虚部),因此它只保存实数部分(这在某种程度上接近数值)。

因此,从您的DCT输出中,使用magnitude()和phase()函数来提取有用的信息。分别显示它们,

而且,最重要的是,仔细阅读有关DCT(http://en.wikipedia.org/wiki/Discrete_cosine_transform),以便您知道自己在做什么。

+0

你在哪里得到有关DCT()的输出的信息?维基百科的内容和实际实施的内容通常是完全不同的东西。我找到的所有OpenCV文档,甚至是我发布的代码都显示它返回与输入数组相同的形状,对于灰度图像,它将是单个通道,而不是两个。 http://opencv.willowgarage.com/documentation/cpp/operations_on_arrays.html#cv-dct – Cerin

+0

寻找发行版附带的opencv refman。它被称为opencv.pdf或opencv_refman.pdf,具体取决于您使用的版本。它比在线参考更详细。相同的形状不等于相同的通道编号。尝试cout << matDct.channels();以解决神秘:) – Sam

+0

但我已经使用它,它给了我2通道,浮点,单精度数据。正如refman – Sam

1

保存的图像实际上是相同的,但在保存为JPEG之前,这些值被钳位到[0..255]并转换为字节(numpy.uint8)。负值设置为零和高于255的值设置为255。

cv2.imshow("before_save", vis1) 
vis1[vis1>255] = 255 
vis1[vis1<0] = 0 
cv2.imshow("saved", vis1.astype(np.uint8))