Hi, David,<br><br>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?<br><br> private void Display(vtkRenderWindow aRenderWindow, vtkImageData aData)<br> {<br> vtkImageData volume = vtkImageData.New();<br> double isoValue = 1;<br> volume.DeepCopy(aData);<br> vtkImageThreshold image_threshold = vtkImageThreshold.New();<br> image_threshold.SetInputData(volume);<br> image_threshold.ThresholdBetween(1000,20000);<br> image_threshold.ReplaceInOn();<br> image_threshold.SetInValue(1);<br> image_threshold.ReplaceOutOn();<br> image_threshold.SetOutValue(0);<br> image_threshold.Update();<br><br> vtkMarchingCubes surface = vtkMarchingCubes.New();<br> surface.SetInputData(image_threshold.GetOutput());<br> surface.ComputeNormalsOn();<br> surface.ComputeScalarsOn();<br> surface.SetValue(0, isoValue);<br> surface.Update();<br><br> vtkPolyData marched = vtkPolyData.New();<br> marched.DeepCopy(surface.GetOutput());<br><br> long pointcnt = marched.GetNumberOfPoints();<br><br> // Decimation to reduce the number of triangles<br> vtkDecimatePro decimator = vtkDecimatePro.New();<br> decimator.SetInputData(marched);<br> decimator.SetTargetReduction(0.5);<br> decimator.SetPreserveTopology(1);<br> decimator.Update();<br> //Smoothing<br> vtkSmoothPolyDataFilter smoother = vtkSmoothPolyDataFilter.New();<br> smoother.SetInputData(decimator.GetOutput());<br> smoother.SetNumberOfIterations(5);<br> smoother.SetFeatureAngle(60);<br> smoother.SetRelaxationFactor(0.05);<br> smoother.FeatureEdgeSmoothingOff();<br><br> //Select the largest region<br> vtkPolyDataConnectivityFilter connectivityFilter = vtkPolyDataConnectivityFilter.New();<br> connectivityFilter.SetInputConnection(decimator.GetOutputPort());<br> connectivityFilter.ScalarConnectivityOff();<br> connectivityFilter.SetExtractionModeToLargestRegion();<br> connectivityFilter.Update();<br><br> // Create final polygon mesh<br> vtkPolyData mesh = vtkPolyData.New();<br> mesh.ShallowCopy(connectivityFilter.GetOutput());<br><br> // Visualization<br> vtkRenderer renderer = aRenderWindow.GetRenderers().GetFirstRenderer();<br> renderer.SetBackground(0.0, 0.0, 0.0);<br><br> vtkPolyDataMapper mapper = vtkPolyDataMapper.New();<br> mapper.SetInputData(mesh);<br> mapper.ScalarVisibilityOff();<br><br> vtkActor actor = vtkActor.New();<br> actor.SetMapper(mapper);<br> renderer.AddActor(actor);<br><br> vtkCamera camera = renderer.MakeCamera();<br> camera.SetPosition(-500.0, 245.5, 122.0);<br> camera.SetFocalPoint(301.0, 245.5, 122.0);<br> camera.SetViewAngle(30.0);<br> camera.SetRoll(-90.0);<br> renderer.SetActiveCamera(camera);<br><br> aRenderWindow.Render();<br><br> vtkRenderWindowInteractor interactor = aRenderWindow.GetInteractor();<br> interactor.Start();<br> }<br><div><br><br></div>
<span>
</span>
<br> 在2016-03-17,"David Gobbi" <david.gobbi@gmail.com> 写道:
<blockquote id="isReplyContent" style="padding-left:1ex; margin: 0px 0px 0px 0.8ex; BORDER-LEFT: #ccc 1px solid">
-----原始邮件-----<br>
<b>发件人:</b>"David Gobbi" <david.gobbi@gmail.com> <br>
<b>发送时间:</b>2016年03月17日 星期四<br>
<b>收件人:</b>"Liu_tj" <tjlp@netease.com><br>
<b>抄送:</b>"vtkusers" <vtkusers@vtk.org><br>
<b>主题:</b>Re: Re: Re: [vtkusers] High memory cost of vtkDecimatePro for 3D model generation from DICOM series<br>
<br><div dir="ltr">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:<div><br></div><div>vtkSmartPointer<vtkMarchingCubes> cubes1 = vtkSmartPointer<vtkMarchingCubes>::New();<br></div><div>cubes1->SetInputData(imagedata);</div><div>cubes1->SetValue(0, lowerThreshold);</div><div><br></div><div>vtkSmartPointer<vtkMarchingCubes> cubes2 = vtkSmartPointer<vtkMarchingCubes>::New();<br></div><div>cubes2->SetInputData(imagedata);</div><div>cubes2->SetValue(0, upperThreshold);</div><div><br></div><div>vtkSmartPointer<vtkReverseSense> reverse = vtkSmartPointer<vtkReverseSense>::New();<br></div><div>reverse->SetInputConnection(cubes2->GetOutputPort());</div><div><br></div><div>vtkSmartPointer<vtkAppendPolyData> surface = vtkSmartPointer<vtkAppendPolyData>::New();<br></div><div>surface->SetInputConnection(cubes1->GetOutputPort());</div><div>surface->AddInputConnection(cubes2->GetOutputPort());<br></div><div>surface->Update();</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Mar 17, 2016 at 6:06 AM, David Gobbi <span dir="ltr"><<a href="mailto:david.gobbi@gmail.com" target="_blank">david.gobbi@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi Liu Peng,<div><br></div><div>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.</div><span class="HOEnZb"><font color="#888888"><div><br></div><div> - David</div></font></span></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Mar 16, 2016 at 11:27 PM, Liu_tj <span dir="ltr"><<a href="mailto:tjlp@netease.com" target="_blank">tjlp@netease.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi, David,<br><br>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. <div><br>Thanks<br>Liu Peng<br></div><span>
<span>
</span>
<br> 在2016-03-17,"David Gobbi" <<a href="mailto:david.gobbi@gmail.com" target="_blank">david.gobbi@gmail.com</a>> 写道:
</span><blockquote style="padding-left:1ex;margin:0px 0px 0px 0.8ex;BORDER-LEFT:#ccc 1px solid"><span>
-----原始邮件-----<br>
<b>发件人:</b>"David Gobbi" <<a href="mailto:david.gobbi@gmail.com" target="_blank">david.gobbi@gmail.com</a>> <br>
<b>发送时间:</b>2016年03月17日 星期四<br>
<b>收件人:</b>"Liu_tj" <<a href="mailto:tjlp@netease.com" target="_blank">tjlp@netease.com</a>><br>
<b>抄送:</b>"vtkusers" <<a href="mailto:vtkusers@vtk.org" target="_blank">vtkusers@vtk.org</a>><br>
</span><b>主题:</b>Re: Re: [vtkusers] High memory cost of vtkDecimatePro for 3D model generation from DICOM series<div><div><br>
<br><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Mar 16, 2016 at 10:35 PM, Liu_tj <span dir="ltr"><<a href="mailto:tjlp@netease.com" target="_blank">tjlp@netease.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,David,<br><br>If using vtkImageThreshold before vtkMarchingCubes is not a good option, what other better way do you have?<br></blockquote><div><br></div><div>The output of the reader should go directly into vtkMarchingCubes.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">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.<br></blockquote><div><br></div><div>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. </div><div><br></div><div>Also, after vtkMarchingCubes, you can use vtkConnectivityFilter to clean up the polydata before you decimate it.</div><div><br></div><div> - David</div></div></div></div>
</div></div></blockquote><br><br><span title="neteasefooter"><p> </p></span></blockquote></div><br></div>
</div></div></blockquote></div><br></div>
</blockquote>