今、画像圧縮の勉強をしてるんですが、離散コサイン変換(DCT)のプログラムが
分からないので、サンプルプログラムなどがあれば見てみたいのですが、誰か
しらないでしょうか?

このQ&Aに関連する最新のQ&A

A 回答 (2件)

高速フーリエ・コサイン・サイン変換(FFT)でよければプログラムはあります。


FFT とは離散フーリエ変換に関連する変換を高速に実行する一連の計算方法のことです。参考になればよいのですが。

参考URL:http://momonga.t.u-tokyo.ac.jp/~ooura/fftman/
    • good
    • 0

以下のサイトはどうでしょうか。



それと本なども出ております。
「マルチメディア技術の基礎DCT(離散コサイン変換)入門」
http://www.cqpub.co.jp/hanbai/books/36791.htm

参考にされてください。

参考URL:http://www.mathworks.com/access/helpdesk/jhelp/t …

この回答への補足

もっとプログラムのことについて詳しく載っているサイトってないんでしょうか?

補足日時:2001/01/17 16:38
    • good
    • 0
この回答へのお礼

本の紹介ありがとうございます。さっそく購入してみます。

お礼日時:2001/01/17 13:32

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QDCT(離散コサイン変換)定義式英語読み

DCT(離散コサイン変換)の定義式の英語読みを教えてください。
参考HP
http://www.eli.hokkai-s-u.ac.jp/~kikuchi/ma2/chap09.html

Aベストアンサー

参考URLの文書を参考にしてはどうでしょうか。
この文書によると,カッコは音読しないようですが,一応参考までに書いておくと,( は bracket, { は curly bracket, [ は square bracket と呼ぶようです。

参考URL:http://www.math.helsinki.fi/engl.pdf

Q離散フーリエ変換のプログラムについて

今DFTのプログラムをC言語で書いているんですが、うまく動いてくれません。
DFTの式はX(k)=1/N{Σx(k)*e^(-j2πkn/N)}のシグマの中をn=0からN-1まで足し合わせればいいと思っているのですがちがいますか。
下にプログラムを書きますのでお願いします。

void DFTcore(double x[],int N,double A[],double fai[],double a_rl[],double a_im[]){

    x[]はデータ
    Nはデータ数
    A[]は振幅
    fai[]は位相差
    a_rl[]は実数部、a_im[]は虚数部

double w,a;
int k,n,t;

for(k=0;k<N;k++){  //初期化
   a_rl[k]=0.0;  //実数部
   a_im[k]=0.0;  //虚数部
  }
    時間間隔は1秒
for(k=0;k<N;k++){
      for(n=0;n<N;n++){
  w=((2*PI)/N)*k*n;
        a_rl[k]=a_rl[k]+x[k]*cos(w);
  a_im[k]=-a_im[k]+x[k]*sin(w);
 }
  a_rl[k]=a_rl[k]/(double)N;実数部
  a_im[k]=-a_im[k]/(double)N; 虚数

  A[k]=sqrt(a_rl[k]*a_rl[k]+a_im[k]*a_im[k]);//振幅
   fai[k]=atan(a_im[k]/a_rl[k]);//位相

}
}

今DFTのプログラムをC言語で書いているんですが、うまく動いてくれません。
DFTの式はX(k)=1/N{Σx(k)*e^(-j2πkn/N)}のシグマの中をn=0からN-1まで足し合わせればいいと思っているのですがちがいますか。
下にプログラムを書きますのでお願いします。

void DFTcore(double x[],int N,double A[],double fai[],double a_rl[],double a_im[]){

    x[]はデータ
    Nはデータ数
    A[]は振幅
    fai[]は位相差
    a_rl[]は実数部、a_im[]は虚数部

double w,a;
...続きを読む

Aベストアンサー

正しくは、X(k)=1/N{Σx(n)*e^(-j2πkn/N)}
(ただし、k=f*N/f_sample , fは調べたい周波数、f_sampleはサンプリング周波数)
です。
とりあえずは、
a_rl[k]=a_rl[k]+x[n]*cos(w);
a_im[k]=a_im[k]+x[n]*sin(w);
とすれば動作確認はできます。
あとはご自分のプログラムの中でのkの意味(f*N/f_sampleは整数でなくてもよい)、f<(f_sample/2)、に注意し、プログラムを書きなおしてみてください。またきれいなスペクトルを得るには窓関数処理をお忘れなく。

数学、数式が大の苦手の私ですが、DFTはおぼろげに理解できたので、以前N88BASICという言語で(今は知っている人が少ないらしい)、DFTのプログラムを書いたことがあります。なにせクロック周波数12MHzのパソコンだったので、サインテーブルを作って積和演算の部分はマシン語で書いたり、いろいろやりました。
きれいなスペクトルが出ると感動しますよ。ご健闘を祈ります。
 

正しくは、X(k)=1/N{Σx(n)*e^(-j2πkn/N)}
(ただし、k=f*N/f_sample , fは調べたい周波数、f_sampleはサンプリング周波数)
です。
とりあえずは、
a_rl[k]=a_rl[k]+x[n]*cos(w);
a_im[k]=a_im[k]+x[n]*sin(w);
とすれば動作確認はできます。
あとはご自分のプログラムの中でのkの意味(f*N/f_sampleは整数でなくてもよい)、f<(f_sample/2)、に注意し、プログラムを書きなおしてみてください。またきれいなスペクトルを得るには窓関数処理をお忘れなく。

数学、数式が大の苦手の私ですが、DFTはおぼろ...続きを読む

Q離散コサイン変換について・・・

DCT(離散コサイン変換)についてなのですが、主に画像処理などに用いられていると習いました。。
身近なものでDCTを利用しているものってどんなものがあるのですか??また画像処理以外に利用されているものとかあるのですか??
どうか教えてください!!
お願いします。。

Aベストアンサー

 DCT の画像処理での利用は,ずばり,JPEG(厳密には,JPEG のもっとも一般的な符号化法)と MPEG です。これは大変身近です。
 JPEG は写真などの符号化に使用されます。なぜなら,写真(自然画像)は低周波成分を多く含むからです。周波数領域に変換することで,圧縮しやすいかたちにします。ここで,コンピュータで DFT(フーリエ変換)より DCT が好まれるのは,計算が実数の範囲で完結する点にあります(DFT では複素数になる)。

 画像処理以外 DCT の利用は,結局似たようなものですが,MP3 の符号化にも使用されています。

Qjpeg の DCT 変換がうまくいきません。

jpeg の DCT 変換がうまくいきません。

jpegを作りたいのですが、DCT変換で詰まってしまいました。
よろしければ、ご教授いただけませんでしょうか?

http://www.ann.hi-ho.ne.jp/jiro/assyuku2.htm

のDCT変換の例を見て、プログラムを作ってみましたが、
変換例と同じ値に変換されませんでした。

作ってみたプログラムです。

#include <iostream>
#include <stdio.h>
#define _USE_MATH_DEFINES
#include <math.h>

using namespace std;


void main(int argc, char** argv)
{

  double cu = 1.0;
  double cv = 1.0;
    double long sum = 0.0;
  
  int before[8][8] ={
    {57,49,44,39,33,28,23,22},
    {55,45,39,33,28,21,21,19},
    {55,44,37,31,20,17,17,16},
    {58,44,37,29,17,15,16,14},
    {66,46,31,22,16,14,12,10},
    {71,49,32,24,14,12,21,19},
    {69,50,30,22,12,4,-1,-2},
    {62,42,25,17,7,1,-16,-16}
  
  };
  int after[8][8];
  ZeroMemory(after,sizeof(int)*64);

  for(int v =0; v < 8; v++)
  {
    if(v) cv =1.0;
    if(!v) cv = 1 / sqrt(2.0);
    for(int u = 0; u < 8; u++)
    {
      if(u) cu =1.0;
      if(!u) cu = 1 / sqrt(2.0);
      sum = 0.0;
      for(int y = 0; y < 8; y++)
      {
        for(int x = 0; x < 8; x++)
        {
          double long a = cos((2 * x + 1)*u*M_PI/16) * cos(( 2 * y + 1)*v*M_PI/16);
          double long d = before[x][y];
          sum += d * a;
        }
      }
      after[u][v] = int(cu*cv*sum/4);
    }
  }

  for(int j = 0; j < 8; j++)
  {
    for(int i = 0; i < 8; i++)
    {
      cout << after[i][j] << ",";
    }
    cout << endl;
  }

  int b;
  cin >> b ;


}

jpeg の DCT 変換がうまくいきません。

jpegを作りたいのですが、DCT変換で詰まってしまいました。
よろしければ、ご教授いただけませんでしょうか?

http://www.ann.hi-ho.ne.jp/jiro/assyuku2.htm

のDCT変換の例を見て、プログラムを作ってみましたが、
変換例と同じ値に変換されませんでした。

作ってみたプログラムです。

#include <iostream>
#include <stdio.h>
#define _USE_MATH_DEFINES
#include <math.h>

using namespace std;


void main(int argc, char** argv)
{

  double cu = 1.0;
 ...続きを読む

Aベストアンサー

ちょっとだけ補足しておきます。

> int(floor(cu*cv*sum/4+0.5));

floor は「引数値を超えない最大の整数」を返す関数であり、
それに0.5足した値を入れることで、四捨五入になります。

修正前> double long d = before[x][y];
修正後> double long d = before[y][x];

修正前> after[u][v] = int(cu*cv*sum/4);
修正後> after[v][u] = int(floor(cu*cv*sum/4+0.5));

修正前> cout << after[i][j] << ",";
修正後> cout << after[j][i] << ",";

この3行の修正で、質問者さんが挙げたリンク先の実行例と同じ結果になることは確認済です。

Q画像圧縮の離散コサイン変換,量子化について

画像圧縮について勉強していてあやふやなところがあり教えて頂きたいです.

変換前
|126, 138, 135, 118, 118, 126, 126, 130|
|150, 168, 161, 122, 105, 109, 100, 118|
|150, 150, 126, 150, 142, 126, 126, 117|
|150, 161, 168, 130, 134, 150, 138, 130|
|130, 118, 134, 142, 157, 142, 117, 126|
|115, 117, 108, 117, 101, 99, 117, 126|
|122, 130, 130, 138, 117, 108, 108, 138|
|142, 118, 134, 117, 109, 91, 126, 109|

変換後
|1029, 52, 10, -21, -1, -3, 2, 1|
| 39, 21, 0, 6, -22, -17, 4, -7|
| -40, 12, 24, -19, -2, 7, -4, 5|
| -32, -34, -1, -7, 5, -8, 5, -7|
| 22, -14, -10, 16, -12, 4, 12, 18|
| 19, -17, 1, -3, -6, -3, -2, -8|
| -24, -18, 3, 15, 9, 15, -20, 1|
| 9, -16, -30, 14, 29, -2, -5, -5|

URLから参考にしたものですが,変換すると右下から左上へと値が高くなっています.
これは圧縮することで,左上の情報量が大きくなる方法ということはわかります.
ですが,量子化する方法がよくわかりません.
この値を使ってどうすればいいのでしょうか.
変換前は濃度あたりだと思うんですが,変換後はマイナスの値がついててさっぱりです.

検索していろいろでてきたのですが,
難しくてわからないところもあったので
一言“量子化する”とかじゃなくて
“離散コサイン変換後の量子化方法はこうするものだ”という具体的なものができればききたいです.

最終的に画像圧縮プログラムを組もうと思っています.
圧縮までに必要な仮定を教えてください.

あと,プログラムはVisualC++OpenCVで組もうと思うのですが,勉強ですので関数を使うつもりはありません.
おまけですが,JPEGで離散コサイン変換するという方法があるみたいですが,IPLimageを使用するのは不可能ですか?

質問する場所がわからなかったのでここでさせて頂いたのですが,間違っていたら移動させますので教えて頂けるとありがたいです.

よろしくお願いします.

参考URL:http://fussy.web.fc2.com/algo/algo8-6.htm

画像圧縮について勉強していてあやふやなところがあり教えて頂きたいです.

変換前
|126, 138, 135, 118, 118, 126, 126, 130|
|150, 168, 161, 122, 105, 109, 100, 118|
|150, 150, 126, 150, 142, 126, 126, 117|
|150, 161, 168, 130, 134, 150, 138, 130|
|130, 118, 134, 142, 157, 142, 117, 126|
|115, 117, 108, 117, 101, 99, 117, 126|
|122, 130, 130, 138, 117, 108, 108, 138|
|142, 118, 134, 117, 109, 91, 126, 109|

変換後
|1029, 52, 10, -21, -1, -3, 2, 1|
| 39, 21, 0, 6...続きを読む

Aベストアンサー

> URLから参考にしたものですが,変換すると右下から左上へと値が高くなっています.
> これは圧縮することで,左上の情報量が大きくなる方法ということはわかります.

まず、一つ指摘をしておきます。離散コサイン変換は、情報量を減らしません。つまり、この変換は情報の圧縮を行っているわけではないのです。しかも、

> 変換前は濃度あたりだと思うんですが,変換後はマイナスの値がついててさっぱりです.

だとすると、”離散コサイン変換”が何をするものなのか、残念ながら理解できていないと思います。

> ですが,量子化する方法がよくわかりません.
> この値を使ってどうすればいいのでしょうか.

参考URL に、
> 画素ブロックの各要素に対して、量子化テーブルの同じ行列にある要素を使って量子化/逆量子化するため、
> 画素ブロックの各要素をSuv、量子化テーブルの各要素をQuvとすると、量子化・逆量子化変換式は次のようになります。

> 量子化 : Ruv = Suv / Quv
> 逆量子化 : Suv = Ruv X Quv

と、書かれています。
つまり、量子化テーブルの値で割り算をすればよいのです。

> URLから参考にしたものですが,変換すると右下から左上へと値が高くなっています.
> これは圧縮することで,左上の情報量が大きくなる方法ということはわかります.

まず、一つ指摘をしておきます。離散コサイン変換は、情報量を減らしません。つまり、この変換は情報の圧縮を行っているわけではないのです。しかも、

> 変換前は濃度あたりだと思うんですが,変換後はマイナスの値がついててさっぱりです.

だとすると、”離散コサイン変換”が何をするものなのか、残念ながら理解できていないと思います。

>...続きを読む

Qどんなプログラムになるのかわからないのでプログラムを作って頂けませんか

どんなプログラムになるのかわからないのでプログラムを作って頂けませんか?

3分間英単語タイプ練習プログラム作ってを5日以上にわけて計25回以上実行します。

1 単語ファイルword.txtを単語数未知として読み込むこと.3975単語含まれているが,単語数をプログラムに直接書き込むことや実行時に与えることは禁止.
2 単語は一様乱数を用いてランダムに呈示すること.プログラム完成後,プログラムの先頭に「srand((unsigned)time(NULL));」を付加しなさい.これにより,実行時刻によって乱数シードが変わるから,異なった単語(系列)が呈示されることになる.
3 各回の得点は「正答した単語の文字数の総和」とする.
4 毎回「月/日/年-時:分:秒,得点」を結果ファイルscore.csvに追加的に書き込む(追記モード)。秒と得点の間のカンマは半角にする必要があることを注意しておく.

Aベストアンサー

とりあえず使いそうな関数だけ書いておきます。あとは調べてください。

fgets, fseek

とりあえずこれだけで作れる・・・かな?word.txtの中身が分からないですが、一行につき一単語のみが書いてあると仮定するとfgetsをループすれば単語数は求められます。

単語をメモリに格納した方が速度は早くなるのでそのときはfgets, malloc, freeで作れるかと。

ポインタは分かっていますか?
ポインタ分かってないとちょっと厳しいかも・・・

がんばってください。

Q液晶、プラズマテレビともにブロック現象がありますか?

 薄型テレビの購入を検討しています。
 家電店で液晶テレビで細かい波の映像を見ていたときのことです。波がちらついて見えるのです。店員さんに言うとプラズマテレビでも見られますよと言ったので、見ると、同じように、細かくちらついていました。四角形の形をしていました。店員さんはブロック現象といってどちらのテレビにも現れることがあると説明してくれました。
 ブロック現象とはなんなのでしょうか。将来、改善される見込みはあるのでしょうか。

Aベストアンサー

Q/ブロック現象とはなんなのでしょうか。

A/本来はブロックノイズといいます。これは、非可逆圧縮(具体的には、離散コサイン変換をした場合)された映像で発生します。これは、デジタル放送やDVDなどがMPEG2-TSまたはPS方式で圧縮されているためです。
現象の発生は次のようなメカニズムによります。

基本的に映像は起点となる写真フレーム(Iピクチャ)から構成されその差分(移動した部分の情報/BおよびPピクチャ)を元に映像となります。
毎秒で最低30コマあるハイビジョンや標準放送の写真をその都度保存すれば情報量が膨大になりますからね。起点を一定間隔に置いた方が少ない情報で済むわけです。

しかし、それだけでは地上デジタルハイビジョンで15Mbps~20Mbps、標準放送相当のDVDで4Mbps~9,8Mbpsという小さな情報量に納めることはできません。
そこで、各フレーム(1コマ)をブロック単位で管理しそのブロックごとに不必要な情報を間引きつつ圧縮かける方式を採用しています。
これによって、より小さなデータ量で映像を再現できるのです。

ブロックノイズは、その過程で発生します。ただ、動きが少ないシーンなどでは、目立つことはありません。目立つようになるのは、動き情報が圧縮時のビットレート(一定時間当たりの情報量)を上回り全ての移動情報を保存できない場合です。具体的には、本来10Mbps(一秒あたり10メガビット)のデータ量がこの動きでは必ず必要というシーンで、8Mbpsしか帯域を確保できない場合には、2Mbps分のノイズとなるという具合です。

これ以外にも、MPEG2などの非可逆圧縮ではデジタルノイズ(圧縮に伴うざらついたノイズ及び直線がギザギザになるジャギー)やモスキートノイズ(煙のように画の稜線に表れるノイズ)などがあります。

これらは、基本的にはビットレート不足が生じれば必ず発生します。
そのため、デジタル放送、DVD、およびパソコンでのインターネット上の映像コンテンツでは多かれ少なかれ発生する物です。

まあ、技術の発達と共に動きの多いシーンをあらかじめ探し、その部分に優先的にデータ量を割り当てる技術(2パスエンコード)が発達していますが、そもそもDVDは標準放送で絶対的に必要な情報量が15Mbps以上であるのに対して、9,8Mbps。地上デジタルハイビジョン放送はハイビジョン放送で本来必要な25Mbpsより低い15~18Mbpsしかありませんから、この手のノイズは出ることになります。

Q/ブロック現象とはなんなのでしょうか。

A/本来はブロックノイズといいます。これは、非可逆圧縮(具体的には、離散コサイン変換をした場合)された映像で発生します。これは、デジタル放送やDVDなどがMPEG2-TSまたはPS方式で圧縮されているためです。
現象の発生は次のようなメカニズムによります。

基本的に映像は起点となる写真フレーム(Iピクチャ)から構成されその差分(移動した部分の情報/BおよびPピクチャ)を元に映像となります。
毎秒で最低30コマあるハイビジョンや標準放送の写真をその...続きを読む

Q離散フーリエ変換について

G(n/Nτ)= Σ[k=0->N-1] {τ*f(kτ)*e^(-i2πkn/N)}
上記の式は離散フーリエ変換の式らしいですが、
これを関数化しようとしてつまずいています。
どのように解釈すれば、関数化できるのでしょうか?
特に、複素数iがよくわかりません。
e^iが点を左に90度回転させるくらいはわかります。
e^(-i2πkn/N)を関数powで表現できなくて困っていますが、多分見当違いだとは思います。
フーリエ級数展開はわかります。
最終的にはFFTを行いたいのですが、
その理解の前に離散フーリエ変換ができないといけないと思っています。
よろしくお願いします。

void GraphClass::ScatteredFourierConvert()
{
/*
N-1
G(n/Nτ)= Σ {τ*f(kτ)*e^(-i2πkn/N)}
k=0
k=何番目の値か?
τ=値を読んだ間隔
N=値を読んだ数
*/
int Tau=10;
int N=RangeSize.cx*2/Tau;
double Sum=0;
double e=2.7182818;
for(int k=0;k<N-1;k++)
{
Sum+=Tau*Data[k*Tau]*pow(e,-i*2*PI*k*n/N);
}
}

G(n/Nτ)= Σ[k=0->N-1] {τ*f(kτ)*e^(-i2πkn/N)}
上記の式は離散フーリエ変換の式らしいですが、
これを関数化しようとしてつまずいています。
どのように解釈すれば、関数化できるのでしょうか?
特に、複素数iがよくわかりません。
e^iが点を左に90度回転させるくらいはわかります。
e^(-i2πkn/N)を関数powで表現できなくて困っていますが、多分見当違いだとは思います。
フーリエ級数展開はわかります。
最終的にはFFTを行いたいのですが、
その理解の前に離散フーリエ変換ができないといけないと思って...続きを読む

Aベストアンサー

その式の「eのべき」の部分は、複素数を実部と虚部に分けて書くとsinとcosで表すことができます。

プログラミング向けの参考書であれば必ず書いてあります。また、「フーリエ変換 sin cos」で検索すると参考になるページがたくさん出てきます。

がんばってください。

#「離散フーリエ変換」はDiscrete Fourier Transformと表現するのが一般的です

Q男子マラソン中継での頻繁なブロックノイズについて

こんにちは。
今、NHKで男子マラソンの中継を見ていますが、しばしば、映像にブロックノイズが発生しています。
会場の音声は途切れていますが、解説の声は普通に聞こえてくるので、テレビの呼称は考えられません。
いったいどうしたのでしょうか?
宇宙の衛星の調子が悪いのでしょうか。それともロンドンの中継車がおかしいのでしょうか。

ご回答お願いします。

Aベストアンサー

男子マラソンはあまりちゃんと見てませんでしたが、1週間前の女子は見てました。そのときも同じでしたね。

どうやら、橋の下?のようなところを中継車が通ると映像が固まったりしているようでしたので、中継車からの電波状態が悪かっただけじゃないかと思いますけども。

Qコード変換(漢字)のサンプルプログラム

始めまして!
困っています、御力添えをお願いします。
UNIX(SouOS5.8)でのコード変換(SJIS→EUC、EUC→SJIS)のコーディング(サンプルソース:C言語)をどなたか教えて頂けないでしょうか?
お願いします。

Aベストアンサー

下記URL参照。

参考URL:http://www-cms.phys.s.u-tokyo.ac.jp/~naoki/CIPINTRO/CCGI/kanjicod.html


人気Q&Aランキング