I have a test program to implement slab MPR rendering using vtkImageResliceMapper. I am seeing a strange broken line artifact around the edge of the image after interacting in the viewport.
When the slab MPR image is first displayed it is fine but as soon as I interact with the viewport by clicking on it, the line appears. The vtkInteractorStyleTrackballCamera interactor is enabled and all I need to do is click in the viewport (without moving the mouse) and the line will appear. If I disable the interactor, then the line artifact no longer appears with left click but still appears for the right click used for a popup menu. This artifact appears regardless of slab rendering mode used (mean, max, min) or slice thickness (including setting it to 1)
This is a java application that uses the java wrappers and a vtkRenderWindowPanel is being used for display. Here are some sample images, the first is the initial slab image that gets display with no line artifact:
I have tried numerous different things but the result is always the same, as soon as I click in the viewport, the slab image will always display some sort of a line artifact around the edges. Lastly I will mention that regular MPR (slab not enabled) works fine as does volume rendering, no line artifacts. Any suggestions would be greatly appreciated.
Try calling AutoAdjustImageQualityOff() on the vtkImageResliceMapper.
When a mouse button is pressed, the interactor reduces VTK’s “AllocatedRenderTime” and this causes the mapper to automatically switch to a faster rendering method that has slightly lower quality for oblique views. The AutoAjustImageQuality setting controls whether this switching occurs.
I’ve been trying to replicate your artifact on my own system, and so far I haven’t been able to. Can you provide details about your program and your system? Such as:
a) operating system and GPU
b) any settings that you have applied to the vtkImageResliceMapper
c) any settings that you have applied to the vtkImageProperty
And about the image itself:
d) the data range, is the lowest value 0 or is it -1000?
e) what are the dimensions and pixel spacings?
I added the call to AutoAdjustImageQualityOff() and interestingly the lines now show up on the initial display of the slab MPR image, don’t need to even click in the viewport. Given this I tried calling AutoAdjustImageQualityOn() after a mouse click but that didn’t seem to work but hopefully this gives you a clue.
I am running this on a Windows 11 laptop that has 2 GPU’s and the issue happens on both. One is the integrated Intel UHD and the other is NVIDIA RTX A2000.
As for the data:
range: -1115 to 3071
dim: 512 x 512 x 286
spacing: 0.859375 x 0.859375 x 1.25
I should mentioned that my test program is using vtkDICOMImageReader for convenience, so the original data range is +1024 as that loader adds the rescale intercept to the data.
Here is the basic setup of the slab MPR pipeline:
slabMapper = new vtkImageResliceMapper();
slabMapper.SetInputData(imageData);
vtkPlane slicePlane = new vtkPlane();
slicePlane.SetOrigin(planeOrigin);
slicePlane.SetNormal(planeNormal);
slabMapper.SetSlicePlane(slicePlane);
slabMapper.SetSlabThickness(currentSlabThickness);
slabMapper.SetSlabTypeToMax();
slabMapper.SetBorder(0); // Suggestion from AI to try remove line
slabImageSlice = new vtkImageSlice();
slabImageSlice.SetMapper(slabMapper);
vtkImageProperty imageProperty = slabImageSlice.GetProperty();
imageProperty.SetInterpolationTypeToLinear(); // Tried nearest neighbor and cubic
imageProperty.SetColorWindow(350.0);
imageProperty.SetColorLevel(40.0);
ren.AddActor(slabImageSlice);
vtkCamera camera = ren.GetActiveCamera();
camera.ParallelProjectionOn();
camera.SetPosition(pos[0], pos[1], pos[2]);
camera.SetFocalPoint(planeOrigin[0], planeOrigin[1], planeOrigin[2]);
camera.SetViewUp(up[0], up[1], up[2]);
ren.ResetCamera();
Let me know if there is any other information you need.
Thanks for the details, I was able to replicate the artifact.
The artifact occurs if the “background” region of the image is a value other than zero. And the use of a tight window accentuates the artifact. The artifact is caused because at the border of the image, the background level is being blended with zero (which in this case is much brighter than the background) during pixel antialiasing. I’m investigating exactly why this occurs, but it definitely occurs at the scale of screen pixels rather than at the scale of image voxels.
There are two options that will eliminate the artifact:
a) mapper.SeparateWindowLevelOperationOff()
This causes the edge antialiasing to occur in RGB colorspace rather than on the raw data values. In RGB space, the background is mostly (0,0,0) and antialising with the (0,0,0) renderer background is artifact-free.
b) mapper.ResampleToScreenPixelsOff()
This changes the way interpolation is done. If it is On, then interpolation is performed on the original data values (i.e. 16-bit), but if it is Off then interpolation is performed on the color-mapped values (i.e. 8-bit). This has an impact especially on the rendering of sharp boundaries between light and dark regions in the image.
Only use one of (a) or (b), there’s no reason to use both. My preference would be (a) for the sake of image quality.
Good news, option ‘a’ seems to resolve the issue … thanks! Could you possibly elaborate on whether you see any down sides to using option ‘a’. This is for a medical imaging application so image quality is very important.
Note I did try option ‘b’ as well … while simply clicking in the viewport no longer resulted in the line artifact, as soon as I dragged the mouse to rotate the plane (I am using the camera trackball interactor), the line artifact would re-appear.
Thx for the additional info on option ‘a’ … will try out the W/L performance on some larger MG images when we get to that point, although, presumably it is still hardware accelerated so I imagine it will be fine.
As for option ‘b’, your guess is correct … I do call SetDesiredUpdateRate. For volume rendering, I found the default degradation in quality while interacting with volume too severe so I was trying to improve the quality during interaction. If there is a more appropriate way to do that, please let me know.
As long as you’re not setting it in response to a mouse presses or other user interactions, it should be fine. It’s meant to be a set-it-and-forget-it sort of thing.