SMIL  1.0.4
DHoughTransform.hpp
1 /*
2  * Copyright (c) 2011-2016, Matthieu FAESSEL and ARMINES
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of Matthieu FAESSEL, or ARMINES nor the
14  * names of its contributors may be used to endorse or promote products
15  * derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #ifndef _D_HOUGH_TRANSFORM_HPP
31 #define _D_HOUGH_TRANSFORM_HPP
32 
33 #include "Core/include/private/DImage.hxx"
34 #include "Base/include/DBase.h"
35 
36 namespace smil
37 {
55  template <class T1, class T2>
56  RES_T houghLines(Image<T1> &imIn, double thetaRes, double rhoRes,
57  Image<T2> &imOut)
58  {
59  size_t wIn = imIn.getWidth();
60  size_t hIn = imIn.getHeight();
61 
62  double rhoMax = std::sqrt(wIn * wIn + hIn * hIn);
63 
64  size_t wOut = thetaRes * 180;
65  size_t hOut = rhoRes * rhoMax;
66 
67  ImageFreezer freeze(imOut);
68  imOut.setSize(wOut, hOut);
69  fill(imOut, T2(0));
70 
71  typename Image<T1>::sliceType linesIn = imIn.getLines();
72  typename Image<T2>::sliceType linesOut = imOut.getLines();
73  typename Image<T1>::lineType lIn;
74 
75  double thetaStep = PI / wOut;
76  double rhoStep = rhoMax / hOut;
77 
78  for (off_t j = 0; j < (off_t) hIn; j++) {
79  lIn = linesIn[j];
80 
81  double coef = 1. / rhoStep;
82  for (off_t i = 0; i < (off_t) wIn; i++) {
83  if (lIn[i] != 0) {
84 #ifdef USE_OPEN_MP
85 #pragma omp for
86 #endif // USE_OPEN_MP
87  for (off_t t = 0; t < (off_t) wOut; t++) {
88  double theta = t * thetaStep;
89  double rho = coef * (i * cos(theta) + j * sin(theta));
90 
91  if (rho >= 0 && rho < hOut) {
92  off_t irho = int(fabs(rho));
93  linesOut[irho][t] += 1;
94  }
95  }
96  }
97  }
98  }
99  return RES_OK;
100  }
101 
111  template <class T1, class T2>
112  RES_T houghCircles(Image<T1> &imIn, double xyResol, double rhoResol,
113  Image<T2> &imOut)
114  {
115  size_t wIn = imIn.getWidth();
116  size_t hIn = imIn.getHeight();
117 
118  double rhoMax = std::sqrt(wIn * wIn + hIn * hIn);
119 
120  size_t wOut = xyResol * wIn;
121  size_t hOut = xyResol * hIn;
122  off_t dOut = rhoResol * rhoMax;
123 
124  ImageFreezer freeze(imOut);
125  imOut.setSize(wOut, hOut, dOut);
126  fill(imOut, T2(0));
127 
128  typename Image<T1>::sliceType linesIn = imIn.getSlices()[0];
129  typename Image<T1>::lineType lIn;
130  typename Image<T2>::volType slicesOut = imOut.getSlices();
131 
132  off_t rho;
133  double coef = 1 / (xyResol * rhoResol);
134 
135  for (off_t j = 0; j < (off_t) hIn; j++) {
136  lIn = linesIn[j];
137  for (off_t i = 0; i < (off_t) wIn; i++) {
138  if (lIn[i] != T1(0)) {
139 #ifdef USE_OPEN_MP
140 #pragma omp for
141 #endif // USE_OPEN_MP
142  for (off_t j2 = 0; j2 < (off_t) hOut; j2++) {
143  for (off_t i2 = 0; i2 < (off_t) wOut; i2++) {
144  if (i != i2 && j != j2) {
145  rho = coef * std::sqrt((i * xyResol - i2) * (i * xyResol - i2) +
146  (j * xyResol - j2) * (j * xyResol - j2));
147  if (rho >= 0 && rho < dOut)
148  slicesOut[rho][j2][i2] += 1;
149  }
150  }
151  }
152  }
153  }
154  }
155  return RES_OK;
156  }
157 
162  template <class T1, class T2>
163  RES_T houghCircles(Image<T1> &imIn, double resol, Image<T2> &imOut,
164  Image<T2> &imRadiiOut)
165  {
166  size_t wIn = imIn.getWidth();
167  size_t hIn = imIn.getHeight();
168 
169  // Commente - rhoMax non utilise
170  // double rhoMax = sqrt(wIn*wIn + hIn*hIn);
171 
172  size_t wOut = resol * wIn;
173  size_t hOut = resol * hIn;
174 
175  ImageFreezer freeze(imRadiiOut);
176 
177  Image<double> imCentersOut(wOut, hOut);
178  imRadiiOut.setSize(wOut, hOut);
179 
180  fill(imCentersOut, 0.);
181  fill(imRadiiOut, T2(0));
182 
183  typename Image<T1>::sliceType linesIn = imIn.getSlices()[0];
184  typename Image<T1>::lineType lIn;
185  typename Image<double>::sliceType linesOut1 = imCentersOut.getSlices()[0];
186  typename Image<T2>::sliceType linesOut2 = imRadiiOut.getSlices()[0];
187 
188  double rho;
189  size_t nonZeroPts = 0;
190 
191  for (off_t j = 0; j < (off_t) imIn.getHeight(); j++) {
192  lIn = linesIn[j];
193  for (off_t i = 0; i < (off_t) imIn.getWidth(); i++) {
194  if (lIn[i] != T1(0)) {
195  nonZeroPts++;
196  for (off_t j2 = 0; j2 < (off_t) hOut; j2++) {
197  for (off_t i2 = 0; i2 < (off_t) wOut; i2++) {
198  if (i != i2 && j != j2) {
199  rho = std::sqrt(double((i * resol - i2) * (i * resol - i2) +
200  (j * resol - j2) * (j * resol - j2)));
201  // JOE : Why 100 and 500 ???
202  if (rho > 100 && rho < 500) {
203  linesOut1[j2][i2] += 1;
204  if (linesOut1[j2][i2] > nonZeroPts &&
205  linesOut2[j2][i2] < T2(rho))
206  linesOut2[j2][i2] = T2(rho);
207  }
208  }
209  }
210  }
211  }
212  }
213  }
214  stretchHist(imCentersOut, imOut);
215  return RES_OK;
216  }
217 
219 } // namespace smil
220 
221 #endif // _D_HOUGH_TRANSFORM_HPP
size_t getWidth() const
Get image width.
Definition: DBaseImage.h:80
size_t getHeight() const
Get image height.
Definition: DBaseImage.h:85
Definition: DBaseImage.h:386
volType getSlices() const
Get an array containing the start offset of each slice.
Definition: DImage.hpp:117
sliceType getLines() const
Get an array containing the start offset of each line.
Definition: DImage.hpp:111
virtual RES_T setSize(size_t w, size_t h, size_t d=1, bool doAllocate=true)
Set the size of image.
RES_T houghCircles(Image< T1 > &imIn, double resol, Image< T2 > &imOut, Image< T2 > &imRadiiOut)
Hough Circles.
Definition: DHoughTransform.hpp:163
RES_T houghLines(Image< T1 > &imIn, double thetaRes, double rhoRes, Image< T2 > &imOut)
Hough Lines.
Definition: DHoughTransform.hpp:56
RES_T sqrt(const Image< T1 > &imIn, Image< T2 > &imOut)
sqrt() - square root of an image
Definition: DImageArith.hpp:926
RES_T fill(Image< T > &imOut, const T &value)
fill() - Fill an image with a given value.
Definition: DImageArith.hpp:1456
RES_T stretchHist(const Image< T1 > &imIn, T1 inMinVal, T1 inMaxVal, Image< T2 > &imOut, T2 outMinVal=numeric_limits< T2 >::min(), T2 outMaxVal=numeric_limits< T2 >::max())
stretchHist() - Stretch histogram
Definition: DImageHistogram.hpp:373