2011-11-09 13 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が見えています情報(何らかの理由で、すべてのピクセル>イプシロンが1にマップされているかのように)。保存された画像の範囲が0〜255で、表示されている画像が誤って0〜1にクリッピングされている可能性があります。 – wim

答えて

2

DCTの複雑な出力が表示されたようです。また、2チャンネルの画像を保存しようとしたため(DCTは2チャンネル、つまり1つは実数用、もう1つは虚数部用)、実際の部分のみが保存されました(これはやや大きさに近い)。

DCT出力から、magnitude()関数とphase()関数を使用して有用な情報を抽出します。別々に表示してください。

DCT(http://en.wikipedia.org/wiki/Discrete_cosine_transform)については、慎重にお読みください。

+0

DCT()の出力についての情報はどこにありますか? Wikipediaに書かれていることと実際に実装されていることは、通常は非常に異なることです。私が見つけたすべてのOpenCVドキュメントと私の投稿されたコードは、入力配列と同じ形を返すことを示しています。これは、グレースケールイメージでは2つではなく1つのチャネルになります。 http://opencv.willowgarage.com/documentation/cpp/operations_on_arrays.html#cv-dct – Cerin

+0

ディストリビューションに付属のopencv refmanを探してください。使用しているバージョンに応じて、opencv.pdfまたはopencv_refman.pdfと呼ばれています。それはオンライン参照よりも詳細です。同じ形が同じチャンネル番号と同じではありません。 try cout << matDct.channels();ミステリーを解決する:) – Sam

+0

しかし、私はそれを使用して、それは私に2チャンネル、浮動小数点、単精度のデータを与えます。返信者 – Sam

1

保存されたイメージは実際には同じですが、値は[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)) 
関連する問題