2011-11-09 391 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))