SImpleITK incremental loading JAVA

I want to implement incremental reading/loading of dicom series with simpleitk in java.
The weasis viewer, radiant viewer and slicer viewer, when selecting the folder loads instantly and shows the first slice of the series. And as the series is loaded, it will allow access to the rest of the slices.
I don’t know what the best approach would be…
Is there a method for this? Maybe ResampleImageFilter? Or convert to byte[], modify and convert to Image again setting new Size?

edit: i find JoinSeriesImageFilter, possible solution??

this is my actual series reader:

private void loadFromLocalFolder() {
        this.reader = new ImageSeriesReader();
        VectorString dicomFilesNames = ImageSeriesReader.getGDCMSeriesFileNames(this.dicomSeriesFolderPath);
        this.reader.setFileNames(dicomFilesNames);
        this.reader.loadPrivateTagsOn();
        this.reader.metaDataDictionaryArrayUpdateOn();
        this.series = reader.execute();
    }

actual try using JoinSeriesImageFIlter results in: JoinSeriesImageFilter(000001EBD6C8F680): Inputs do not occupy the same physical space!

code:

private void loadFromLocalFolder() {
        this.reader = new ImageSeriesReader();
        VectorString dicomFilesNames = ImageSeriesReader.getGDCMSeriesFileNames(this.dicomSeriesFolderPath);
        this.reader.loadPrivateTagsOn();
        this.reader.metaDataDictionaryArrayUpdateOn();
        this.reader.setFileNames(new VectorString(Collections.singleton(dicomFilesNames.get(0))));
        this.series = reader.execute();
        dicomFilesNames.remove(0);
        Volume thisVolumeInstance = this;
        Runnable asyncLoading = () -> {
            int fileIndex = 0;
            JoinSeriesImageFilter filter = new JoinSeriesImageFilter();
            for (String filename : dicomFilesNames) {
                thisVolumeInstance.reader.setFileNames(new VectorString(Collections.singleton(dicomFilesNames.get(fileIndex))));
                Image fileToConcatenate = reader.execute();
                thisVolumeInstance.series = filter.execute(thisVolumeInstance.series, fileToConcatenate);
                fileIndex++;
            }
        };
        asyncLoading.run();
    }

Hello @Salu_Ramos,

In your context, combining multiple slices into a single volume, the JoinSeriesImageFilter expects a list of images and should be called once. In the code, you are calling the filter in a loop which is not the way it should be used.

1 Like

hmm that’s not what I want, what should I do? i want to create an image from a file and then start incrementing the layers one by one.

Hello @Salu_Ramos,

If you are reading the slices one by one and want to display them as such (2D axial slices), no need to combine them into a volume. Keep them as an ordered list of 2D images. When you need them as a volume, use the JoinSeries.

1 Like

Hi @zivy,

The intention is to be able to extract axial, sagittal, coronal, and oblique slices. So I really need to mount an Image.

OK, so you’ll need to maintain double the memory until you load all of the 2D slices.

Load the 2D slices into a list/container. Then JoinSeries on the contents of the container and display the resulting partial volume. You may want to do the Join operation only after loading k additional images, so not after every image. Once you load all 2D images and create the complete volume you can get rid of the 2D images.

I suspect this approach will slow things down considerably. Loading a 3D volume is fast, so not sure about the motivation to do this type of incremental loading while providing visual feedback to the user.

1 Like

Thanks for the help @zivy,

the motivation for this is that some dicom series can take up to 15 seconds to load in my setup, during this time the software freezes, while the viewers I mentioned load instantly.

That is very strange. Loading a (512, 512, 283) series takes less than 1sec on my laptop using this short Python snippet:

import SimpleITK as sitk

file_names = sitk.ImageSeriesReader.GetGDCMSeriesFileNames(".")
image = sitk.ReadImage(file_names)

Please try running this code on your data and see how long it takes. Not sure what could cause such a slow runtime, possibly you have a series with many more slices.

1 Like

i have a lot of dicom files here, let me show some example:

series 1 is 512x512x53 and takes 100ms to load
series 2 is 512x512x514 an takes 8000ms to load (by logic it would be approximately 970ms)

note that this is the measurement of ImageSeriesReader.Execute() execution time, not SimpleITK.ReadImage:

VectorString filenames = ImageSeriesReader.getGDCMSeriesFileNames(this.dicomSeriesFolderPath);
this.reader = new ImageSeriesReader();
this.reader.setFileNames(filenames)
long start = System.currentTimeMillis();
this.series = reader.execute();
long finish = System.currentTimeMillis();
System.out.println("time = " + (finish - start) + "ms");

The ReadImage just creates the reader internally and calls the execute method, so same as you are doing.

The difference in performance you are seeing is surprising (assuming here that you have enough RAM for the larger volume and we aren’t seeing the use of virtual memory, possibly some memory issue with the JVM, I’m really guessing here).

@blowekamp, @dzenanz, any ideas why there is such a difference between the expected and actual performance?

Could it be a RAM issue? 512^3 is 270 meg of RAM for 16 bit voxels. Maybe your computer is thrashing.

I would inspect a slice from each. Look at the DICOM tags, maybe check if there is compression enabled or something. Then I would time the reading of a single slice from each series.

my setup is:
ryzen 5 5500
gtx 1660 super
24gb ram 2400Mhz ddr4
2 hd 1 TB
1 ssd 256 GB
Windows 11

I started my project in python and my reader was taking the same amount of time to do this.
This example series consists of 549 files of approximately 220KB, that is 118MB.
This is one of the heaviest files I have here

output of loading timer:

image 0 takes 22ms
image 1 takes 19 ms
image 2 takes 20 ms
image 3 takes 20 ms
image 4 takes 19 ms
image 5 takes 20 ms
image 6 takes 20 ms
image 7 takes 19 ms
image 8 takes 21 ms
image 9 takes 20 ms
image 10 takes 18 ms
image 11 takes 17 ms
image 12 takes 18 ms
image 13 takes 19 ms
image 14 takes 18 ms
image 15 takes 20 ms
image 16 takes 18 ms
image 17 takes 19 ms
image 18 takes 18 ms
image 19 takes 18 ms
image 20 takes 17 ms
image 21 takes 19 ms
image 22 takes 18 ms
image 23 takes 18 ms
image 24 takes 18 ms
image 25 takes 18 ms
image 26 takes 17 ms
image 27 takes 19 ms
image 28 takes 18 ms
image 29 takes 18 ms
image 30 takes 21 ms
image 31 takes 20 ms
image 32 takes 21 ms
image 33 takes 20 ms
image 34 takes 19 ms
image 35 takes 18 ms
image 36 takes 18 ms
image 37 takes 20 ms
image 38 takes 19 ms
image 39 takes 19 ms
image 40 takes 17 ms
image 41 takes 18 ms
image 42 takes 19 ms
image 43 takes 18 ms
image 44 takes 18 ms
image 45 takes 20 ms
image 46 takes 19 ms
image 47 takes 19 ms
image 48 takes 18 ms
image 49 takes 19 ms
image 50 takes 18 ms
image 51 takes 19 ms
image 52 takes 18 ms
image 53 takes 18 ms
image 54 takes 19 ms
image 55 takes 17 ms
image 56 takes 20 ms
image 57 takes 19 ms
image 58 takes 19 ms
image 59 takes 19 ms
image 60 takes 18 ms
image 61 takes 19 ms
image 62 takes 18 ms
image 63 takes 17 ms
image 64 takes 18 ms
image 65 takes 18 ms
image 66 takes 19 ms
image 67 takes 20 ms
image 68 takes 20 ms
image 69 takes 19 ms
image 70 takes 20 ms
image 71 takes 20 ms
image 72 takes 18 ms
image 73 takes 18 ms
image 74 takes 19 ms
image 75 takes 18 ms
image 76 takes 17 ms
image 77 takes 19 ms
image 78 takes 16 ms
image 79 takes 18 ms
image 80 takes 17 ms
image 81 takes 19 ms
image 82 takes 18 ms
image 83 takes 18 ms
image 84 takes 19 ms
image 85 takes 18 ms
image 86 takes 19 ms
image 87 takes 18 ms
image 88 takes 19 ms
image 89 takes 17 ms
image 90 takes 19 ms
image 91 takes 18 ms
image 92 takes 18 ms
image 93 takes 18 ms
image 94 takes 19 ms
image 95 takes 19 ms
image 96 takes 19 ms
image 97 takes 19 ms
image 98 takes 18 ms
image 99 takes 19 ms
image 100 takes 18 ms
image 101 takes 18 ms
image 102 takes 17 ms
image 103 takes 18 ms
image 104 takes 18 ms
image 105 takes 17 ms
image 106 takes 18 ms
image 107 takes 17 ms
image 108 takes 17 ms
image 109 takes 16 ms
image 110 takes 18 ms
image 111 takes 20 ms
image 112 takes 18 ms
image 113 takes 18 ms
image 114 takes 18 ms
image 115 takes 19 ms
image 116 takes 18 ms
image 117 takes 18 ms
image 118 takes 18 ms
image 119 takes 18 ms
image 120 takes 18 ms
image 121 takes 17 ms
image 122 takes 17 ms
image 123 takes 18 ms
image 124 takes 17 ms
image 125 takes 17 ms
image 126 takes 18 ms
image 127 takes 19 ms
image 128 takes 20 ms
image 129 takes 18 ms
image 130 takes 19 ms
image 131 takes 18 ms
image 132 takes 19 ms
image 133 takes 18 ms
image 134 takes 18 ms
image 135 takes 17 ms
image 136 takes 18 ms
image 137 takes 17 ms
image 138 takes 19 ms
image 139 takes 18 ms
image 140 takes 19 ms
image 141 takes 19 ms
image 142 takes 19 ms
image 143 takes 19 ms
image 144 takes 19 ms
image 145 takes 17 ms
image 146 takes 19 ms
image 147 takes 17 ms
image 148 takes 18 ms
image 149 takes 18 ms
image 150 takes 19 ms
image 151 takes 17 ms
image 152 takes 17 ms
image 153 takes 19 ms
image 154 takes 18 ms
image 155 takes 19 ms
image 156 takes 19 ms
image 157 takes 20 ms
image 158 takes 19 ms
image 159 takes 18 ms
image 160 takes 19 ms
image 161 takes 18 ms
image 162 takes 17 ms
image 163 takes 18 ms
image 164 takes 18 ms
image 165 takes 17 ms
image 166 takes 18 ms
image 167 takes 18 ms
image 168 takes 19 ms
image 169 takes 17 ms
image 170 takes 19 ms
image 171 takes 19 ms
image 172 takes 20 ms
image 173 takes 21 ms
image 174 takes 21 ms
image 175 takes 20 ms
image 176 takes 20 ms
image 177 takes 19 ms
image 178 takes 18 ms
image 179 takes 18 ms
image 180 takes 18 ms
image 181 takes 17 ms
image 182 takes 19 ms
image 183 takes 17 ms
image 184 takes 19 ms
image 185 takes 20 ms
image 186 takes 19 ms
image 187 takes 20 ms
image 188 takes 20 ms
image 189 takes 21 ms
image 190 takes 20 ms
image 191 takes 20 ms
image 192 takes 18 ms
image 193 takes 19 ms
image 194 takes 20 ms
image 195 takes 19 ms
image 196 takes 19 ms
image 197 takes 20 ms
image 198 takes 18 ms
image 199 takes 20 ms
image 200 takes 20 ms
image 201 takes 19 ms
image 202 takes 18 ms
image 203 takes 20 ms
image 204 takes 18 ms
image 205 takes 19 ms
image 206 takes 18 ms
image 207 takes 18 ms
image 208 takes 18 ms
image 209 takes 18 ms
image 210 takes 18 ms
image 211 takes 19 ms
image 212 takes 19 ms
image 213 takes 18 ms
image 214 takes 20 ms
image 215 takes 19 ms
image 216 takes 18 ms
image 217 takes 20 ms
image 218 takes 18 ms
image 219 takes 18 ms
image 220 takes 18 ms
image 221 takes 17 ms
image 222 takes 18 ms
image 223 takes 18 ms
image 224 takes 19 ms
image 225 takes 19 ms
image 226 takes 22 ms
image 227 takes 21 ms
image 228 takes 21 ms
image 229 takes 22 ms
image 230 takes 22 ms
image 231 takes 21 ms
image 232 takes 23 ms
image 233 takes 20 ms
image 234 takes 21 ms
image 235 takes 21 ms
image 236 takes 23 ms
image 237 takes 22 ms
image 238 takes 21 ms
image 239 takes 23 ms
image 240 takes 22 ms
image 241 takes 18 ms
image 242 takes 19 ms
image 243 takes 18 ms
image 244 takes 18 ms
image 245 takes 20 ms
image 246 takes 19 ms
image 247 takes 20 ms
image 248 takes 19 ms
image 249 takes 18 ms
image 250 takes 20 ms
image 251 takes 20 ms
image 252 takes 21 ms
image 253 takes 21 ms
image 254 takes 21 ms
image 255 takes 22 ms
image 256 takes 22 ms
image 257 takes 20 ms
image 258 takes 19 ms
image 259 takes 21 ms
image 260 takes 20 ms
image 261 takes 20 ms
image 262 takes 20 ms
image 263 takes 19 ms
image 264 takes 20 ms
image 265 takes 20 ms
image 266 takes 19 ms
image 267 takes 22 ms
image 268 takes 22 ms
image 269 takes 23 ms
image 270 takes 21 ms
image 271 takes 22 ms
image 272 takes 19 ms
image 273 takes 18 ms
image 274 takes 20 ms
image 275 takes 21 ms
image 276 takes 20 ms
image 277 takes 20 ms
image 278 takes 18 ms
image 279 takes 20 ms
image 280 takes 19 ms
image 281 takes 21 ms
image 282 takes 21 ms
image 283 takes 21 ms
image 284 takes 20 ms
image 285 takes 22 ms
image 286 takes 22 ms
image 287 takes 21 ms
image 288 takes 21 ms
image 289 takes 23 ms
image 290 takes 22 ms
image 291 takes 24 ms
image 292 takes 18 ms
image 293 takes 20 ms
image 294 takes 23 ms
image 295 takes 20 ms
image 296 takes 22 ms
image 297 takes 22 ms
image 298 takes 24 ms
image 299 takes 23 ms
image 300 takes 24 ms
image 301 takes 20 ms
image 302 takes 18 ms
image 303 takes 20 ms
image 304 takes 20 ms
image 305 takes 20 ms
image 306 takes 19 ms
image 307 takes 18 ms
image 308 takes 20 ms
image 309 takes 21 ms
image 310 takes 21 ms
image 311 takes 25 ms
image 312 takes 26 ms
image 313 takes 24 ms
image 314 takes 36 ms
image 315 takes 25 ms
image 316 takes 21 ms
image 317 takes 22 ms
image 318 takes 19 ms
image 319 takes 22 ms
image 320 takes 23 ms
image 321 takes 20 ms
image 322 takes 26 ms
image 323 takes 24 ms
image 324 takes 23 ms
image 325 takes 22 ms
image 326 takes 23 ms
image 327 takes 21 ms
image 328 takes 21 ms
image 329 takes 20 ms
image 330 takes 21 ms
image 331 takes 21 ms
image 332 takes 20 ms
image 333 takes 22 ms
image 334 takes 20 ms
image 335 takes 22 ms
image 336 takes 23 ms
image 337 takes 23 ms
image 338 takes 24 ms
image 339 takes 25 ms
image 340 takes 24 ms
image 341 takes 20 ms
image 342 takes 21 ms
image 343 takes 27 ms
image 344 takes 22 ms
image 345 takes 23 ms
image 346 takes 21 ms
image 347 takes 21 ms
image 348 takes 21 ms
image 349 takes 23 ms
image 350 takes 27 ms
image 351 takes 26 ms
image 352 takes 23 ms
image 353 takes 27 ms
image 354 takes 21 ms
image 355 takes 20 ms
image 356 takes 23 ms
image 357 takes 19 ms
image 358 takes 20 ms
image 359 takes 19 ms
image 360 takes 20 ms
image 361 takes 21 ms
image 362 takes 19 ms
image 363 takes 23 ms
image 364 takes 24 ms
image 365 takes 23 ms
image 366 takes 23 ms
image 367 takes 21 ms
image 368 takes 21 ms
image 369 takes 19 ms
image 370 takes 19 ms
image 371 takes 19 ms
image 372 takes 18 ms
image 373 takes 20 ms
image 374 takes 20 ms
image 375 takes 19 ms
image 376 takes 23 ms
image 377 takes 22 ms
image 378 takes 21 ms
image 379 takes 21 ms
image 380 takes 22 ms
image 381 takes 23 ms
image 382 takes 19 ms
image 383 takes 20 ms
image 384 takes 20 ms
image 385 takes 19 ms
image 386 takes 19 ms
image 387 takes 21 ms
image 388 takes 20 ms
image 389 takes 19 ms
image 390 takes 19 ms
image 391 takes 17 ms
image 392 takes 19 ms
image 393 takes 23 ms
image 394 takes 23 ms
image 395 takes 24 ms
image 396 takes 21 ms
image 397 takes 21 ms
image 398 takes 21 ms
image 399 takes 19 ms
image 400 takes 19 ms
image 401 takes 21 ms
image 402 takes 20 ms
image 403 takes 21 ms
image 404 takes 19 ms
image 405 takes 20 ms
image 406 takes 21 ms
image 407 takes 22 ms
image 408 takes 22 ms
image 409 takes 23 ms
image 410 takes 21 ms
image 411 takes 19 ms
image 412 takes 19 ms
image 413 takes 19 ms
image 414 takes 21 ms
image 415 takes 25 ms
image 416 takes 21 ms
image 417 takes 30 ms
image 418 takes 30 ms
image 419 takes 27 ms
image 420 takes 28 ms
image 421 takes 28 ms
image 422 takes 29 ms
image 423 takes 26 ms
image 424 takes 30 ms
image 425 takes 30 ms
image 426 takes 25 ms
image 427 takes 28 ms
image 428 takes 25 ms
image 429 takes 22 ms
image 430 takes 21 ms
image 431 takes 21 ms
image 432 takes 22 ms
image 433 takes 19 ms
image 434 takes 20 ms
image 435 takes 19 ms
image 436 takes 20 ms
image 437 takes 19 ms
image 438 takes 20 ms
image 439 takes 19 ms
image 440 takes 19 ms
image 441 takes 21 ms
image 442 takes 19 ms
image 443 takes 21 ms
image 444 takes 21 ms
image 445 takes 18 ms
image 446 takes 19 ms
image 447 takes 19 ms
image 448 takes 19 ms
image 449 takes 19 ms
image 450 takes 19 ms
image 451 takes 19 ms
image 452 takes 19 ms
image 453 takes 18 ms
image 454 takes 18 ms
image 455 takes 20 ms
image 456 takes 20 ms
image 457 takes 19 ms
image 458 takes 19 ms
image 459 takes 21 ms
image 460 takes 20 ms
image 461 takes 21 ms
image 462 takes 20 ms
image 463 takes 19 ms
image 464 takes 19 ms
image 465 takes 19 ms
image 466 takes 19 ms
image 467 takes 20 ms
image 468 takes 20 ms
image 469 takes 20 ms
image 470 takes 19 ms
image 471 takes 21 ms
image 472 takes 21 ms
image 473 takes 19 ms
image 474 takes 18 ms
image 475 takes 20 ms
image 476 takes 20 ms
image 477 takes 22 ms
image 478 takes 20 ms
image 479 takes 20 ms
image 480 takes 20 ms
image 481 takes 20 ms
image 482 takes 20 ms
image 483 takes 18 ms
image 484 takes 20 ms
image 485 takes 20 ms
image 486 takes 19 ms
image 487 takes 19 ms
image 488 takes 18 ms
image 489 takes 21 ms
image 490 takes 18 ms
image 491 takes 20 ms
image 492 takes 20 ms
image 493 takes 20 ms
image 494 takes 21 ms
image 495 takes 20 ms
image 496 takes 25 ms
image 497 takes 27 ms
image 498 takes 20 ms
image 499 takes 18 ms
image 500 takes 19 ms
image 501 takes 18 ms
image 502 takes 18 ms
image 503 takes 23 ms
image 504 takes 20 ms
image 505 takes 19 ms
image 506 takes 20 ms
image 507 takes 21 ms
image 508 takes 19 ms
image 509 takes 23 ms
image 510 takes 23 ms
image 511 takes 19 ms
image 512 takes 19 ms
image 513 takes 19 ms
image 514 takes 20 ms
image 515 takes 17 ms
image 516 takes 20 ms
image 517 takes 20 ms
image 518 takes 21 ms
image 519 takes 18 ms
image 520 takes 19 ms
image 521 takes 20 ms
image 522 takes 22 ms
image 523 takes 20 ms
image 524 takes 23 ms
image 525 takes 20 ms
image 526 takes 19 ms
image 527 takes 20 ms
image 528 takes 20 ms
image 529 takes 19 ms
image 530 takes 18 ms
image 531 takes 20 ms
image 532 takes 26 ms
image 533 takes 19 ms
image 534 takes 23 ms
image 535 takes 23 ms
image 536 takes 20 ms
image 537 takes 19 ms
image 538 takes 22 ms
image 539 takes 20 ms
image 540 takes 28 ms
image 541 takes 19 ms
image 542 takes 19 ms
image 543 takes 20 ms
image 544 takes 18 ms
image 545 takes 22 ms
image 546 takes 20 ms
image 547 takes 25 ms
image 548 takes 20 ms

total 10981 ms

Metadatas:

image
image
image
image
image
image

i finish a implementation of incremental loading, but it is too slow:

image

private void loadFromLocalFolder() {
        this.reader = new ImageSeriesReader();
        VectorString dicomFilesNames = ImageSeriesReader.getGDCMSeriesFileNames(this.dicomSeriesFolderPath);
        this.reader.loadPrivateTagsOn();
        this.reader.metaDataDictionaryArrayUpdateOn();
        this.reader.setFileNames(new VectorString(Collections.singleton(dicomFilesNames.get(0))));
        this.series = reader.execute();
        if (dicomFilesNames.size() > 1) {
            this.loading = true;
            VectorUInt32 mainSize = new VectorUInt32(new long[]{this.series.getSize().get(0), this.series.getSize().get(1), dicomFilesNames.size()});
            VectorDouble mainOrigin = this.series.getOrigin();
            VectorDouble mainDirection = this.series.getDirection();
            VectorDouble mainSpacing = this.series.getSpacing();
            this.reader.setFileNames(new VectorString(Collections.singleton(dicomFilesNames.get(1))));
            this.series = reader.execute();
            VectorDouble mainOrigin2 = this.series.getOrigin();
            mainSpacing = new VectorDouble(new double[]{mainSpacing.get(0), mainSpacing.get(1), (Math.abs(mainOrigin.get(2)) - Math.abs(mainOrigin2.get(2)))});
            Volume thisVolumeInstance = this;
            Image finalConcatenatedImage = new Image(mainSize, PixelIDValueEnum.sitkVectorUInt8);
            finalConcatenatedImage.setOrigin(mainOrigin);
            finalConcatenatedImage.setDirection(mainDirection);
            finalConcatenatedImage.setSpacing(mainSpacing);
            long startTotal = System.currentTimeMillis();
            Runnable asyncLoading = () -> {
                for (int fileIndex = 0; fileIndex < dicomFilesNames.size(); fileIndex++) {
                    long startImage = System.currentTimeMillis();
                    thisVolumeInstance.reader.setFileNames(new VectorString(Collections.singleton(dicomFilesNames.get(fileIndex))));
                    Image referenceImage = reader.execute();
                    if (referenceImage.getPixelID() != PixelIDValueEnum.sitkVectorUInt8) {
                        referenceImage = Filters.convertImageToVectorUInt8(referenceImage);
                    }
                    byte[] referencePixels = Slicer.volumeToByteArray(referenceImage);
                    int pixelIndex = 0;
                    for (int y = 0; y < referenceImage.getSize().get(0); y++) {
                        for (int x = 0; x < referenceImage.getSize().get(1); x++) {
                            VectorUInt32 pixelPosition = new VectorUInt32(new long[]{x, y, fileIndex});
                            VectorUInt8 pixelValue = new VectorUInt8(new short[]{referencePixels[pixelIndex], referencePixels[pixelIndex], referencePixels[pixelIndex]});
                            finalConcatenatedImage.setPixelAsVectorUInt8(pixelPosition, pixelValue);
                            pixelIndex += 1;
                        }
                    }
                    long finishImage = System.currentTimeMillis();
                    System.out.println("finish image " + fileIndex + " = " + (finishImage - startImage) + "ms");
                }
                thisVolumeInstance.series = finalConcatenatedImage;
                this.loading = false;
            };
            asyncLoading.run();
            long finishTotal = System.currentTimeMillis();
            System.out.println("total = " + (finishTotal - startTotal) + "ms");
        }
    }


public static byte[] volumeToByteArray(Image volume) {
        ByteBuffer imageDataBuffer = volume.getBufferAsByteBuffer();
        byte[] imageByteArray = new byte[imageDataBuffer.remaining()];
        imageDataBuffer.get(imageByteArray);
        return imageByteArray;
    }



public static Image convertImageToVectorUInt8(Image image) {
        CastImageFilter filter = new CastImageFilter();
        filter.setOutputPixelType(PixelIDValueEnum.sitkVectorUInt8);
        return filter.execute(image);
    }

Hi @zivy, @blowekamp and @dchen.

Do you guys have any idea why my SeriesReader is so slow?

I don’t know. I just loaded a 800 slice DICOM data set and it took 2.53 seconds. 512x512x800 2byte pixels.

I would suggest profiling your code to evaluate performance bottle necks.

I’m not sure what’s going on with your code. From my reading of it, at the 6th line (quoted below) you are actually loading the whole DICOM series into memory.

Then later on, in your loop below you are loading each DICOM one by one. But haven’t you already loaded it above?

And then you are looping over each pixel in each slice and copying that pixel into ‘finalConcatenatedImage’. That’s gotta be brutally slow.

If you have asynchronously loaded each slice, once that loading is done, you can use SimpleITK’s JoinSeriesImageFilter to combine the stack of 2d images into one 3d image.

But, again, I think you’ve already loaded the volume up at the top of your code when you call reader.execute().