public void CvDct(ref Mat DST, Mat SRC, int N) { Mat dct, idct; Mat dct2, dct3; int width = SRC.Width;//N; int height = SRC.Height;//N; DST = SRC.Clone(); //DCT,IDCT用の行列作成(double) dct = new Mat(height, width, MatType.CV_64FC1); idct = new Mat(height, width, MatType.CV_64FC1); dct2 = new Mat(height, width, MatType.CV_64FC1); dct3 = new Mat(height, width, MatType.CV_64FC1); var indexer_DST = new MatOfByte3(DST).GetIndexer(); var indexer_dct = new MatOfDouble3(dct).GetIndexer(); //行列dctに画像データをコピー //double fcos; for (int x = 0; x < width; x++) for (int y = 0; y < height; y++) { Vec3d color = indexer_dct[y, x]; color.Item0= indexer_DST[y, x].Item0 / 256.0; indexer_dct[y,x] = color; } //DCT…dctをコサイン変換してdct2を作成します Cv2.Dct(dct, dct2, DctFlags.None); //dct2をDenomで割りdct3を作成します PerformDenom(ref dct3, dct2); //IDCT…dct3を逆コサイン変換します Cv2.Dct(dct3, idct, DctFlags.Inverse); var indexer_idct = new MatOfDouble3(idct).GetIndexer(); //逆変換用画像にデータをコピー for (int x = 0; x < width; x++) for (int y = 0; y < height; y++) { Vec3b color = indexer_DST[y, x]; color.Item0= (byte)(indexer_idct[y,x].Item0 * 256.0); indexer_DST[y,x]=color; } ////正規化 //double min, max; //min = 4000000000000; //max = -4000000000000; //double offset = 0.0; ////輝度値の最大と最小を取得 //DST.MinMaxIdx(out min, out max); ////for (int x = 0; x < width; x++) //// for (int y = 0; y < height; y++) //// { //// double data = indexer_DST[y,x].Item0; //// if (data < min) min = data; //// if (data > max) max = data; //// } //for (int x = 0; x < width; x++) // for (int y = 0; y < height; y++) // { // Vec3b color = indexer_DST[y, x]; // double data = indexer_DST[y, x].Item0; // if (data < min + offset) data = min + offset; // color.Item0 = (byte)( (((data / (max - min + offset))) * 255.0) - (((min + offset) / (max - min + offset)) * 255.0) ); // indexer_DST[y,x] = color; // } ////DST = idct.Clone(); //行列メモリを開放します dct.Dispose(); dct2.Dispose(); dct3.Dispose(); idct.Dispose(); indexer_dct = null; indexer_DST = null; indexer_idct = null; }
private void PerformDenom(ref Mat DST, Mat SRC) { double PI = 3.1416; int width = SRC.Width; int height = SRC.Height; //XとYを準備 double[,] meshX = new double[height,width]; double[,] meshY = new double[height,width]; double[,] denom = new double[height,width]; DST = SRC.Clone(); var indexer = new MatOfDouble3(DST).GetIndexer(); //メッシュグリッドの作成 for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) { meshX[y, x] = x; meshY[y, x] = y; } //固有値計算 for (int y = 0; y < height; y++) for (int x = 0;x < width; x++) denom[y, x] = (2.0 * Math.Cos(PI * (double)x / ((double)width)) - 2.0) + (2.0 * Math.Cos(PI * (double)y / ((double)height)) - 2.0); //計算 for (int x = 0; x < width; x++) for (int y = 0; y < height; y++) { //data_d[j][i] = data_s[j][i] / denom[j][i]; Vec3d color = indexer[y, x]; color.Item0 = indexer[y, x].Item0; //ゼロ割防止 if (!(x == 0 && y == 0)) color.Item0 = color.Item0 / denom[y, x]; indexer[y, x] = color; } indexer = null; }