Python 用OpenCV计算DCT

Python 用OpenCV计算DCT,python,opencv,computer-vision,signal-processing,Python,Opencv,Computer Vision,Signal Processing,我试图使用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 vi

我试图使用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处理图像的样本图像,所以我不确定哪一个是正确的

原始图像:

显示的DCT图像:

保存的DCT图像:


为什么显示的DCT图像和保存的DCT图像之间存在如此大的差异?哪个是正确的?

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

因此,从DCT输出中,使用magnity()和phase()函数提取有用的信息。分别展示,


而且,最重要的是,仔细阅读关于DCT()的内容,这样您就知道自己在做什么

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

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

vis1[vis1只是一个猜测,但保存的DCT在我看来是正确的,并且显示的DCT看起来似乎以某种方式丢失了大部分信息(好像出于某种原因,所有像素>ε都已映射到1)。可能保存的图像在0-255范围内,而显示的图像错误地将其剪裁为0-1。您从哪里获得有关DCT()输出的信息?Wikipedia中编写的内容和实际实现的内容通常是非常不同的。我找到的所有OpenCV文档,甚至我发布的代码,都显示它返回与输入数组相同的形状,对于灰度图像,它将是一个单一通道,而不是两个。查找发行版附带的OpenCV参考人。它被称为opencv.pdf或opencv_refman.pdf,具体取决于您使用的版本。它比在线参考更详细。相同的形状不等于相同的通道号。请尝试,但我使用过它,它提供了2通道浮点单精度数据。如中所述refman@vasile...I我不知道该告诉你什么,密码不是谎言nd cv2.dct()输出一个numpy ndarray…它没有channels()函数而不是C++ API。也许Python包装器的工作方式与过去使用的不同,我不使用Python,但是我使用了更多的OCV版本,包括2.3和2.3.1。你所贴的图片清楚地显示了DCT的复杂(第一)和真实(第二)部分。对于DCT输出,检查结果。我应该接近第二幅图像(但不完全相同)。