# Hough Transform 2D Circles Image Filter GetCircles patch.

**URL:** https://discourse.itk.org/t/hough-transform-2d-circles-image-filter-getcircles-patch/350
**Category:** Algorithms
**Created:** [October 24, 2017, 5:26pm UTC](https://discourse.itk.org/t/hough-transform-2d-circles-image-filter-getcircles-patch/350 "2017-10-24T17:26:37Z")
**Posts on this page:** 20
**Page:** 4

<div class="post-metadata">

### Author: ![tim-evain](https://discourse.itk.org/user_avatar/discourse.itk.org/tim-evain/32/220_2.png) [@tim-evain](https://discourse.itk.org/u/tim-evain)
#### Post date: [February 19, 2018, 10:08am UTC](https://discourse.itk.org/t/hough-transform-2d-circles-image-filter-getcircles-patch/350/61 "2018-02-19T10:08:23Z")

</div>

As far as the documentation mentions that computation is done in grid (index) space, it doesn’t seem a problem (to me) to have different spacings.

---

<div class="post-metadata">

### Author: ![Niels\_Dekker](https://discourse.itk.org/letter_avatar_proxy/v4/letter/n/9d8465/32.png) [@Niels\_Dekker](https://discourse.itk.org/u/Niels_Dekker)
#### Post date: [February 23, 2018, 1:15pm UTC](https://discourse.itk.org/t/hough-transform-2d-circles-image-filter-getcircles-patch/350/62 "2018-02-23T13:15:04Z")

</div>

FYI, the helper functions GetCenterPoint() and SetCenterPoint(point) have been added to the master branch, this week:

> <https://github.com/Kitware/ITK/commit/842f15a86221741f9a52f424907e154d3dbb24bb>
>
> 1722d1ea ENH: Added GetCenterPoint and SetCenterPoint to EllipseSpatialObject

As well as a notice that GetCenterPoint() yields _pixel grid coordinates_, when used to retrieve the center of a circle from GetCircles():

> <https://github.com/Kitware/ITK/commit/a84ae022f8d48eb25626fadb76dd70c7e1eac014>
>
> a5971d91 DOC: Explained calling GetCenterPoint() when using Hough filter-\>GetCir…cles()

A change of behavior can be observed as follows, when the algorithm has detected a circle centered at pixel index [6, 8]:

```
const itk::SpatialObject<2>* const object = filter->GetCircles().front();
std::cout
  << "To Parent Offset: " << object->GetObjectToParentTransform()->GetOffset()
  << "\nTo World Offset: " << object->GetObjectToWorldTransform()->GetOffset()
  << std::endl;

```

This produced the following output before the patch:

> To Parent Offset: [6, 8]  
> To World Offset: [0, 0]

Whereas now, after the patch, it produces the following output:

> To Parent Offset: [0, 0]  
> To World Offset: [6, 8]

But of course, instead of calling GetOffset() on whichever transform, to retrieve the center point of a circle, ITKv5 users should just call EllipseSpatialObject::GetCenterPoint() 😃

---

<div class="post-metadata">

### Author: ![Niels\_Dekker](https://discourse.itk.org/letter_avatar_proxy/v4/letter/n/9d8465/32.png) [@Niels\_Dekker](https://discourse.itk.org/u/Niels_Dekker)
#### Post date: [February 24, 2018, 1:16pm UTC](https://discourse.itk.org/t/hough-transform-2d-circles-image-filter-getcircles-patch/350/63 "2018-02-24T13:16:14Z")

</div>

@matt.mccormick, @tim-evain I’m glad that you like the patch [https://github.com/Kitware/ITK/commit/842f15a86221741f9a52f424907e154d3dbb24bb](https://github.com/Kitware/ITK/commit/842f15a86221741f9a52f424907e154d3dbb24bb) However, I still don’t fully understand the consequences of having replaced _GetObjectToParentTransform()-\>m\_Offset_ by _GetObjectToWorldTransform()-\>m\_Offset_ as storage for the center coordinates.

Before the patch (for example, with ITK 4.13), it could be checked that the center of a circle is inside its spatial object by calling _spatialObject-\>IsInside(center)_ as follows:

```
// Create an image with a circle centered at [6, 8]:
enum { centerX = 6, centerY = 8 };
const auto image = itk::Image<unsigned>::New();
image->SetRegions({ 16, 16 });
image->Allocate(true);
image->SetPixel({ centerX, centerY }, 1);
image->SetPixel({ centerX, centerY - 1 }, 1);
image->SetPixel({ centerX, centerY + 1 }, 1);
image->SetPixel({ centerX - 1, centerY }, 1);
image->SetPixel({ centerX + 1, centerY }, 1);

const auto filter = 
  itk::HoughTransform2DCirclesImageFilter<unsigned, unsigned, double>::New();
filter->SetInput(image);
filter->Update();

// GetCircles() finds a circle of radius 1, centered at [6, 8].
const auto& spatialObject = filter->GetCircles().front();
spatialObject->ComputeObjectToWorldTransform();

const double center[] = { centerX, centerY };
const bool isInside = spatialObject->IsInside(center);

std::cout << (isInside ?
  "OK: The center is inside." :
  "ERROR: The center is not inside!") << std::endl;

```

Before the patch, this example would print _“OK: The center is inside.”_ Now, after the patch, the example prints _“ERROR: The center is not inside!”_. Is that OK? Or should _IsInside_ be used in a different way?

_Update 26 Feb 2018:_ The code example is also at [https://gist.github.com/N-Dekker/b276d312dc37958b6657f889f2687ba4](https://gist.github.com/N-Dekker/b276d312dc37958b6657f889f2687ba4)

---

<div class="post-metadata">

### Author: ![matt.mccormick](https://discourse.itk.org/user_avatar/discourse.itk.org/matt.mccormick/32/7_2.png) [@matt.mccormick](https://discourse.itk.org/u/matt.mccormick)
#### Post date: [February 26, 2018, 7:17pm UTC](https://discourse.itk.org/t/hough-transform-2d-circles-image-filter-getcircles-patch/350/64 "2018-02-26T19:17:56Z")

</div>

@Niels_Dekker Thanks for looking into this and sharing the example code. 👍

I looked into it, and after

```auto
  this->GetModifiableObjectToWorldTransform()->SetOffset(point - originPoint);

```

we need to call

```auto
  this->ComputeObjectToParentTransform();

```

so the `ObjectToParentTransform` is updated after we modified the `ObjectToWorldTransform`. This is used by `IsInside`.

Also, we should consider re-naming the method from `SetCenterPoint` to `SetCenter` to be consistent with the rest of the toolkit.

---

<div class="post-metadata">

### Author: ![Niels\_Dekker](https://discourse.itk.org/letter_avatar_proxy/v4/letter/n/9d8465/32.png) [@Niels\_Dekker](https://discourse.itk.org/u/Niels_Dekker)
#### Post date: [February 27, 2018, 12:43pm UTC](https://discourse.itk.org/t/hough-transform-2d-circles-image-filter-getcircles-patch/350/65 "2018-02-27T12:43:59Z")

</div>

Thanks, Matt. I did not know about ComputeObjectToParentTransform(). But then, what is the difference between:

Old approach (see also [the very first version of GetCircles()](https://github.com/Kitware/ITK/commit/49f7706bbb44fc6f724a54190e9ef0c734e8ddb0#diff-e717c78dc038516ceb9dc06db9729963R259), Julien Jomier, 2003):

```
spatialObject->GetObjectToParentTransform()->SetOffset(center);
spatialObject->ComputeObjectToWorldTransform();

```

New approach (after [the patch](https://github.com/Kitware/ITK/commit/842f15a86221741f9a52f424907e154d3dbb24bb#diff-dc27e2abb22e9e02d01c1091c9560fd1R72)):

```
spatialObject->GetModifiableObjectToWorldTransform()->SetOffset(center);
spatialObject->ComputeObjectToParentTransform();

```

Why do you think the new approach is better than the old one? Note that the center is currently still expressed in pixel grid coordinates (as it was before).

---

<div class="post-metadata">

### Author: ![matt.mccormick](https://discourse.itk.org/user_avatar/discourse.itk.org/matt.mccormick/32/7_2.png) [@matt.mccormick](https://discourse.itk.org/u/matt.mccormick)
#### Post date: [February 28, 2018, 5:16pm UTC](https://discourse.itk.org/t/hough-transform-2d-circles-image-filter-getcircles-patch/350/66 "2018-02-28T17:16:45Z")

</div>

> [@Niels\_Dekker](#):
>
> But then, what is the difference between:
> 
> Old approach (see also the very first version of GetCircles(), Julien Jomier, 2003):
> 
> spatialObject-\>GetObjectToParentTransform()-\>SetOffset(center);  
> spatialObject-\>ComputeObjectToWorldTransform();
> 
> New approach (after the patch):
> 
> spatialObject-\>GetModifiableObjectToWorldTransform()-\>SetOffset(center);  
> spatialObject-\>ComputeObjectToParentTransform();

There are two transformation’s inside `itk::SpatialObject`, related to `ObjectToParent` and `ObjectToWorld`. They are related, but two are kept for performance reasons. `ComputeObjectToWorldTransform` needs to be called in `EllipseSpatialObject<TDimension>::GetCenterPoint() ` so they are properly in sync.

> [@Niels\_Dekker](#):
>
> Note that the center is currently still expressed in pixel grid coordinates (as it was before).

This is a bug, which will cause issues for images with non-unit spacing or non-identity orientation. These lines:

> <https://github.com/InsightSoftwareConsortium/ITK/blob/e41790229b92fd98865037153ac631e68ac0e9fa/Modules/Filtering/ImageFeature/include/itkHoughTransform2DCirclesImageFilter.hxx#L251-L253>

should be replaced by a call to [itk::Image::TransformIndexToPhysicalPoint](https://itk.org/Doxygen/html/classitk_1_1ImageBase.html#ab003313ba1a078d89a832dc0a35d2efa).

> [@Niels\_Dekker](#):
>
> Why do you think the new approach is better than the old one?

It is important to operate in physical space to avoid bugs related to non-unit spacing in images, non-identity orientation of images, images with different sizes, images with non-null origins, comparisons with circles that exist in physical space, meshes that exist in physical space, bounding boxes that exist in physical space, point sets that exist in physical space, etc. ITK’s powerful architecture helps avoid these issues by consistently defining operations and values in physical space. This is why the **Spatial** Object framework [was created](https://itk.org/ITKSoftwareGuide/html/Book1/ITKSoftwareGuide-Book1ch5.html#x43-780005).

---

<div class="post-metadata">

### Author: ![Niels\_Dekker](https://discourse.itk.org/letter_avatar_proxy/v4/letter/n/9d8465/32.png) [@Niels\_Dekker](https://discourse.itk.org/u/Niels_Dekker)
#### Post date: [February 28, 2018, 8:47pm UTC](https://discourse.itk.org/t/hough-transform-2d-circles-image-filter-getcircles-patch/350/67 "2018-02-28T20:47:57Z")

</div>

Thanks, Matt. If I understand correctly, there are three issues now related to the center of the circles found by HoughTransform2D GetCircles():

1. ComputeObjectTo… functions should still be called inside either or both GetCenterPoint + SetCenterPoint
2. HoughTransform2D GetCircles() should include spacial information from the input image.
3. GetCenterPoint/SetCenterPoint should be renamed to GetCenter/SetCenter.

Do you think each of these issues should be fixed (preferably?) by the first release of ITKv5?

---

<div class="post-metadata">

### Author: ![matt.mccormick](https://discourse.itk.org/user_avatar/discourse.itk.org/matt.mccormick/32/7_2.png) [@matt.mccormick](https://discourse.itk.org/u/matt.mccormick)
#### Post date: [February 28, 2018, 9:26pm UTC](https://discourse.itk.org/t/hough-transform-2d-circles-image-filter-getcircles-patch/350/68 "2018-02-28T21:26:19Z")

</div>

👍 Yes

---

<div class="post-metadata">

### Author: ![Niels\_Dekker](https://discourse.itk.org/letter_avatar_proxy/v4/letter/n/9d8465/32.png) [@Niels\_Dekker](https://discourse.itk.org/u/Niels_Dekker)
#### Post date: [March 2, 2018, 2:28pm UTC](https://discourse.itk.org/t/hough-transform-2d-circles-image-filter-getcircles-patch/350/69 "2018-03-02T14:28:11Z")

</div>

Thanks for merging my proposed patch, which added a _ComputeObjectToParentTransform()_ call to _EllipseSpatialObject::SetCenterPoint(point)_:  
[https://github.com/Kitware/ITK/commit/b040480ea3f4f86c6f361e57021371c9bcd6f7c1](https://github.com/Kitware/ITK/commit/b040480ea3f4f86c6f361e57021371c9bcd6f7c1)

Do you still think that a call to _ComputeObjectToWorldTransform()_ needs to be added to _EllipseSpatialObject::GetCenterPoint()_ now? If so, can you please show me some test code that currently produces the wrong results, _and_ would be fixed by adding _ComputeObjectToWorldTransform()_ to _GetCenterPoint()_?

---

<div class="post-metadata">

### Author: ![matt.mccormick](https://discourse.itk.org/user_avatar/discourse.itk.org/matt.mccormick/32/7_2.png) [@matt.mccormick](https://discourse.itk.org/u/matt.mccormick)
#### Post date: [March 2, 2018, 2:45pm UTC](https://discourse.itk.org/t/hough-transform-2d-circles-image-filter-getcircles-patch/350/70 "2018-03-02T14:45:19Z")

</div>

Thanks for submitting the patch, @Neils\_Dekker! That fix was the only place we needed to call `ComputeObjectToWorldTransform`.

---

<div class="post-metadata">

### Author: ![Niels\_Dekker](https://discourse.itk.org/letter_avatar_proxy/v4/letter/n/9d8465/32.png) [@Niels\_Dekker](https://discourse.itk.org/u/Niels_Dekker)
#### Post date: [March 2, 2018, 2:51pm UTC](https://discourse.itk.org/t/hough-transform-2d-circles-image-filter-getcircles-patch/350/71 "2018-03-02T14:51:41Z")

</div>

> [@matt.mccormick](#):
>
> Thanks for submitting the patch, @Neils\_Dekker! That fix was the only place we needed to call ComputeObjectToWorldTransform.

You’re welcome, Matt! You mean **_ComputeObjectToParentTransform()_**, right? At least, that’s the one I added to _SetCenterPoint(point)_, with [ENH: IsInside(point) made easier, especially for HoughTransform circles · Kitware/ITK@210ba16 · GitHub](https://github.com/Kitware/ITK/commit/210ba16c02641dfc14d7b1381aa19545fbdb0338)

---

<div class="post-metadata">

### Author: ![matt.mccormick](https://discourse.itk.org/user_avatar/discourse.itk.org/matt.mccormick/32/7_2.png) [@matt.mccormick](https://discourse.itk.org/u/matt.mccormick)
#### Post date: [March 2, 2018, 3:48pm UTC](https://discourse.itk.org/t/hough-transform-2d-circles-image-filter-getcircles-patch/350/72 "2018-03-02T15:48:52Z")

</div>

> [@Niels\_Dekker](#):
>
> You mean ComputeObjectToParentTransform(), right?

Correct.

---

<div class="post-metadata">

### Author: ![Niels\_Dekker](https://discourse.itk.org/letter_avatar_proxy/v4/letter/n/9d8465/32.png) [@Niels\_Dekker](https://discourse.itk.org/u/Niels_Dekker)
#### Post date: [March 2, 2018, 4:34pm UTC](https://discourse.itk.org/t/hough-transform-2d-circles-image-filter-getcircles-patch/350/73 "2018-03-02T16:34:17Z")

</div>

That brings us to the next issue: _HoughTransform2D GetCircles() should include spacial information from the input image._

You already suggested calling _itk::Image::TransformIndexToPhysicalPoint_ to convert the found index (2-D) of the center to the physical center point. Would it _also_ be useful (or even _necessary_) to call _itk::SpatialObject::SetSpacing_, to copy the pixel spacing from the input image into each found circle? Something like this:

```
 Circle->SetSpacing(inputImage->GetSpacing());

```

But then, what would be the actual effect of calling SetSpacing, to the user?

_Update, March 5, 2018:_ The ability to directly pass the spacing of an itk::Image to an itk::SpatialObject was added by Luis Ibanez, 2004-01-24 [https://github.com/Kitware/ITK/commit/6956f3390162bbce004704d411ded919a3883fcf](https://github.com/Kitware/ITK/commit/6956f3390162bbce004704d411ded919a3883fcf) but then again removed by Stephen Aylward, 2005-03-09, [https://github.com/Kitware/ITK/commit/2b536fbe9d81d74fdf7af42e0950f2a18c5eb861#diff-46707908d0b621a26a7d7943c70bcae1](https://github.com/Kitware/ITK/commit/2b536fbe9d81d74fdf7af42e0950f2a18c5eb861#diff-46707908d0b621a26a7d7943c70bcae1) However, it is still possible to do _spatialObject-\>SetSpacing( inputImage-\>GetSpacing()**.GetDataPointer()** )_.

---

<div class="post-metadata">

### Author: ![matt.mccormick](https://discourse.itk.org/user_avatar/discourse.itk.org/matt.mccormick/32/7_2.png) [@matt.mccormick](https://discourse.itk.org/u/matt.mccormick)
#### Post date: [March 5, 2018, 4:55pm UTC](https://discourse.itk.org/t/hough-transform-2d-circles-image-filter-getcircles-patch/350/74 "2018-03-05T16:55:28Z")

</div>

Good questions, @Niels_Dekker

Since the `EllipseSpatialObject` is defined by its _Center_ and _Radius_, which are both defined in terms of physical space units, this is all we need to set. We do not need to set the _Spacing_, whose meaning is ill-defined for an ellipse / circle.

---

<div class="post-metadata">

### Author: ![Niels\_Dekker](https://discourse.itk.org/letter_avatar_proxy/v4/letter/n/9d8465/32.png) [@Niels\_Dekker](https://discourse.itk.org/u/Niels_Dekker)
#### Post date: [March 5, 2018, 5:54pm UTC](https://discourse.itk.org/t/hough-transform-2d-circles-image-filter-getcircles-patch/350/75 "2018-03-05T17:54:09Z")

</div>

> [@matt.mccormick](#):
>
> Since the EllipseSpatialObject is defined by its Center and Radius, which are both defined in terms of physical space units, this is all we need to set. We do not need to set the Spacing, whose meaning is ill-defined for an ellipse / circle.

OK, thanks for your explanation, @matt.mccormick . Well, it does surprise me somewhat, as in the past, a use case that did actually try to set the spacing of an _EllipseSpatialObject_ was found convincing enough to improve spacing support for SpatialObject. As Luis Ibanez replied to Corinne Mattmann:  
[https://public.kitware.com/pipermail/insight-users/2004-January/006382.html](https://public.kitware.com/pipermail/insight-users/2004-January/006382.html)

Anyway, do you agree that the radii of an object detected by GetCircles() could be as follows:

```
  const double radius = m_RadiusImage->GetPixel(indexOfMaximum);
  const double radii[] = { radius * spacing[0], radius * spacing[1] };
  Circle->SetRadius(radii);

```

Instead of this line of code:

> <https://github.com/Kitware/ITK/blob/v4.13.0/Modules/Filtering/ImageFeature/include/itkHoughTransform2DCirclesImageFilter.hxx#L249>

Note that it would imply that a circle detected by GetCircles() might have two different radii. Would that be OK to you?

---

<div class="post-metadata">

### Author: ![matt.mccormick](https://discourse.itk.org/user_avatar/discourse.itk.org/matt.mccormick/32/7_2.png) [@matt.mccormick](https://discourse.itk.org/u/matt.mccormick)
#### Post date: [March 5, 2018, 6:53pm UTC](https://discourse.itk.org/t/hough-transform-2d-circles-image-filter-getcircles-patch/350/76 "2018-03-05T18:53:47Z")

</div>

> [@Niels\_Dekker](#):
>
> Anyway, do you agree that the radii of an object detected by GetCircles() could be as follows:
> 
> const double radius = m\_RadiusImage-\>GetPixel(indexOfMaximum);  
> const double radii = { radius \* spacing[0], radius \* spacing[1] };  
> Circle-\>SetRadius(radii);

No, a circle only has a single radius, which is defined in physical space.

---

<div class="post-metadata">

### Author: ![dzenanz](https://discourse.itk.org/user_avatar/discourse.itk.org/dzenanz/32/1093_2.png) [@dzenanz](https://discourse.itk.org/u/dzenanz)
#### Post date: [March 5, 2018, 7:33pm UTC](https://discourse.itk.org/t/hough-transform-2d-circles-image-filter-getcircles-patch/350/77 "2018-03-05T19:33:24Z")

</div>

Perhaps throw an exception if spacing along axes is different?

---

<div class="post-metadata">

### Author: ![matt.mccormick](https://discourse.itk.org/user_avatar/discourse.itk.org/matt.mccormick/32/7_2.png) [@matt.mccormick](https://discourse.itk.org/u/matt.mccormick)
#### Post date: [March 5, 2018, 8:06pm UTC](https://discourse.itk.org/t/hough-transform-2d-circles-image-filter-getcircles-patch/350/78 "2018-03-05T20:06:33Z")

</div>

> [@dzenanz](#):
>
> Perhaps throw an exception if spacing along axes is different?

This is not necessary if the radius is in physical space units.

---

<div class="post-metadata">

### Author: ![dzenanz](https://discourse.itk.org/user_avatar/discourse.itk.org/dzenanz/32/1093_2.png) [@dzenanz](https://discourse.itk.org/u/dzenanz)
#### Post date: [March 5, 2018, 8:14pm UTC](https://discourse.itk.org/t/hough-transform-2d-circles-image-filter-getcircles-patch/350/79 "2018-03-05T20:14:29Z")

</div>

If I remember correctly, processing is in index space, not physical space, hence the suggestion. Otherwise my suggestion is moot.

---

<div class="post-metadata">

### Author: ![matt.mccormick](https://discourse.itk.org/user_avatar/discourse.itk.org/matt.mccormick/32/7_2.png) [@matt.mccormick](https://discourse.itk.org/u/matt.mccormick)
#### Post date: [March 5, 2018, 9:07pm UTC](https://discourse.itk.org/t/hough-transform-2d-circles-image-filter-getcircles-patch/350/80 "2018-03-05T21:07:03Z")

</div>

Since the resulting circles are used as an output, the radius should be in physical space.

[Previous page](https://discourse.itk.org/t/hough-transform-2d-circles-image-filter-getcircles-patch/350.md?page=3)

[Next page](https://discourse.itk.org/t/hough-transform-2d-circles-image-filter-getcircles-patch/350.md?page=5)
