c++ - JPEG Compression using OpenCV -


i'm trying perform basic jpeg compression (dct + quantization + idct) using opencv not using entropy-encoding/huffman-coding. problem after decompress compressed image, not close in appearance original one.

i'm following these tutorials:

basic jpeg compressing/decompressing simulation

basic jpeg compression using opencv

following 3 images (original, compressed , decompressed images): original image

compressed image

final image

i'm using following matrix luminance , chrominance:

double dataluminance[8][8] = {     {16, 11, 10, 16, 24, 40, 51, 61},     {12, 12, 14, 19, 26, 58, 60, 55},     {14, 13, 16, 24, 40, 57, 69, 56},     {14, 17, 22, 29, 51, 87, 80, 62},     {18, 22, 37, 56, 68, 109, 103, 77},     {24, 35, 55, 64, 81, 104, 113, 92},     {49, 64, 78, 87, 103, 121, 120, 101},     {72, 92, 95, 98, 112, 100, 103, 99} };  double datachrominance[8][8] = {     {17, 18, 24, 27, 99, 99, 99, 99},     {18, 21, 26, 66, 99, 99, 99, 99},     {24, 26, 56, 99, 99, 99, 99, 99},     {47, 66, 99, 99, 99, 99, 99, 99},     {99, 99, 99, 99, 99, 99, 99, 99},     {99, 99, 99, 99, 99, 99, 99, 99},     {99, 99, 99, 99, 99, 99, 99, 99},     {99, 99, 99, 99, 99, 99, 99, 99} }; 

// edit 1: @micka told problem of using imread/imwrite, edited code use compressed image directly program.

the compression method is:

void imagecompression::compression(){ // getting original image size int height = imgoriginal.size().height; int width = imgoriginal.size().width;  // converting image color mat imgcolorconverted; cvtcolor(imgoriginal, imgcolorconverted, cv_bgr2ycrcb);  // transforming 2d array in image matrix mat luminance = mat(8,8, cv_64fc1, &dataluminance); mat chrominance = mat(8,8, cv_64fc1, &datachrominance);  cout << "luminance: " << luminance << endl << endl; cout << "chrominance" << chrominance << endl << endl;  // splitting image 3 planes vector<mat> planes; split(imgcolorconverted, planes);  // downsampling chrominance // resizing 1/4 of original image resize(planes[1], planes[1], size(width/2, height/2)); resize(planes[2], planes[2], size(width/2, height/2));  // resizing original image size resize(planes[1], planes[1], size(width, height)); resize(planes[2], planes[2], size(width, height));  // dividing image in blocks 8x8 ( int = 0; < height; i+=8 ){     for( int j = 0; j < width; j+=8 ){         // each plane         for( int plane = 0; plane < imgcolorconverted.channels(); plane++ ){              // creating block             mat block = planes[plane](rect(j, i, 8, 8));              // converting block float             block.convertto( block, cv_64fc1 );              // subtracting block 128             subtract( block, 128.0, block );              // dct             dct( block, block );              // applying quantization             if( plane == 0 ){                 divide( block, luminance, block );             }             else {                 divide( block, chrominance, block );             }              // converting unsigned int             block.convertto( block, cv_8uc1 );              // copying block original image             block.copyto( planes[plane](rect(j, i, 8, 8)) );         }     } }  merge( planes, finalimage ); } 

and decompression method:

imagecompression::decompression{ // getting size of image int height = finalimage.size().height; int width = finalimage.size().width;  // transforming 2d array in image matrix mat luminance = mat(8,8, cv_64fc1, &dataluminance); mat chrominance = mat(8,8, cv_64fc1, &datachrominance);  // splitting image 3 planes vector<mat> planes; split(finalimage, planes);  // dividing image in blocks 8x8 ( int = 0; < height; i+=8 ){     for( int j = 0; j < width; j+=8 ){         // each plane         for( int plane = 0; plane < finalimage.channels(); plane++ ){              // creating block             mat block = planes[plane](rect(j, i, 8, 8));              // converting block float             block.convertto( block, cv_64fc1 );              // applying dequantization             if( plane == 0 ){                 multiply( block, luminance, block );             }             else {                 multiply( block, chrominance, block );             }              // idct             idct( block, block );              // adding 128 block             add( block, 128.0, block );              // converting unsigned int             block.convertto( block, cv_8uc1 );              // copying block original image             block.copyto( planes[plane](rect(j, i, 8, 8)) );         }     } }  merge(planes, finalimage); cvtcolor( finalimage, finalimage, cv_ycrcb2bgr );  imshow("decompressed image", finalimage); waitkey(0); imwrite(".../finalresult.jpg", finalimage); } 

does have idea of why i'm getting resulting image?

thank you.

you need add 128 block before converting unsigned int , subtract again in decompression.

            add(block, 128.0, block);              // converting unsigned int             block.convertto(block, cv_8uc1); 

.

        // converting block float         block.convertto(block, cv_64fc1);          subtract(block, 128.0, block); 

Comments

Popular posts from this blog

css - SVG using textPath a symbol not rendering in Firefox -

Java 8 + Maven Javadoc plugin: Error fetching URL -

node.js - How to abort query on demand using Neo4j drivers -