<html>
<head>
<meta content="text/html; charset=windows-1252"
http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<p>Hi Tejas,</p>
<p>You can check out vtkRuledSurfaceFilter for that. Here are some
starters:</p>
<p><a class="moz-txt-link-freetext"
href="http://www.paraview.org/Wiki/VTK/Examples/Python/PolyData/RuledSurfaceFilter">http://www.paraview.org/Wiki/VTK/Examples/Python/PolyData/RuledSurfaceFilter</a></p>
<p>Best,</p>
<p>Paul<br>
</p>
<br>
<div class="moz-cite-prefix">On 20/01/2017 21:05, Tejas Sudharshan
Mathai wrote:<br>
</div>
<blockquote
cite="mid:CAFjn-L2CRU0sty8SdVc7Eo=0k_BEEJMGz+x4VndDZk_XNnkO+w@mail.gmail.com"
type="cite">
<div dir="ltr">Hi,
<div><br>
</div>
<div>I have a 3D vascular free-hand ultrasound volume containing
one vessel, and I am trying to reconstruct the surface of the
vessel. The 3D volume is constructed from a stack of 2D
images/B-scans, and the contour of the vessel in each B-scan
has been segmented; that is, I have an ellipse representing
the contour of the vessel in each B-scan in the volume. I have
tried to reconstruct the contour of the vessel by following
the VTK example of 'GenerateModelsFromLabels.cxx' (<a
moz-do-not-send="true"
href="http://www.vtk.org/Wiki/VTK/Examples/Cxx/Medical/GenerateModelsFromLabels">http://www.vtk.org/Wiki/VTK/Examples/Cxx/Medical/GenerateModelsFromLabels</a>).
However, the result is not a smooth surface from one frame to
another as I would have hoped for it to be. It is
discontinuous and irregular, and the surface doesn't connect
the vessel contours between two adjacent frames in the volume
if the displacement between the ellipses is large. In my
approach, I basically used DiscreteMarchingCubes ->
WindowedSincPolyDataFilter -> GeometryFilter. </div>
<div><br>
</div>
<div>I played around with the passband, smoothingIterations and
featureAngle parameters, and I was able to obtain the best
following result: </div>
<div><br>
</div>
<div><a moz-do-not-send="true" href="https://snag.gy/yqK3Fd.jpg">https://snag.gy/yqK3Fd.jpg</a><br>
</div>
<div><a moz-do-not-send="true" href="https://snag.gy/txu6Ur.jpg">https://snag.gy/txu6Ur.jpg</a><br>
</div>
<div><a moz-do-not-send="true" href="https://snag.gy/ksJfUa.jpg">https://snag.gy/ksJfUa.jpg</a><br>
</div>
<div><br>
</div>
<div><br>
</div>
<div>As you can see, it is not a smooth continuous surface with
a lot of uninterpolated "holes" between adjacent frames, but
it is all right. Can it be made better? I also tried using a
3D Delaunay triangulation, but it only gave me the convex
hull, which is not the output I expected. I would like to know
if there is a better approach towards reconstructing a surface
that closely follows the contour of the vessel from one B-scan
to the next in a volume? <br>
</div>
<div><br>
</div>
<div>A minimal working example is shown below: </div>
<div><br>
</div>
<div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>vtkSmartPointer<vtkImageData>
vesselVolume =</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>vtkSmartPointer<vtkImageData>::New();</div>
<div><br>
</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>int
totalImages = 210;<br>
</div>
<div><br>
</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>for
(int z = 0; z < totalImages; z++)</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>{</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>std::string
strFile = "E:/datasets/vasc/rendering/contour/" +
std::to_string(z + 1) + ".png";</div>
<div><br>
</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>cv::Mat
im = cv::imread(strFile, CV_LOAD_IMAGE_GRAYSCALE);</div>
<div><br>
</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>if
(z == 0)</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>{</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>vesselVolume->SetExtent(0,
im.cols, 0, im.rows, 0, totalImages - 1);</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>vesselVolume->SetSpacing(1,
1, 1);</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>vesselVolume->SetOrigin(0,
0, 0);</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>vesselVolume->AllocateScalars(VTK_UNSIGNED_CHAR,
0);</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>}<span class="gmail-Apple-tab-span" style="white-space:pre"> </span></div>
<div><br>
</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>std::vector<cv::Point2i>
locations; // output, locations of non-zero pixels </div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>cv::findNonZero(im,
locations);</div>
<div><br>
</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>for
(int nzi = 0; nzi < locations.size(); nzi++)</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>{</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>unsigned
char* pixel = static_cast<unsigned
char*>(vesselVolume->GetScalarPointer(locations[nzi].x,
locations[nzi].y, z));</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>pixel[0]
= 255;</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>}</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>}</div>
</div>
<div><br>
</div>
<div>
<div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>vtkSmartPointer<vtkDiscreteMarchingCubes>
discreteCubes =</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>vtkSmartPointer<vtkDiscreteMarchingCubes>::New();</div>
<div><br>
</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>discreteCubes->SetInputData(vesselVolume);</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>discreteCubes->GenerateValues(1,
255, 255);</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>discreteCubes->ComputeNormalsOn();</div>
<div><br>
</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>vtkSmartPointer<vtkWindowedSincPolyDataFilter>
smoother =</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>vtkSmartPointer<vtkWindowedSincPolyDataFilter>::New();</div>
<div><br>
</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>unsigned
int smoothingIterations = 10;</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>double
passBand = 2;</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>double
featureAngle = 360.0;</div>
<div><br>
</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>smoother->SetInputConnection(discreteCubes->GetOutputPort());</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>smoother->SetNumberOfIterations(smoothingIterations);</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>smoother->BoundarySmoothingOff();</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>//smoother->FeatureEdgeSmoothingOff();</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>smoother->FeatureEdgeSmoothingOn();</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>smoother->SetFeatureAngle(featureAngle);</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>smoother->SetPassBand(passBand);</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>smoother->NonManifoldSmoothingOn();</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>smoother->BoundarySmoothingOn();</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>smoother->NormalizeCoordinatesOn();</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>smoother->Update();</div>
<div><br>
</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>vtkSmartPointer<vtkThreshold>
selector =</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>vtkSmartPointer<vtkThreshold>::New();</div>
<div><br>
</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>selector->SetInputConnection(smoother->GetOutputPort());</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>selector->SetInputArrayToProcess(0,
0, 0,</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>vtkDataObject::FIELD_ASSOCIATION_CELLS,</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>vtkDataSetAttributes::SCALARS);</div>
<div><br>
</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>vtkSmartPointer<vtkMaskFields>
scalarsOff =</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>vtkSmartPointer<vtkMaskFields>::New();</div>
<div><br>
</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>//
Strip the scalars from the output</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>scalarsOff->SetInputConnection(selector->GetOutputPort());</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>scalarsOff->CopyAttributeOff(vtkMaskFields::POINT_DATA,</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>vtkDataSetAttributes::SCALARS);</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>scalarsOff->CopyAttributeOff(vtkMaskFields::CELL_DATA,</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>vtkDataSetAttributes::SCALARS);</div>
<div><br>
</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>vtkSmartPointer<vtkGeometryFilter>
geometry =</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>vtkSmartPointer<vtkGeometryFilter>::New();</div>
<div><br>
</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>geometry->SetInputConnection(scalarsOff->GetOutputPort());</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>geometry->Update();</div>
</div>
</div>
<div><br>
</div>
<div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>vtkSmartPointer<vtkPolyDataMapper>
mapper =</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>vtkSmartPointer<vtkPolyDataMapper>::New();<span style="white-space:pre"> </span></div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>mapper->SetInputConnection(geometry->GetOutputPort());<span style="white-space:pre"> </span></div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>mapper->ScalarVisibilityOff();</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>mapper->Update();</div>
</div>
<div>
<div><br>
</div>
<div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>vtkSmartPointer<vtkRenderWindow>
renderWindow =</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>vtkSmartPointer<vtkRenderWindow>::New();</div>
<div><br>
</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>vtkSmartPointer<vtkRenderWindowInteractor>
renderWindowInteractor =</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>vtkSmartPointer<vtkRenderWindowInteractor>::New();</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>renderWindowInteractor->SetRenderWindow(renderWindow);</div>
</div>
<div><br>
</div>
<div>
<div> vtkSmartPointer<vtkRenderer> renderer =</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>vtkSmartPointer<vtkRenderer>::New();</div>
</div>
<div><br>
</div>
<div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>renderWindow->AddRenderer(renderer);</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>renderer->SetBackground(.2,
.3, .4);<br>
</div>
</div>
<div><br>
</div>
<div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>vtkSmartPointer<vtkActor>
actor =</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>vtkSmartPointer<vtkActor>::New();</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>actor->SetMapper(mapper);</div>
</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>renderer->AddActor(actor);<br>
</div>
</div>
<div><br>
</div>
<div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>renderer->ResetCamera();</div>
<div><br>
</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>renderWindow->Render();<br>
</div>
<div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>renderWindowInteractor->Start();<span class="gmail-Apple-tab-span" style="white-space:pre"> </span></div>
</div>
<div><br>
</div>
<div><br>
</div>
<div>Thanks, </div>
<div>Tejas</div>
<div><br>
</div>
<div><br>
</div>
</div>
<br>
<fieldset class="mimeAttachmentHeader"></fieldset>
<br>
<pre wrap="">_______________________________________________
Powered by <a class="moz-txt-link-abbreviated" href="http://www.kitware.com">www.kitware.com</a>
Visit other Kitware open-source projects at <a class="moz-txt-link-freetext" href="http://www.kitware.com/opensource/opensource.html">http://www.kitware.com/opensource/opensource.html</a>
Please keep messages on-topic and check the VTK FAQ at: <a class="moz-txt-link-freetext" href="http://www.vtk.org/Wiki/VTK_FAQ">http://www.vtk.org/Wiki/VTK_FAQ</a>
Search the list archives at: <a class="moz-txt-link-freetext" href="http://markmail.org/search/?q=vtkusers">http://markmail.org/search/?q=vtkusers</a>
Follow this link to subscribe/unsubscribe:
<a class="moz-txt-link-freetext" href="http://public.kitware.com/mailman/listinfo/vtkusers">http://public.kitware.com/mailman/listinfo/vtkusers</a>
</pre>
</blockquote>
<br>
<div class="moz-signature">-- <br>
<strong>Paul
x4422</strong></div>
</body>
</html>