0

Using turbojpeg is theoretically faster, but my tests showed the opposite. The result:

the size of jpg: 5040*5216
opencv:  4.2.0
quailty : 100
sample: 4:2:0
use fastdct

using OpenCV imencode: 38.78 ms

using turbo decompress: 87.5 ms

Following is my code:

// support jpg to bmp/ppm/pgm
bool jpg2bmp_turbo(char * jpg_file_path, char * bmp_dst_path, int height, int width)
{
  if (height == 0) return false;
  tjscalingfactor scalingFactor = { 1, 1 };
  int flags = TJFLAG_FASTDCT;
  FILE *jpegFile = NULL;
  unsigned char *imgBuf = NULL, *jpegBuf = NULL;
  int pixelFormat = TJPF_UNKNOWN;
  tjhandle tjInstance = NULL;
  long size;
  int inSubsamp, inColorspace;
  unsigned long jpegSize;

  /* Read the JPEG file into memory. */
  jpegFile = fopen(jpg_file_path, "rb");
  fseek(jpegFile, 0, SEEK_END); 
  size = ftell(jpegFile);
  fseek(jpegFile, 0, SEEK_SET);
  
  jpegSize = (unsigned long)size;
  jpegBuf = (unsigned char *)tjAlloc(jpegSize);
  fread(jpegBuf, jpegSize, 1, jpegFile);
  tjInstance = tjInitDecompress();
  pixelFormat = TJPF_BGRX;
  imgBuf = (unsigned char *)tjAlloc(width * height * tjPixelSize[pixelFormat]);
  tjDecompressHeader3(tjInstance, jpegBuf, jpegSize, &width, &height,
    &inSubsamp, &inColorspace);

  std::chrono::time_point<std::chrono::steady_clock> start, end;
  start = std::chrono::steady_clock::now();
  
  tjDecompress2(tjInstance, jpegBuf, jpegSize, imgBuf, width, 0, height,
    pixelFormat, flags);
  end = std::chrono::steady_clock::now();
  std::chrono::duration<double, std::milli> elapsed_time = end - start;
  std::cout << "turbo uncompress jpg to bmp: " << elapsed_time.count() << std::endl;

  /* Output image */
  tjSaveImage(bmp_dst_path, imgBuf, width, 0, height, pixelFormat, 0);

  tjFree(imgBuf);
  tjDestroy(tjInstance);
  tjFree(jpegBuf);
  fclose(jpegFile);
  return true;
}

Here's the main function

int main()
{
  std::chrono::time_point<std::chrono::steady_clock> start, end;
  std::chrono::duration<double, std::milli> elapsed_time;
  std::vector<int> param(2);
 
  // turbo jpg to bmp/ppm/pgm
  char jpgfile_src[] = "/test_data/input/map.jpg";
  char bmpfile_dst[] = "/test_data/output/jpg_bmp_map_turbo.bmp";
  jpg2bmp_turbo(jpgfile_src, bmpfile_dst, 5216, 5040);

  // opencv jpg to bmp
  std::string jpgfile = "/test_data/input/map.jpg";
  cv::Mat cv_jpg = cv::imread(jpgfile, cv::IMREAD_UNCHANGED);
  std::vector<uchar> jpgbuffer;
  start = std::chrono::steady_clock::now();
  cv::imencode(".bmp", cv_jpg, jpgbuffer, std::vector<int>());
  end = std::chrono::steady_clock::now();
  elapsed_time = end - start;
  std::cout << "opencv encode jpg to bmp: " << elapsed_time.count() << std::endl;

  return 0;
}

Libjpeg-turbo is officially shown to be 2 to 6 times faster. https://libjpeg-turbo.org/About/Performance

kiner_shah
  • 3,939
  • 7
  • 23
  • 37
xf Li
  • 11
  • The page does not mentions opencv, so why do you think opencv should be slower? – gerum Nov 10 '21 at 08:00
  • OpenCV has libjpeg-turbo among other stuff in its 3rdparty dependencies https://github.com/opencv/opencv/tree/master/3rdparty Perhaps for years. Your measured differences likely come from differences in compiling options or the like. – Öö Tiib Nov 10 '21 at 08:17
  • Maybe your hardware has an acceleration for jpeg decompression that is used by opencv – Micka Nov 10 '21 at 08:36
  • Why are you comparing encoding vs. decoding? Try opencv imdecode instead – Micka Nov 10 '21 at 08:40
  • 2
    Your process is completely wrong. imread already decodes the image and gives basically a bitmap, so your imencode to .bmp does not convert from jpeg to bmp but from bgr24 to bmp – Micka Nov 10 '21 at 08:43
  • Hi Micka, Since I wanted to compare the efficiency of converting JPG to BMP with TurboJPEG and OpencV for image format conversion, I didn't compare Encode and decode. Thank you very much for your advice to let me know more about the implementation of OpencV, but I did not find an API in OpencV that can directly convert JPG to BMP, and only found a way to convert it through cv::Mat. How can I get the exact time when OpencV will convert images directly – xf Li Nov 10 '21 at 12:30

0 Answers0