Blocked images larger than a certain size will not render in Image Labeler
5 views (last 30 days)
Show older comments
Dominique Chabot
on 1 May 2023
Commented: Ashish Uthama
on 8 May 2023
I am endeavouring to train a deep learning object detection network. For training data, I have large photomosaics that I would like to label using the Image Labeler app, and then ultimately create a Blocked Image Datastore with a Block Location Set argument to sample blocks from the large training images that are the appropriate input size for the network.
I appreciate that the Image Labeler app can import large images like these as blocked images, but I've found that above a certain size it seems to be unable to render them, and consequently I am unable to work with them in the Image Labeler.
Specifically, when things are working properly, if I import a blocked image into the lmage Labeler and proceed to zoom in from its initial zoom level, after several seconds at most the resolution of the image updates to the new zoom level. But above a certain image size, when I zoom in it just remains 'pixelated' from the previous zoom level's resolution, the resolution never updates to the new zoom level, and eventually after some time (several or more minutes) the MATLAB command window reports a graphics timeout error.
As it stands, my largest training image to not have this issue in Image Labeler is 15887 x 33197 pixels (≈ 527 million pixels), but as of my next size up image (18682 x 34701 pixels ≈ 648 million pixels), it will not render at higher zoom levels.
I'm not sure precisely which hardware resources are used to render images in Image Labeler, but my PC has 64 GB of RAM as well as an NVIDIA GeForce RTX 3060 with 12 GB of VRAM (and yes, I have the Parallel Computing Toolbox).
Any advice/insight?
5 Comments
Matt J
on 1 May 2023
Maybe you could show us the details of the blockedImage representation, e.g.,
blockedImage with properties:
Read only properties
Source: [128x128x27 uint8]
Adapter: [1x1 images.blocked.InMemory]
Size: [128 128 27]
SizeInBlocks: [1 1 1]
ClassUnderlying: "uint8"
Accepted Answer
Ashish Uthama
on 3 May 2023
Thanks for sharing the blockedImage representation - This is a JPG file. Which means there is really no way to do blocked IO (i.e read only parts of the file). Since its a compressed format, the whole file needs to be uncompressed to access any small region of the image.
You could convert this file (one time hit) using something like: (choose a blocksize the same as the image size you want to train your network on, that will help IO performance down the line)
makeMultiLevel2D(bim, BlockSize=[1024 1024], Scales=[1 .1], OutputLocation="withOverview.tif", Adapter=images.blocked.TIFF)
Loading this TIFF file into the app should hopefully give you better performance. It will also help when you get to the blockedImageDatastore workflow.
2 Comments
Ashish Uthama
on 8 May 2023
Many things to unpack :)
TIFF vs JPEG - JPEG is 'lossy' compression, details are lost. Which is why it can compress much better than LZW in TIFF (lossless). Depending on your experiment, the loss in quality may not matter. There is an option to have each tile in TIFF comrpessed with JPEG which gives you the best of both worlds. Not sure if your image stitching software has than option to expore. You can create that with blockedImage/write though - this should reduce file size significantly.
adapter = images.blocked.TIFF;
adapter.Compression = Tiff.Compression.JPEG;
write(bim,'out.tif', BlockSize = [1024, 1024],Adapter=adapter)
About long time to import - if your generating software has a capability to create pyramid versions (which is what the makeMultiLevel2D function does) that would help significantly. TIFFs support this format, JPG do not. Having a low resolution version that can be quickly loaded helps the labeller app quickly show you the overiew and only load the finer details when you get down to the block level.
Good point about the suggestion from Image Labeler. That catch is that the boundary of when a JPEG file is 'too large' is highly dependent on a user's machine, ability to change format and a user's patience :) We can definitely add more color to that suggestion.
Not familiar, but using a single labelling project should be the right thing to do.
More Answers (3)
Matt J
on 1 May 2023
I could of course break the images up into smaller images but that would make my workflow less efficient
Breaking them up for the purposes of network training shouldn't impact your workflow. After the network is trained, you can use the original image size for inference.
Matt J
on 1 May 2023
Edited: Matt J
on 1 May 2023
my understanding has been that it automatically sets the block size based on the size of the image and maybe the zoom level
Perhaps it should, but my guess would be that it chooses it no differently from how the blockedImage constructor chooses it and, as you can see from the object properties, the default SizeInBlocks that it has chosen is [1,1,1]. In other words, the software is assuming that a [34701 18682 3] chunk of data is just fine for the memory resources of your computer. No need to split it up.
Are you able to import a blockedImage object to the app? If so, you should probably import to the workspace as a blockedImage object with the blockSize chosen by you directly, e.g.,
bim = blockedImage(Source, blockSize=[1000,1000]);
3 Comments
Matt J
on 1 May 2023
I think we may have exhausted all avenues, but you could always try Tech Support, to see if there's something we've overlooked. If nothing else, they should probably be informed about these limitations.
Matt J
on 1 May 2023
Edited: Matt J
on 1 May 2023
One other possible workaround is to convert the image to grayscale, e.g., using the ReadFcn property of the imageDataStore, for the purposes of labeling only. I don't know if the loss of color affects your ability to recognize targets for labeling purposes. If not, it will cut down memory requirements by a factor of 3.
I would still recommend you chop up the images in any case. I would expect it to make training go much faster.
0 Comments
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!