[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