0

理论上使用 turbojpeg 更快,但我的测试结果恰恰相反。结果:

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

使用 OpenCV imencode:38.78 毫秒

使用涡轮解压:87.5 毫秒

以下是我的代码:

// 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;
}

这是主要功能

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 被官方证明要快 2 到 6 倍。 https://libjpeg-turbo.org/About/Performance

4

0 回答 0