private void aula2ToolStripMenuItem_Click(object sender, EventArgs e) { if (img == null) { return; } //copy Undo Image imgUndo = img.Copy(); Image <Gray, float> matrix = ImageClass.GetQuantificationMatrix(true, 100); Image <Ycc, float> blockYCC; //TableForm.ShowTableStatic(matrix,"Matriz de Quantificacao"); Image <Ycc, float> imgYCC = img.Convert <Ycc, float>(); //Transformar o espaço de cor RGB para YCbCr // TODO subsampling //Para cada bloco de 8x8 pixéis, fazer: (Copy(new rectangle(...) ) ) int Yblocks = (int)Math.Ceiling(img.Height / 8.0); int Xblocks = (int)Math.Ceiling(img.Width / 8.0); for (int x = 0; x < Xblocks; x++) { for (int y = 0; y < Yblocks; y++) { Image <Gray, float> y1 = imgYCC[0].Copy(new Rectangle(x * 8, y * 8, 8, 8)); Image <Gray, float> Cr = imgYCC[1].Copy(new Rectangle(x * 8, y * 8, 8, 8)); Image <Gray, float> Cb = imgYCC[2].Copy(new Rectangle(x * 8, y * 8, 8, 8)); CvInvoke.cvDCT(y1, y1, CV_DCT_TYPE.CV_DXT_FORWARD);//cálculo da transformada de cossenos DCT CvInvoke.cvDCT(Cb, Cb, CV_DCT_TYPE.CV_DXT_FORWARD); CvInvoke.cvDCT(Cr, Cr, CV_DCT_TYPE.CV_DXT_FORWARD); CvInvoke.cvDiv(y1, matrix, y1, 1); // quantificação dos coeficientes CvInvoke.cvDiv(Cb, matrix, Cb, 1); CvInvoke.cvDiv(Cr, matrix, Cr, 1); ImageClass.myRound(y1); //arredondamento dos coeficientes ImageClass.myRound(Cb); ImageClass.myRound(Cr); // DESCOMPRESSÃO CvInvoke.cvMul(y1, matrix, y1, 1); // recuperação dos coeficientes (Mul) CvInvoke.cvMul(Cb, matrix, Cb, 1); CvInvoke.cvMul(Cr, matrix, Cr, 1); CvInvoke.cvDCT(y1, y1, CV_DCT_TYPE.CV_DXT_INVERSE);//cálculo da transformada inversa de cossenos iDCT ( CvInvoke.cvDCT(Cb, Cb, CV_DCT_TYPE.CV_DXT_INVERSE); CvInvoke.cvDCT(Cr, Cr, CV_DCT_TYPE.CV_DXT_INVERSE); imgYCC.ROI = new Rectangle(x * 8, y * 8, 8, 8); blockYCC = new Image <Ycc, float>(8, 8); CvInvoke.cvMerge(y1, Cr, Cb, IntPtr.Zero, blockYCC); blockYCC.CopyTo(imgYCC); imgYCC.ROI = Rectangle.Empty; } } Image <Bgr, byte> imgfinal = imgYCC.Convert <Bgr, float>().Convert <Bgr, byte>(); ShowIMG.ShowIMGStatic(img, imgfinal); }