how to add text/annotation to a dicom image

All other questions regarding DCMTK

Moderator: Moderator Team

Post Reply
Message
Author
maxim.titov
Posts: 2
Joined: Fri, 2023-04-21, 13:43

how to add text/annotation to a dicom image

#1 Post by maxim.titov »

Hi colleagues, need help. I want to add text on a dicom image. How can this be done? Example of text output Image
According to the examples found https://support.dcmtk.org/redmine/proje ... quenceItem, I tried to come up with something, but got confused in the tags. There is no text output on the image

Code: Select all

#include "dcmtk/config/osconfig.h" 
#include "dcmtk/dcmdata/dctk.h" 

#define PRIVATE_CREATOR_NAME "Your Company Name" 
#define PRIVATE_CREATOR_TAG  0x0029, 0x0010
#define PRV_PrivateCreator   DcmTag(PRIVATE_CREATOR_TAG)

int main(int argc, char *argv[]) 
{
    DcmFileFormat fileformat;
    if (fileformat.loadFile("test.dcm").good())
    {
        DcmItem *item = NULL;
        DcmDataset *dataset = fileformat.getDataset();
        if (dataset->findOrCreateSequenceItem(DCM_GraphicAnnotationSequence, item, -2 /* append */).good())
        {
            item->putAndInsertString(PRV_PrivateCreator/*a new tag, as an example*/, PRIVATE_CREATOR_NAME);
            item->putAndInsertString(DCM_UnformattedTextValue, "output message");
        }
        DcmItem *i = NULL;
        if(dataset->findOrCreateSequenceItem(DCM_BoundingBoxBottomRightHandCorner, i, -2).good())
        {
            i->putAndInsertString(DCM_UnformattedTextValue, "output message");
            i->putAndInsertUint16(DCM_Rows, 10);
            i->putAndInsertUint16(DCM_Columns, 10);
        }
        fileformat.saveFile("test_out.dcm");
    }
    return 0;
}
Or maybe there are other options for how to do it. Thank you in advance!

Michael Onken
DCMTK Developer
Posts: 2048
Joined: Fri, 2004-11-05, 13:47
Location: Oldenburg, Germany
Contact:

Re: how to add text/annotation to a dicom image

#2 Post by Michael Onken »

Hi,

my colleagues may correct me but I don't think we have any functionality to burn text into existing images.

Usually, this also not what should be done when you want to annotate images. Instead of copying the image and burning text into it one usually uses so called Grayscale Softcopy Presentation State Objects (GSPS) which just contain the annotations and reference the original image. A viewer would open the image and applies the Presentation Context to it to display the annotations. GSPS objects can do a lot more than just showing text, including rotation, zoom, drawing rectangles, circles and so on. The DICOMscope demo vieweris based on DCMTK + extra java code that demonstrates this. Within DCMTK the dcmpstat library offers a dedicated API for working with GSPS objects.

If you really want to burn text/drawings into an existing image, I think the easiest way is to get the pixel data from the DICOM file, and then use another library that is specialized to draw text on raster images, then write the pixel data back to DICOM and save it. Maybe something like the Freetype library might help, but I am just guessing, it is just something that pops up in my mind when I hear text drawing. Note that extracting and writing back the pixel data sounds easy but you must consider that the raw pixel data is not what is shown on the screen, but must undergo some grayscale value transformations that can be defined in the file.

Best regards,
Michael

maxim.titov
Posts: 2
Joined: Fri, 2023-04-21, 13:43

Re: how to add text/annotation to a dicom image

#3 Post by maxim.titov »

I'm sorry, but I'm going to reformulate the question a bit, since I decided to choose a different approach, using opencv. That's the problem, I'm trying to add the image I created via opencv to the 60xx tags, but the image output is a little strange. I have no idea how to fix it. I was prompted that for the DCM_OverlayData tag, you need to transfer the image pixel by pixel, how to do this in the methods of the dcmtk libraries, I did not find anything similar, except create6xxx3000OverlayData, only this method does not work. How do I transfer an image to DCM_OverlayData?
Image
there should be text on top of the image, but it outputs some strips

Code: Select all

#include "dcmtk/dcmdata/dcfilefo.h"
#include "dcmtk/dcmdata/dcdeftag.h"
#include "dcmtk/dcmdata/dcuid.h"
#include <string>
#include <memory>
#include <cstring>
#include "dcmtk/dcmimgle/dcmimage.h"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/opencv.hpp> 
#include "Base64.h"
#include <vector>

using namespace cv;
using namespace std;

int main(int argc, char *argv[]) 
{
    DcmFileFormat dicom, test;
    if (dicom.loadFile("test.dcm").bad())
        throw runtime_error("don't open DicomFile\n");
    DcmDataset *d = dicom.getDataset();

    E_TransferSyntax xfer = d->getOriginalXfer();
    if (xfer == EXS_Unknown)
        xfer = EXS_LittleEndianExplicit;

    shared_ptr<DicomImage> dimage = make_shared<DicomImage>(d, xfer, CIF_NeverAccessEmbeddedOverlays);
    if (not dimage or (dimage->getStatus() != EIS_Normal))
        throw runtime_error("don't create DicomImage\n");

    string str = "Text in Images";
    Mat mat(30, str.length() * 11, CV_8U, Scalar(0, 0, 0));
    // normalize(mat, mat, 0, 255, NORM_MINMAX);    

    Point text_position(10, 20);//Declaring the text position//
    double font_size = 0.5;//Declaring the font size//
    Scalar font_Color(255, 255, 255);//Declaring the color of the font//
    int font_weight = 1;//Declaring the font weight//
    putText(mat, str.c_str(), text_position, FONT_HERSHEY_COMPLEX, font_size, font_Color, font_weight);//Putting the text in the matrix//

    /*vector<uchar> buf;
    string encoded_png;
    cv::imencode(".png", mat, buf);
    auto base64_png = reinterpret_cast<const unsigned char*>(buf.data());
    encoded_png = "data:image/jpeg;base64," + base64_encode(base64_png, buf.size());*/

    {
        const Sint16 arr[] = {1, 1};
        if (
            !d->putAndInsertUint16(DCM_OverlayRows, dimage->getHeight()).good() ||
            !d->putAndInsertUint16(DCM_OverlayColumns, dimage->getWidth()).good() ||
            !d->putAndInsertString(DCM_OverlayDescription, "additional information").good() ||
            !d->putAndInsertString(DCM_OverlayType, "G").good() ||
            !d->putAndInsertString(DCM_NumberOfFramesInOverlay, "1").good() ||
            !d->putAndInsertSint16Array(DCM_OverlayOrigin, arr, 2).good() ||
            !d->putAndInsertUint16(DCM_ImageFrameOrigin, 1).good() ||
            !d->putAndInsertUint16(DCM_OverlayBitsAllocated, 16).good() ||
            !d->putAndInsertUint16(DCM_OverlayBitPosition, 15).good() ||
            !d->putAndInsertUint8Array(DCM_OverlayData, (const Uint8 *)mat.data, static_cast<size_t>(mat.rows * mat.cols * mat.channels())).good())
            throw runtime_error("Can't get Dicom image\n");

        dicom.saveFile("out.dcm", xfer);
    }

    return 0;
}

Marco Eichelberg
OFFIS DICOM Team
OFFIS DICOM Team
Posts: 1437
Joined: Tue, 2004-11-02, 17:22
Location: Oldenburg, Germany
Contact:

Re: how to add text/annotation to a dicom image

#4 Post by Marco Eichelberg »

The overlay data should be a black/white bitmap, with one bit per pixel (equivalent to a DICOM image with Bits Allocated=1, Bits Stored=1, High Bit=0) and the same size as the main image.

J. Riesmeier
DCMTK Developer
Posts: 2501
Joined: Tue, 2011-05-03, 14:38
Location: Oldenburg, Germany
Contact:

Re: how to add text/annotation to a dicom image

#5 Post by J. Riesmeier »

It is not required that the overlay planes have the same size (rows and columns) as the image (pixel data).

Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Google [Bot] and 1 guest