[vtkusers] method to extract regions

David Gobbi david.gobbi at gmail.com
Sat Jan 2 15:45:49 EST 2016


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>
> 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/20160102/5dad389e/attachment.html>


More information about the vtkusers mailing list