Ask Your Question

Why cv:: encode gives similar size of output buffer for bgr8 and mono8 images?

asked 2020-07-18 19:19:31 -0500

JeyP4 gravatar image

updated 2020-07-19 10:59:13 -0500


I notice 4.1 MB/s @50fps 1280x720 bgr8.

.....and 3.7 MB/s @50fps 1280x720 mono8.

Above test performed with same camera looking at same scene in same ambient light conditions.

I was expecting around 3 times less bandwidth consumption for grayscale.

jai@jai:~$ opencv_version
jai@jai:~$ opencv_version -v | grep jpeg
JPEG:                        /usr/lib/x86_64-linux-gnu/ (ver 80)
jai@jai:~$ ldconfig -p | grep jpeg (libc6,x86-64) => /lib/x86_64-linux-gnu/ (libc6,x86-64) => /lib/x86_64-linux-gnu/ (libc6,x86-64) => /lib/x86_64-linux-gnu/ (libc6,x86-64) => /lib/x86_64-linux-gnu/ (libc6,x86-64) => /lib/x86_64-linux-gnu/ (libc6,x86-64) => /lib/x86_64-linux-gnu/ (libc6,x86-64) => /lib/x86_64-linux-gnu/ (libc6,x86-64) => /lib/x86_64-linux-gnu/ (libc6,x86-64) => /lib/x86_64-linux-gnu/ (libc6,x86-64) => /lib/x86_64-linux-gnu/

FYI: I am using ros::compressed_image_transport plugin. I checked on opencv4 and opencv3.4.9.

I thought to try the same thing with simple C++ program and find the same pattern again. Below is my simple C++ program and its output.


#include <iostream>
#include <vector>
#include <opencv2/imgproc/imgproc.hpp>    // gray
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
using namespace std;

int main( int argc, char** argv )
    Mat im, imGray;
    im = imread( "lenna.png", IMREAD_COLOR ); // Read the file
    imGray = imread( "lenna.png", IMREAD_GRAYSCALE ); // Read the file
    if( im.empty() )                      // Check for invalid input
        cout <<  "Could not open or find the image" << std::endl ;
        return -1;

        std::vector<int> params;
        params.resize(9, 0);
        params[0] = cv::IMWRITE_JPEG_QUALITY;
        params[1] = 80;
        params[2] = cv::IMWRITE_JPEG_PROGRESSIVE;
        params[3] = 0;
        params[4] = cv::IMWRITE_JPEG_OPTIMIZE;
        params[5] = 0;
        params[6] = cv::IMWRITE_JPEG_RST_INTERVAL;
        params[7] = 0;

        std::vector< uchar > buffer, bufferGray;

        if (cv::imencode(".jpeg", im, buffer, params)) {

        float cRatio = (float)(im.rows * im.cols * im.elemSize())
            / (float)buffer.size();
        printf("BGR8 Jpeg image size: %lu KB,  Compression Ratio: 1:%.2f\n", buffer.size()/1024, cRatio);
        imwrite("im.jpg", im, params);
        printf("cv::imencode (jpeg) failed on bgr8 image\n");

    if (cv::imencode(".jpeg", imGray, bufferGray, params)) {

        float cRatio = (float)(imGray.rows * imGray.cols * imGray.elemSize())
            / (float)bufferGray.size();
        printf("MONO8 Jpeg image size: %lu KB,  Compression Ratio: 1:%.2f\n\n", bufferGray.size()/1024, cRatio);
        imwrite("imGray.jpg", imGray, params);

        printf("cv::imencode (jpeg) failed on mono8 image\n");

    imshow( "BGR8", im );
    imshow( "MONO8", imGray );
   return 0;

image description

My concern is the low compression ratio for gray-scale.

edit retag flag offensive close merge delete


ros::compressed_image_transport plugin

you expect us to know, what that is ? (or that anyone here can reproduce your findings ?)

maybe it's a good idea to write a simple test prog, that just loads a single image and saves it again, and show us here

berak gravatar imageberak ( 2020-07-19 02:06:33 -0500 )edit

Thanks @berak I follow your suggestion and explicitly present a simple program to reproduce my findings. (Appended my question)

JeyP4 gravatar imageJeyP4 ( 2020-07-19 06:52:38 -0500 )edit

1 answer

Sort by » oldest newest most voted

answered 2020-07-20 07:32:26 -0500

berak gravatar image

the effect is specific to jpg compression. quoting from here:

  1. The representation of the colors in the image is converted to Y′CBCR, consisting of one luma component (Y'), representing brightness, and two chroma components, (CB and CR), representing color. This step is sometimes skipped.
  2. The resolution of the chroma data is reduced, usually by a factor of 2 or 3. This reflects the fact that the eye is less sensitive to fine color details than to fine brightness details.

so, the contribution from Y takes the main chunk in the compressed image (it's almost the same as the grayscale)

(and btw, png encoding will have same (expected) compresssion ratio for bgr and gray)

edit flag offensive delete link more
Login/Signup to Answer

Question Tools

1 follower


Asked: 2020-07-18 19:19:31 -0500

Seen: 46 times

Last updated: Jul 20