[vtkusers] method to extract regions

David Gobbi david.gobbi at gmail.com
Sun Jan 3 09:59:59 EST 2016


Hi Imre,

The input that is set via SetInputConnection() must be a vtkImageData.
Connected component labelling is done on this input.  For examples of
connected component labelling, see
https://en.wikipedia.org/wiki/Connected-component_labeling

There are two other inputs.  The optional SetStencilConnection() input,
which I mentioned in previous emails, applies a mask to the entire
operation, and must be a vtkImageStencilData.

The optional SetSeedConnection() input provides points to be used as seeds,
and it can be anything.  When seeds are used, the filter acts like a
traditional flood-fill filter  (i.e. it labels regions that are connected
to the seed points).

 - David

On Sun, Jan 3, 2016 at 4:28 AM, Imre Goretzki <goretzki.imre at gmail.com>
wrote:

> Hi David,
>
> is it possible to connect the vtkImageConnectivityFilter to other filters
> of VTK that do not have vtkImageData as output?
>
> I have a pipleline that creates vtkPolyData as output, so I cannot use
> your filter directly. Using this example:
> http://www.vtk.org/Wiki/VTK/Examples/Cxx/PolyData/PolyDataToImageData
> creates one single region. I printed the number of regions and the size by
>
> s = c->GetExtractedRegionSizes();
> for (int i = 0; i < c->GetNumberOfExtractedRegions(); i++)
> {
>     cout << "num: " << c->GetNumberOfExtractedRegions() << endl;  //1
>     cout << "size: " << s->GetTuple1(i);  //1.27008e+07
> }
>
> - Imre
>
> Am 02.01.2016 um 21:45 schrieb David Gobbi:
>
> On Sat, Jan 2, 2016 at 1:06 PM, Imre Goretzki <goretzki.imre at gmail.com>
> wrote:
>>
>>
>> Yes they can be partially outside the mask because I neither know the
>> sizes and locations of the regions I want to keep nor the sizes and
>> locations of the regions I want to discard for both input image and mask
>> image (the mask changes dynamically)
>>
>> Ok so in later progress I could use the mask as the second input (the
>> stencil) and this removes the regions?
>>
>
> The vtkImageConnectivityFilter ignores any pixels that are outside the
> stencil (so that might be the reverse of what you want, since you want to
> ignore the regions that are inside your mask).
>
> If a region is partly outside the stencil, then only the part that is
> outside will be ignored.  The rest would be counted.  As far as I
> understand, that is not what you want.  You would want the entire region to
> be ignored, right?
>
> Is there any reason that you even need a "mask"?  Would it be just as good
> if you could specify the unwanted regions by giving just one point in each
> unwanted region, i.e. the user would use the mouse to click on the unwanted
> regions?
>
> Actually, instead of using an input mask, it seems that it would be best
> to allow vtkImageConnectivityFilter to assign a different label value to
> each region.  Then, once you know which labels correspond to which regions,
> you could pass this label image through a lookup table that colors all of
> the unwanted regions black.
>
>  - David
>
>
>
>
>> My current code lets me get the regions I want to discard by storing the
>> polydata output of vtkPolyDataConnectivityFilter and then iterate over the
>> cells and their points
>>
>> for (int i = 0; i < filter->GetNumberOfExtractedRegions(); i++)
>> {
>>     vtkSmartPointer<vtkPolyData> extractRegionData =
>> vtkSmartPointer<vtkPolyData>::New(); //fast
>>     extractFilter->InitializeSpecifiedRegionList(); //fast
>>     extractFilter->AddSpecifiedRegion(i); //fast
>>     extractFilter->Modified(); //fast
>>     extractFilter->Update(); //very long
>>     extractRegionData->DeepCopy(extractFilter->GetOutput()); //fast
>>     regionList.push_back(extractRegionData); //fast
>> }
>> for (int i = 0; i < filter->GetNumberOfExtractedRegions(); i++)
>> {
>>     // some other operations
>> }
>>
>> The update() process takes a very long time. As an example, if I have
>> about 200 regions, this would take about 10 minutes. All other following
>> operations on the data and/or a vtkPolyDataConnectivityFilter do not take
>> so long.
>>
>> - Imre
>>
>>
>> Am 02.01.2016 um 20:48 schrieb David Gobbi:
>>
>> Thanks, that helps.  Here is my understanding so far:
>>
>> 1) The mask is, originally, a polydata contour.
>> 2) The mask indicates the regions you do not want.
>> 3) The mask will be converted into a binary image before use.
>>
>> What I still need to know is:
>>
>> 3) Will some regions be partially within and partially outside the mask?
>> Or will they always be entirely within or entirely outside?
>>
>> The vtkImageConnectivityFilter takes two inputs: the first input is just
>> an image (of course) and the second input (which is optional) is an image
>> stencil (essentially a binary image).  There is a filter called
>> vtkPolyDataToImageStencil which can be used create this second input from a
>> vtkPolyData object.
>>
>>  - David
>>
>>
>> On Sat, Jan 2, 2016 at 12:32 PM, Imre Goretzki <
>> <goretzki.imre at gmail.com>goretzki.imre at gmail.com> wrote:
>>
>>> I've drawn another image you could look at. The left image is the input
>>> data from which I would like to extract the regions. Here every region I
>>> would like to keep is painted green. The other two regions, that are
>>> painted red, have points that are located inside a region in the binary
>>> mask.
>>>
>>>
>>> For all points *P* in all regions *R* of image 1 with binary mask *B*
>>>
>>> If B_P == 255
>>>     color region *R* red
>>> else
>>>     color region *R* green
>>>
>>> - Imre
>>>
>>>
>>> Am 02.01.2016 um 20:16 schrieb David Gobbi:
>>>
>>> Sorry, but I still don't follow your explanation.  I have some vague
>>> idea of what you are trying to do, but I don't understand well enough to
>>> give you any concrete advice.  Can you try focussing on just one specific
>>> aspect of the problem, and then once I've understood that one aspect, we
>>> can move forward from there?
>>>
>>>  - David
>>>
>>> On Sat, Jan 2, 2016 at 11:46 AM, Imre Goretzki <
>>> <goretzki.imre at gmail.com>goretzki.imre at gmail.com> wrote:
>>>
>>>> Mh ok, I guess I did not explained my problem well enough.
>>>>
>>>> The vtkPolyDataConnectivityFilter returns regions, either the largest,
>>>> specified, seeded or all regions (your filter returns largest, seeded or
>>>> all). I'm interessted in the following:
>>>>
>>>> - all regions
>>>> - specified regions.
>>>>
>>>> The problem is not the filter, the performance or possible memory
>>>> leaks, I need the region's polydata representation because I have a second
>>>> object (vtkImageData or vtkPolyData, binary mask) that has some additional
>>>> information, that are not represented by the data (the input for the
>>>> vtkImageConnectivityFilter).
>>>>
>>>> Imagine the input for the filter as image 1 and the mask as image 2.
>>>> Both images have the same dimensions in all 3 directions (x, y, z) but
>>>> contain different information.
>>>>
>>>> image 2 will be transformed to a binary image mask
>>>>
>>>> from image 1 i need to extract regions, but if some (unknown) regions
>>>> have points that are located in the binary image mask, I do not want these
>>>> regions to be contained in the extracted region list.
>>>>
>>>> So it's not about your filter or the performance, but I have some
>>>> problems using this filter for my issue, because I cannot reach the
>>>> region's polydata.
>>>>
>>>> I hope this helps.
>>>>
>>>> - Imre
>>>>
>>>>
>>>> Am 02.01.2016 um 18:54 schrieb David Gobbi:
>>>>
>>>> Hi Imre, Happy New Year!
>>>>
>>>> I've read your email few times, and I feel that I must be missing some
>>>> important because there are several things that I don't understand about it.
>>>>
>>>> The vtkImageConnectivityFilter is essentially just a connected
>>>> component filter.  In the output of this filter, all pixels outside the
>>>> mask will be colored black (they will have a value of zero).  So what I
>>>> don't understand about your email is why you say that non-rectangular
>>>> regions are a problem.  Are you just worried about the wasted memory?
>>>>
>>>>  - David
>>>>
>>>>
>>>> On Sat, Jan 2, 2016 at 9:00 AM, Imre Goretzki <
>>>> <goretzki.imre at gmail.com>goretzki.imre at gmail.com> wrote:
>>>>
>>>>> Hey David,
>>>>>
>>>>> first of all: Happy new year :)
>>>>>
>>>>> I have some questions about your filter. First of all in part A of the
>>>>> attached image, is my understanding of extents, so if you have a region,
>>>>> you will get the x_min/x_max, y_min/y_max (and z_min/z_max for 3D). If you
>>>>> do not have rectangular regions than you could have some problems (see part
>>>>> A and B). In part B you see my mask. The red rectangle shows the case that
>>>>> the 4 corners of a 2D region cannot be directly checked, because the region
>>>>> that lies within this rectangle has little matches with the mask (none of
>>>>> the 4 corners are within the mask). The green rectangle has 3 out of 4
>>>>> edges that lie within the mask.
>>>>>
>>>>> Part C shows one of the worst cases of this approach (using extents)
>>>>> because there is so much space that does not belong to the actual region.
>>>>>
>>>>> My question: Is it possible to extend your filter to directly store
>>>>> the region data (for each region, for example as vtkImageData) if the
>>>>> extraction mode is set to "All"?
>>>>>
>>>>> - Imre
>>>>>
>>>>>
>>>>> Am 29.12.2015 um 13:27 schrieb Imre Goretzki:
>>>>>
>>>>> Hi David,
>>>>>
>>>>> thank you. I'll take a look at your class.
>>>>>
>>>>> Regards
>>>>> Imre
>>>>>
>>>>> Am 29.12.2015 um 13:07 schrieb David Gobbi:
>>>>>
>>>>> Hi Imre,
>>>>>
>>>>> I have a connectivity filter that works directly on images, it can
>>>>> label connected regions according to size and it should be much faster
>>>>> (probably 1000x) than doing voxel checks via polydata:
>>>>>
>>>>> <https://github.com/dgobbi/AIRS/blob/master/ImageSegmentation/vtkImageConnectivityFilter.h>
>>>>> https://github.com/dgobbi/AIRS/blob/master/ImageSegmentation/vtkImageConnectivityFilter.h
>>>>> I'll probably be contributing this filter to VTK sometime in the near
>>>>> future.
>>>>>
>>>>>  - David
>>>>>
>>>>>
>>>>> On Tue, Dec 29, 2015 at 4:02 AM, Imre Goretzki <
>>>>> <goretzki.imre at gmail.com>goretzki.imre at gmail.com> wrote:
>>>>>
>>>>>> Is there an easier way in ITK?
>>>>>>
>>>>>> Thanks
>>>>>> Imre
>>>>>>
>>>>>>
>>>>>> Am 28.12.2015 um 23:38 schrieb Imre Goretzki:
>>>>>>
>>>>>> Hey guys,
>>>>>>
>>>>>> I use the vtkPolyDataConnectivityFilter from polydata to extract
>>>>>> several different and more or less unknown regions.
>>>>>> My problem is that I want to extract regions from this filter, but if
>>>>>> I do this, the update process for all regions takes up to 10minutes:
>>>>>>
>>>>>> filter->SetExtractionModeToAllRegions();
>>>>>> filter->Update();
>>>>>> ...
>>>>>>
>>>>>> for (int i = 0; i < filter->GetNumberOfExtractedRegions(); i++)
>>>>>> {
>>>>>>     extractFilter->InitializeSpecifiedRegionList();
>>>>>>     extractFilter->AddSpecifiedRegion(i);
>>>>>>     extractFilter->Modified();
>>>>>>     extractFilter->Update();
>>>>>>     extractRegionData->DeepCopy(extractFilter->GetOutput());
>>>>>> }
>>>>>> extractFilter->InitializeSpecifiedRegionList();
>>>>>>
>>>>>> Background for this: I want to use the points of each region to check
>>>>>> whether they lie within an object in my binary
>>>>>> mask image. So the pipeline would be like this:
>>>>>>
>>>>>> 1) Get all Regions
>>>>>>     2) get region *i*
>>>>>>          3) get points of region *i*
>>>>>>              4) check if point *j* lies within the binary mask *B*
>>>>>> (*B*_*j* == 255)
>>>>>>                  4a) if true then add region to the extractFilter and
>>>>>> break (-> next region *i*)
>>>>>>                  4b) if false then continue with next point *j*
>>>>>> 5) Mark all regions red (done easily)
>>>>>> 6) Mark some regions green that are above a specific size (can be
>>>>>> accessed with filter->GetRegionSizes() )
>>>>>> 7) Mark some regions yellow (the regions that are extracted during
>>>>>> step 1-4a)
>>>>>>
>>>>>> I do not know if the PolyDataConnectivityFilter is the right class
>>>>>> for this, I think it is.
>>>>>> If I store the extractRegionData in a vector, all regions have the
>>>>>> same number of points (which is kind of strange) but different number of
>>>>>> cells (region size == number of cells is correct).
>>>>>>
>>>>>> I would now try to get the points from the cells and check the binary
>>>>>> mask, because the
>>>>>>
>>>>>> vtkPolyData->GetNumberOfPoints()
>>>>>>
>>>>>> and
>>>>>>
>>>>>> vtkPolyData->GetPoint(pointCounter, point);
>>>>>>
>>>>>> are not working correctly in this scenario (all regions are extracted
>>>>>> because every single region has every point?
>>>>>> i did not verify my guess but I think there would be the problem)
>>>>>>
>>>>>> The binary mask is a vtkImageData, that could be transformed to
>>>>>> vtkPolyData.
>>>>>> The input image (already filtered with vtkMarchingCubes) and the
>>>>>> binary mask have the same dimensions (x,y,z).
>>>>>>
>>>>>> I hope you can imagine what I'm trying to do and have some tips for
>>>>>> me, if my approach is correct.
>>>>>>
>>>>>> Regards
>>>>>> Imre
>>>>>>
>>>>>>
>>>>
>>>>
>>>
>>>
>>
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtkusers/attachments/20160103/182835b5/attachment.html>


More information about the vtkusers mailing list