0

I have developed a program in C++ that works in 2 major steps :

  • extract frames from a video with ffmpeg and convert them to jpeg ffmpeg -i videofile.mp4 -q:v 1 -r desired_framerate tmp_04%d.jpeg

  • create a multiframe Dicom file from those jpeg images via DCMTK

    //Example for one image
    
    // Get the n-th image
    QFile* imageFile = new QFile("Path/To/Image");
    
    // Read the image inside a byte array
    QByteArray * ba = new QByteArray();
    imageFile->open(QIODevice::ReadOnly);
    *ba = imageFile->readAll();
    
    // Insert the byte array in the Dicom file
    cond = jpegPixelItem->putUint8Array(reinterpret_cast<Uint8 *>(ba->data()), ba->size());
    
    // Rinse and repeat
    

It works well and can be displayed on most viewers but some complain about the Transfer Syntax being wrong. As of now, I'm using the "JPEGLossless:Non-hierarchical-1stOrderPrediction" but It seems some viewers can't read my Dicom file unless I change the Transfer Syntax to "JPEG Baseline (Process 1)" which is a lossy Transfer Syntax.

I assume the problem comes from the first step of the program with ffmpeg that might be creating lossy JPEG images but I'm not sure because I'm using the "best" q:v scale as I've seen in other posts on the subject.

Therefore, my 2 main questions are:

  • why do some viewers have no problems displaying the dicom file whereas some others can't?
  • is there any way to obtain lossless JPEG images from a ffmpeg command?
genpfault
  • 51,148
  • 11
  • 85
  • 139

1 Answers1

0

why do some viewers have no problems displaying the dicom file whereas some others can't ?

Probably because they catch the inconsistency between the TransferSyntaxUID in the DICOM header and the encapsulated JPEG data which is lossy JPEG.

is there any way to obtain lossless JPEG images from a ffmpeg command ?

AFAIK there is no way to guarantee mathematically lossless compression with the frame extraction of ffmpeg. But with DCMTK you could convert the resulting DICOM image to other formats. The command line tool dcmdjpeg can be used directly or serve as an example how to extend your code to do that.

Although it cannot be technically verified, I advise against pretending the image being losslessly encoded. The MPEG stream does have a lossy compression.

If you store the DICOM image as lossless JPEG, I strongly recommend to set Lossy Image Compression (0028,2110) to "01" to avoid repeated lossy compression. See the tag desciption in DICOM

Markus Sabin
  • 3,916
  • 14
  • 32
  • Thanks a lot for this clear explanation. I think dcmdjpeg is a false good idea though, because the output transfer syntax are always Little/BigEndian and would require yet another conversion to obtain the precious JPEGLossless Transfer Syntax. Using a different tool than ffmpeg to convert a video to *n* images seems to be the most efficient way after reading your answer. – PizzaPasNette May 12 '23 at 13:30
  • It is possible to control the quality factor of the extracted frames in ffmpeg and achieve visually lossless quality. So I do not see what is wrong with it, I actually find your frame extraction method quite smart. I do not understand why you are so keen on writing JPEG lossless. Quality loss _is_ in the image already from the MPEG compression. So IMHO the easiest way of moving forward is writing the correct transfer syntax UID to the DICOM header. – Markus Sabin May 12 '23 at 14:01