[vtkusers] High memory cost of vtkDecimatePro for 3D model generation from DICOM series
David Gobbi
david.gobbi at gmail.com
Thu Mar 17 22:19:11 EDT 2016
You can segment an image with just one threshold (i.e. just the lower
threshold). It is not necessary to set a range.
But, regardless, vtkMarchingCubes is designed to take a greyscale image as
input, not a binary image.
- David
On Thu, Mar 17, 2016 at 8:09 PM, Liu_tj <tjlp at netease.com> wrote:
> Hi, David,
>
> The user scenario is that we allow the user to set segment threshold which
> is a grayscale range. So at the 2D DICOM view, the pixels which fall in
> this range will be shown by special color (I implement it with
> vtkLookupTableand vtkImageMapToColors); then the user can preview the 3D
> model generated by the points in this grayscale range.
>
> Thanks
>
>
> 在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: Re: [vtkusers] High memory cost of vtkDecimatePro
> for 3D model generation from DICOM series
>
>
> 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/02726fb6/attachment.html>
More information about the vtkusers
mailing list