[vtkusers] Opacity discrepancy with downscaled volume despite opacity unit distance == spacing

Elvis Stansvik elvis.stansvik at orexplore.com
Sun Feb 12 11:54:25 EST 2017


2017-02-12 17:51 GMT+01:00 Elvis Stansvik <elvis.stansvik at orexplore.com>:

> 2017-02-12 17:31 GMT+01:00 David Gobbi <david.gobbi at gmail.com>:
>
>> Hi Elvis,
>>
>> Here is something you can do as a check: set the sample distance for the
>> ray casting to a very small value, so that it takes around 1000 steps for
>> the ray to traverse the volume from front to back.  The thickness of your
>> volume is 29*0.006 = 0.174, so you can try a sample spacing of 1.74e-04:
>>
>> mapper->AutoAdjustSampleDistancesOff();
>> mapper->SetSampleDistance(1.74e-04);
>>
>> If the two volumes look the same when you use a small sample distance,
>> then the difference you were seeing was probably just due to discretization.
>>
>
> Ah, good idea. However, if I set the opacity unit distance to such a small
> value, both volumes appear as completely opaque red. This makes sense to
> me, since with so many accumulations, the opacity value in my opacity
> function (0.1) will add up very quickly..
>

Bah sorry, I read you completely wrong. You were talking about the sample
distance, not the opacity unit distance. Will check again..

Elvis


>
> If I, just as a test, try to "compensate" by using 0.001 instead of 0.1 in
> my opacity function, the volumes appear non-opaque as expected, but again
> there's a discrepancy between the small-spaced and large-spaced volume
> (shown in attached screenshot).
>
> Elvis
>
>
>>
>>  - David
>>
>>
>>
>> On Thu, Feb 9, 2017 at 6:45 AM, Elvis Stansvik <
>> elvis.stansvik at orexplore.com> wrote:
>>
>>> Hi all,
>>>
>>> The following example shows a 30x30x30 volume rendered, and next to it a
>>> downscaled version of it (but using an identical opacity/transfer
>>> function). Notice how in the result (attached), the downscaled version is
>>> less opaque. This is despite me using
>>>
>>>     SetScalarOpacityUnitDistance(image->GetSpacing()[0])
>>>
>>> to set the scalar opacity unit distance to the spacing of the respective
>>> image. I would thought calling SetScalarOpacityUnitDistance like this would
>>> ensure both volumes look the same (apart from resolution).
>>>
>>> How can I make both volumes look the same opacity-wise when using the
>>> same transfer functions?
>>>
>>> Thanks in advance,
>>> Elvis
>>>
>>> main.cpp:
>>>
>>>
>>> #include <algorithm>
>>>
>>> #include <vtkCamera.h>
>>> #include <vtkColorTransferFunction.h>
>>> #include <vtkGPUVolumeRayCastMapper.h>
>>> #include <vtkImageData.h>
>>> #include <vtkImageResize.h>
>>> #include <vtkPiecewiseFunction.h>
>>> #include <vtkRenderer.h>
>>> #include <vtkRenderWindow.h>
>>> #include <vtkRenderWindowInteractor.h>
>>> #include <vtkSmartPointer.h>
>>> #include <vtkVolume.h>
>>> #include <vtkVolumeProperty.h>
>>>
>>> // Create a volume from the given image
>>> vtkSmartPointer<vtkVolume> createVolume(vtkSmartPointer<vtkImageData>
>>> image) {
>>>     auto color = vtkSmartPointer<vtkColorTransferFunction>::New();
>>>     color->AddRGBPoint(0.0, 1.0, 0.0, 0.0);
>>>     color->AddRGBPoint(1.0, 1.0, 0.0, 0.0);
>>>
>>>     auto opacity = vtkSmartPointer<vtkPiecewiseFunction>::New();
>>>     opacity->AddPoint(0.0, 0.1);
>>>     opacity->AddPoint(1.0, 0.1);
>>>
>>>     auto property = vtkSmartPointer<vtkVolumeProperty>::New();
>>>     property->SetColor(color);
>>>     property->SetScalarOpacity(opacity);
>>>     property->SetInterpolationTypeToLinear();
>>>     property->ShadeOff();
>>>     property->SetScalarOpacityUnitDistance(image->GetSpacing()[0]);
>>>
>>>     auto mapper = vtkSmartPointer<vtkGPUVolumeRayCastMapper>::New();
>>>     mapper->SetInputData(image);
>>>
>>>     auto volume = vtkSmartPointer<vtkVolume>::New();
>>>     volume->SetMapper(mapper);
>>>     volume->SetProperty(property);
>>>
>>>     return volume;
>>> }
>>>
>>> int main(int argc, char *argv[]) {
>>>
>>>     // Create a 30x30x30 volume
>>>     auto image = vtkSmartPointer<vtkImageData>::New();
>>>     image->SetDimensions(30, 30, 30);
>>>     image->SetSpacing(0.006, 0.006, 0.006);
>>>     image->AllocateScalars(VTK_FLOAT, 1);
>>>
>>>     auto imagePtr = static_cast<float *>(image->GetScalarPointer());
>>>     std::fill_n(imagePtr, 30 * 30 * 30, 1.0);
>>>
>>>     auto volume = createVolume(image);
>>>
>>>     // Create a smaller (10x10x10) version
>>>     auto resize = vtkSmartPointer<vtkImageResize>::New();
>>>     resize->SetInputData(image);
>>>     resize->SetOutputDimensions(10, 10, 10);
>>>     resize->Update();
>>>
>>>     auto smallVolume = createVolume(resize->GetOutput());
>>>     smallVolume->SetPosition(0.2, 0, 0);
>>>
>>>     // Render the two volumes
>>>     auto renderer = vtkSmartPointer<vtkRenderer>::New();
>>>     renderer->SetBackground(1.0, 1.0, 1.0);
>>>     renderer->AddVolume(volume);
>>>     renderer->AddVolume(smallVolume);
>>>     renderer->ResetCamera();
>>>
>>>     auto camera = renderer->GetActiveCamera();
>>>     camera->SetParallelProjection(1);
>>>
>>>     auto window = vtkSmartPointer<vtkRenderWindow>::New();
>>>     window->AddRenderer(renderer);
>>>     window->SetSize(800, 400);
>>>
>>>     auto interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
>>>     interactor->SetRenderWindow(window);
>>>     interactor->Start();
>>>
>>>     return 0;
>>> }
>>>
>>>
>>> CMakeLists.txt:
>>>
>>>
>>> cmake_minimum_required(VERSION 3.1)
>>>
>>> project(TestCase)
>>>
>>> set(CMAKE_CXX_STANDARD 11)
>>> set(CMAKE_CXX_STANDARD_REQUIRED ON)
>>>
>>> find_package(VTK COMPONENTS
>>>     vtkCommonCore
>>>     vtkCommonDataModel
>>>     vtkCommonExecutionModel
>>>     vtkInteractionStyle
>>>     vtkImagingCore
>>>     vtkRenderingCore
>>>     vtkRenderingOpenGL2
>>>     vtkRenderingVolume
>>>     vtkRenderingVolumeOpenGL2
>>> )
>>>
>>> add_executable(TestCase main.cpp)
>>>
>>> target_link_libraries(TestCase PUBLIC
>>>     vtkCommonCore
>>>     vtkCommonDataModel
>>>     vtkCommonExecutionModel
>>>     vtkImagingCore
>>>     vtkInteractionStyle
>>>     vtkRenderingCore
>>>     vtkRenderingOpenGL2
>>>     vtkRenderingVolume
>>>     vtkRenderingVolumeOpenGL2
>>> )
>>>
>>> target_include_directories(TestCase PUBLIC
>>>     ${VTK_INCLUDE_DIRS}
>>> )
>>>
>>>
>>> target_compile_definitions(TestCase PUBLIC
>>>     ${VTK_DEFINITIONS}
>>> )
>>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtkusers/attachments/20170212/24e874bc/attachment.html>


More information about the vtkusers mailing list