[vtkusers] High memory cost of vtkDecimatePro for 3D model generation from DICOM series

David Gobbi david.gobbi at gmail.com
Thu Mar 17 22:01:52 EDT 2016


You only need one threshold to create a model from an image.
Why do you let the user set two thresholds?


On Thu, Mar 17, 2016 at 7:54 PM, Liu_tj <tjlp at netease.com> wrote:

> Hi, David,
>
> If the user sets a upper value, what should we do?
>
> Thanks
> Liu Peng
>
>
>
> 在2016-03-18,"David Gobbi" <david.gobbi at gmail.com> 写道:
>
> -----原始邮件-----
> *发件人:*"David Gobbi" <david.gobbi at gmail.com>
> *发送时间:*2016年03月18日 星期五
> *收件人:*"Liu_tj" <tjlp at netease.com>
> *抄送:*"vtkusers" <vtkusers at vtk.org>
> *主题:*Re: Re: Re: Re: [vtkusers] High memory cost of vtkDecimatePro for 3D
> model generation from DICOM series
>
>
> Hi Liu Peng,
>
> Now that I have seen your code, you should definitely remove
> vtkImageThreshold and set the vtkMarchingCubes isovalue to around 1000.
> I'm certain that vtkImageThreshold does nothing useful in this pipeline.
>
> For vtkReverseSense, see the documentation page for the class for an
> explanation of what it does.  I wrote that example code because I thought
> you might need an upper and a lower threshold, but now that I have seen
> your code, I think you only need one threshold (just the lower threshold).
> So you can ignore the code that I sent.
>
> As for the camera, it is usually a good idea to point it at the center of
> the volume.  I do not always like VTK's default camera position, so I when
> I write VTK code, I almost always set the camera position myself.
>
>  - David
>
>
>
> On Thu, Mar 17, 2016 at 7:07 PM, Liu_tj <tjlp at netease.com> wrote:
>
>> Hi, David,
>>
>> Below is my present C# code.You can see that I reset the camera position,
>> otherwise after rendering, the 3D model is not at the window center, I have
>> to pan it, any recommendation for the position issue also?
>>
>>       private void Display(vtkRenderWindow aRenderWindow, vtkImageData
>> aData)
>>         {
>>             vtkImageData volume = vtkImageData.New();
>>             double isoValue = 1;
>>             volume.DeepCopy(aData);
>>             vtkImageThreshold image_threshold = vtkImageThreshold.New();
>>             image_threshold.SetInputData(volume);
>>             image_threshold.ThresholdBetween(1000,20000);
>>             image_threshold.ReplaceInOn();
>>             image_threshold.SetInValue(1);
>>             image_threshold.ReplaceOutOn();
>>             image_threshold.SetOutValue(0);
>>             image_threshold.Update();
>>
>>             vtkMarchingCubes surface = vtkMarchingCubes.New();
>>             surface.SetInputData(image_threshold.GetOutput());
>>             surface.ComputeNormalsOn();
>>             surface.ComputeScalarsOn();
>>             surface.SetValue(0, isoValue);
>>             surface.Update();
>>
>>             vtkPolyData marched = vtkPolyData.New();
>>             marched.DeepCopy(surface.GetOutput());
>>
>>             long pointcnt = marched.GetNumberOfPoints();
>>
>>             // Decimation to reduce the number of triangles
>>             vtkDecimatePro decimator = vtkDecimatePro.New();
>>             decimator.SetInputData(marched);
>>             decimator.SetTargetReduction(0.5);
>>             decimator.SetPreserveTopology(1);
>>             decimator.Update();
>>             //Smoothing
>>            vtkSmoothPolyDataFilter smoother =
>> vtkSmoothPolyDataFilter.New();
>>             smoother.SetInputData(decimator.GetOutput());
>>             smoother.SetNumberOfIterations(5);
>>             smoother.SetFeatureAngle(60);
>>             smoother.SetRelaxationFactor(0.05);
>>             smoother.FeatureEdgeSmoothingOff();
>>
>>             //Select the largest region
>>             vtkPolyDataConnectivityFilter connectivityFilter =
>> vtkPolyDataConnectivityFilter.New();
>>
>> connectivityFilter.SetInputConnection(decimator.GetOutputPort());
>>             connectivityFilter.ScalarConnectivityOff();
>>             connectivityFilter.SetExtractionModeToLargestRegion();
>>             connectivityFilter.Update();
>>
>>             // Create final polygon mesh
>>             vtkPolyData mesh = vtkPolyData.New();
>>             mesh.ShallowCopy(connectivityFilter.GetOutput());
>>
>>             // Visualization
>>             vtkRenderer renderer =
>> aRenderWindow.GetRenderers().GetFirstRenderer();
>>             renderer.SetBackground(0.0, 0.0, 0.0);
>>
>>             vtkPolyDataMapper mapper = vtkPolyDataMapper.New();
>>             mapper.SetInputData(mesh);
>>             mapper.ScalarVisibilityOff();
>>
>>             vtkActor actor = vtkActor.New();
>>             actor.SetMapper(mapper);
>>             renderer.AddActor(actor);
>>
>>             vtkCamera camera = renderer.MakeCamera();
>>             camera.SetPosition(-500.0, 245.5, 122.0);
>>             camera.SetFocalPoint(301.0, 245.5, 122.0);
>>             camera.SetViewAngle(30.0);
>>             camera.SetRoll(-90.0);
>>             renderer.SetActiveCamera(camera);
>>
>>             aRenderWindow.Render();
>>
>>             vtkRenderWindowInteractor interactor  =
>> aRenderWindow.GetInteractor();
>>             interactor.Start();
>>         }
>>
>>
>>
>> 在2016-03-17,"David Gobbi" <david.gobbi at gmail.com> 写道:
>>
>> -----原始邮件-----
>> *发件人:*"David Gobbi" <david.gobbi at gmail.com>
>> *发送时间:*2016年03月17日 星期四
>> *收件人:*"Liu_tj" <tjlp at netease.com>
>> *抄送:*"vtkusers" <vtkusers at vtk.org>
>> *主题:*Re: Re: Re: [vtkusers] High memory cost of vtkDecimatePro for 3D
>> model generation from DICOM series
>>
>>
>> And I should add: if it is necessary to use a range (instead of just a
>> lower threshold), then the pipeline can use vtkMarchingCubes twice:
>>
>> vtkSmartPointer<vtkMarchingCubes> cubes1 =
>> vtkSmartPointer<vtkMarchingCubes>::New();
>> cubes1->SetInputData(imagedata);
>> cubes1->SetValue(0, lowerThreshold);
>>
>> vtkSmartPointer<vtkMarchingCubes> cubes2 =
>> vtkSmartPointer<vtkMarchingCubes>::New();
>> cubes2->SetInputData(imagedata);
>> cubes2->SetValue(0, upperThreshold);
>>
>> vtkSmartPointer<vtkReverseSense> reverse =
>> vtkSmartPointer<vtkReverseSense>::New();
>> reverse->SetInputConnection(cubes2->GetOutputPort());
>>
>> vtkSmartPointer<vtkAppendPolyData> surface =
>> vtkSmartPointer<vtkAppendPolyData>::New();
>> surface->SetInputConnection(cubes1->GetOutputPort());
>> surface->AddInputConnection(cubes2->GetOutputPort());
>> surface->Update();
>>
>>
>> On Thu, Mar 17, 2016 at 6:06 AM, David Gobbi <david.gobbi at gmail.com>
>> wrote:
>>
>>> Hi Liu Peng,
>>>
>>> For creating a model, it is common to allow the user to set just a lower
>>> threshold (rather than a range), and to use the lower threshold as the
>>> isovalue.  If you send the code for the whole pipeline, that might help.
>>>
>>>  - David
>>>
>>> On Wed, Mar 16, 2016 at 11:27 PM, Liu_tj <tjlp at netease.com> wrote:
>>>
>>>> Hi, David,
>>>>
>>>> If I don't use vtkImageThreshol, how to generate 3D model from the
>>>> points whose grayscale is in some specific range? This range can be changed
>>>> by the user.
>>>>
>>>> Thanks
>>>> Liu Peng
>>>>
>>>> 在2016-03-17,"David Gobbi" <david.gobbi at gmail.com> 写道:
>>>>
>>>> -----原始邮件-----
>>>> *发件人:*"David Gobbi" <david.gobbi at gmail.com>
>>>> *发送时间:*2016年03月17日 星期四
>>>> *收件人:*"Liu_tj" <tjlp at netease.com>
>>>> *抄送:*"vtkusers" <vtkusers at vtk.org>
>>>> *主题:*Re: Re: [vtkusers] High memory cost of vtkDecimatePro for 3D
>>>> model generation from DICOM series
>>>>
>>>>
>>>> On Wed, Mar 16, 2016 at 10:35 PM, Liu_tj <tjlp at netease.com> wrote:
>>>>
>>>>> Hi,David,
>>>>>
>>>>> If using vtkImageThreshold before vtkMarchingCubes is not a good
>>>>> option, what other better way do you have?
>>>>>
>>>>
>>>> The output of the reader should go directly into vtkMarchingCubes.
>>>>
>>>>
>>>>> Beside, for the isovalue, I try 2,3,4 and marched->GetNumberOfPoints()
>>>>> return 0, only isovalue is 1 and marched->GetNumberOfPoints() return a
>>>>> number greater than 0. I have no idea this is relating to the DICOM series
>>>>> or other problem.
>>>>>
>>>>
>>>> If you remove vtkImageThreshold, and put the output of the reader
>>>> directly into vtkMarchingCubes, then you should be able to use an isovalue
>>>> somewhere between 100 and 2000 and get a good result.
>>>>
>>>> Also, after vtkMarchingCubes, you can use vtkConnectivityFilter to
>>>> clean up the polydata before you decimate it.
>>>>
>>>>  - David
>>>>
>>>>
>>>>
>>>>
>>>>
>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtkusers/attachments/20160317/25752bb8/attachment-0001.html>


More information about the vtkusers mailing list