1 #ifndef __FAST_LINE_SOILLE_T_HPP__
2 #define __FAST_LINE_SOILLE_T_HPP__
4 #include "Core/include/DCore.h"
30 #define PI 3.14159265358979323846
54 typedef unsigned char ubyte;
55 typedef unsigned int uint;
56 typedef unsigned long ulong;
58 ulong ComputeLinePosDiag(
long x,
long y, ulong width, ulong height,
74 for (; (x < (long) width) && (y < (long) height); x++) {
83 ulong ComputeLineNegDiag(
long x,
long y, ulong width, ulong height,
89 if (y >= (
long) height) {
93 if (x >= (
long) width)
98 while ((x < (
long) (width - 1)) && (y > 0)) {
108 ulong ComputeBresenhamLinePX(
long x,
long y,
long dx,
long dy, ulong phase,
109 ulong width, ulong height, ulong *p)
115 long dp = 2 * dy - 2 * phase, twody = 2 * dy, twodydx = 2 * dy - 2 * dx;
117 while ((x < 0) || (y < 0)) {
127 while ((x < (
long) width) && (y < (
long) height)) {
142 ulong ComputeBresenhamLineNX(
long x,
long y,
long dx,
long dy, ulong phase,
143 ulong width, ulong height, ulong *p)
147 ulong x0 = x, idx = y * width + x;
148 long dp = 2 * dy - 2 * phase, twody = 2 * dy, twodydx = 2 * dy - 2 * dx;
150 while (y >= (
long) height) {
158 if (x >= (
long) width)
164 while ((x < (
long) width - 1) && (y > 0)) {
179 ulong ComputeBresenhamLinePY(
long x,
long y,
long dx,
long dy, ulong phase,
180 ulong width, ulong height, ulong *p)
185 long dp = 2 * dx - 2 * phase, twodx = 2 * dx, twodxdy = 2 * dx - 2 * dy;
187 while ((x < 0) || (y < 0)) {
197 while ((y < (
long) height) && (x < (
long) width)) {
212 ulong ComputeBresenhamLineNY(
long x,
long y,
long dx,
long dy, ulong phase,
213 ulong width, ulong height, ulong *p)
218 long dp = 2 * dx - 2 * phase, twodx = 2 * dx, twodxdy = 2 * dx - 2 * dy;
220 while (x >= (
long) width) {
228 if (y >= (
long) height)
234 while ((y < (
long) height - 1) && (x > 0) && (x < (
long) width)) {
249 void DilateHorLine(T *f, ulong width, ulong k, T *g, T *h, T *h2, T *r)
255 for (x = 0; x < width; x++) {
258 g[x] = MAX(g[x - 1], f[x]);
263 if (((x2 % k) == (k - 1)) || (x2 == (width - 1))) {
266 h[x2] = MAX(h[x2 + 1], f[x2]);
269 if ((k == 1) || (width == 1))
272 h[0] = MAX(h[1], f[0]);
273 h2[width - 1] = f[width - 1];
274 for (x = width - 2; x >= (width - k); x--)
275 h2[x] = MAX(h2[x + 1], f[x]);
276 h2[0] = MAX(h2[1], f[0]);
278 if (width <= (k / 2)) {
279 for (x = 0; x < width; x++)
281 }
else if (width <= k) {
282 for (x = 0; x < (width - k / 2); x++)
284 for (; x <= (k / 2); x++)
286 for (; x < width; x++)
290 for (x = 0; x < (width - k / 2); x++) {
294 r[x] = MAX(g[x + k / 2], h[x - k / 2]);
296 for (x = width - k / 2; x < width; x++)
297 r[x] = h2[x - k / 2];
301 void DilateVerLine(T *f, ulong width, ulong height, ulong k, T *g, T *h,
308 for (y = 0; y < height; y++) {
311 g[y] = MAX(g[y - 1], f[y * width]);
315 if (((y2 % k) == (k - 1)) || (y2 == (height - 1)))
316 h[y2] = f[y2 * width];
318 h[y2] = MAX(h[y2 + 1], f[y2 * width]);
321 if ((k == 1) || (height == 1))
324 h[0] = MAX(h[1], f[0]);
325 h2[height - 1] = f[(height - 1) * width];
326 for (y = height - 2; y >= (height - k); y--)
327 h2[y] = MAX(h2[y + 1], f[y * width]);
328 h2[0] = MAX(h[1], f[0]);
330 if (height <= (k / 2)) {
331 for (y = 0; y < height; y++)
332 r[y * width] = g[height - 1];
333 }
else if (height <= k) {
334 for (y = 0; y < (height - k / 2); y++)
335 r[y * width] = g[y + k / 2];
336 for (; y <= (k / 2); y++)
337 r[y * width] = g[height - 1];
338 for (; y < height; y++)
339 r[y * width] = h[y - k / 2];
342 for (y = 0; y < (height - k / 2); y++) {
344 r[y * width] = g[y + k / 2];
346 r[y * width] = MAX(g[y + k / 2], h[y - k / 2]);
348 for (y = height - k / 2; y < height; y++)
349 r[y * width] = h2[y - k / 2];
353 void DilateLine(T *f, SMIL_UNUSED ulong width, SMIL_UNUSED ulong height,
354 ulong k, ulong nx, ulong *p, T *g, T *h, T *h2, T *r)
360 for (x = 0; x < nx; x++) {
363 g[x] = MAX(g[x - 1], f[p[x]]);
367 if (((x2 % k) == (k - 1)) || (x2 == (nx - 1)))
370 h[x2] = MAX(h[x2 + 1], f[p[x2]]);
373 if ((k == 1) || (nx == 1))
376 h[0] = MAX(h[1], f[p[0]]);
377 h2[nx - 1] = f[p[nx - 1]];
379 for (x = nx - 2; (x > 0) && (x >= (nx - k)); x--)
380 h2[x] = MAX(h2[x + 1], f[p[x]]);
381 h2[0] = MAX(h2[1], f[p[0]]);
385 for (x = 0; x < nx; x++)
387 }
else if (nx <= k) {
388 for (x = 0; x < (nx - k / 2); x++)
389 r[p[x]] = g[x + k / 2];
390 for (; x <= (k / 2); x++)
393 r[p[x]] = h[x - k / 2];
396 for (x = 0; x < (nx - k / 2); x++) {
398 r[p[x]] = g[x + k / 2];
400 r[p[x]] = MAX(g[x + k / 2], h[x - k / 2]);
402 for (x = nx - k / 2; x < nx; x++)
403 r[p[x]] = h2[x - k / 2];
407 void ImageGrayDilateHor(SoilleImage *img, ulong k, T *g, T *h, T *h2,
410 T *f = (T *) img->Pixmap;
411 T *r = (T *) out->Pixmap;
412 ulong width = img->Width;
414 for (ulong y = 0; y < img->Height; y++) {
415 DilateHorLine(f, width, k, g, h, h2, r);
421 void ImageGrayDilateVer(SoilleImage *img, ulong k, T *g, T *h, T *h2,
424 T *f = (T *) img->Pixmap;
425 T *r = (T *) out->Pixmap;
426 ulong width = img->Width;
427 ulong height = img->Height;
429 for (ulong x = 0; x < width; x++) {
430 DilateVerLine(f, width, height, k, g, h, h2, r);
436 void ImageGrayDilateLine(SoilleImage *img, ulong k,
long dx,
long dy,
437 ulong phase, ulong *p, T *g, T *h, T *h2,
440 T *f = (T *) img->Pixmap;
441 T *r = (T *) out->Pixmap;
442 ulong width = img->Width, height = img->Height, nx;
446 ImageGrayDilateHor(img, k, g, h, h2, out);
448 ImageGrayDilateVer(img, k, g, h, h2, out);
449 else if (abs(dx) == abs(dy)) {
452 nx = ComputeLineNegDiag(0, y, width, height, p);
454 DilateLine(f, width, height, k, nx, p, g, h, h2, r);
456 nx = ComputeLineNegDiag(0, y, width, height, p);
460 nx = ComputeLinePosDiag(0, y, width, height, p);
462 DilateLine(f, width, height, k, nx, p, g, h, h2, r);
464 nx = ComputeLinePosDiag(0, y, width, height, p);
467 }
else if (abs(dx) > abs(dy)) {
468 if (((dx > 0) && (dy > 0)) || ((dx < 0) && (dy < 0))) {
472 nx = ComputeBresenhamLinePX(0, y, dx, dy, phase, width, height, p);
474 DilateLine(f, width, height, k, nx, p, g, h, h2, r);
476 nx = ComputeBresenhamLinePX(0, y, dx, dy, phase, width, height, p);
482 nx = ComputeBresenhamLineNX(0, y, dx, dy, phase, width, height, p);
484 DilateLine(f, width, height, k, nx, p, g, h, h2, r);
486 nx = ComputeBresenhamLineNX(0, y, dx, dy, phase, width, height, p);
490 if (((dx > 0) && (dy > 0)) || ((dx < 0) && (dy < 0))) {
494 nx = ComputeBresenhamLinePY(x, 0, dx, dy, phase, width, height, p);
496 DilateLine(f, width, height, k, nx, p, g, h, h2, r);
498 nx = ComputeBresenhamLinePY(x, 0, dx, dy, phase, width, height, p);
504 nx = ComputeBresenhamLineNY(x, 0, dx, dy, phase, width, height, p);
506 DilateLine(f, width, height, k, nx, p, g, h, h2, r);
508 nx = ComputeBresenhamLineNY(x, 0, dx, dy, phase, width, height, p);
515 RES_T lineDilate(
const Image<T> &imIn,
const int angle,
const int radius,
519 ASSERT_ALLOCATED(&imIn);
520 ASSERT_ALLOCATED(&imOut);
521 ASSERT_SAME_SIZE(&imIn, &imOut);
525 H = imIn.getHeight();
526 if (imIn.getDepth() > 1) {
527 std::cerr <<
"This functions doesn't handle 3D images" << std::endl;
531 int maxnx = MAX(W, H);
534 T *h2 =
new T[maxnx];
535 ulong *p =
new ulong[maxnx];
537 SoilleImage MyImgIn, MyImgOut;
541 MyImgIn.Pixmap = (
void *) imIn.getPixels();
545 MyImgOut.Pixmap = (
void *) imOut.getPixels();
547 float rd = angle * PI / 180.;
549 r = (int ) floor(r * std::max(fabs(cos(rd)), fabs(sin(rd))) + 0.5);
551 int dx = (int) (cos(angle * PI / 180.0) * maxnx);
552 int dy = (int) (-sin(angle * PI / 180.0) * maxnx);
554 ImageGrayDilateLine(&MyImgIn, r * 2 + 1, dx, dy, 1, p, g, h, h2,
565 RES_T lineErode(
const Image<T> &imIn,
const int angle,
const int radius,
569 Image<T> imTmp(imIn);
571 r =
inv(imIn, imTmp);
573 r = lineDilate(imTmp, angle, radius, imOut);
575 r =
inv(imOut, imOut);
579 RES_T lineOpen(
const Image<T> &imIn,
const int angle,
const int radius,
583 Image<T> imTmp(imIn);
585 r = lineErode(imIn, angle, radius, imTmp);
587 r = lineDilate(imTmp, angle, radius, imOut);
591 RES_T lineClose(
const Image<T> &imIn,
const int angle,
const int radius,
595 Image<T> imTmp(imIn);
597 r = lineDilate(imIn, angle, radius, imTmp);
599 r = lineErode(imTmp, angle, radius, imOut);
603 RES_T circleDilate(
const Image<T> &imIn,
const int radius,
608 double alpha, kalpha, rd, k0;
610 r =
copy(imIn, imOut);
614 k0 = (radius * PI / nbAngle * 0.5);
615 for (i = 0; i < nbAngle; i++) {
616 alpha = i * 180. / nbAngle;
617 rd = alpha * PI / 180.;
618 kalpha = k0 * std::max(fabs(cos(rd)), fabs(sin(rd))) + 0.5;
620 r = lineDilate(imOut, (
int) alpha, (
int) kalpha, imOut);
627 RES_T circleErode(
const Image<T> &imIn,
const int radius, Image<T> &imOut)
631 double alpha, kalpha, rd, k0;
633 r =
copy(imIn, imOut);
637 k0 = (radius * PI / nbAngle * 0.5);
638 for (i = 0; i < nbAngle; i++) {
639 alpha = i * 180. / nbAngle;
640 rd = alpha * PI / 180.;
641 kalpha = k0 * std::max(fabs(cos(rd)), fabs(sin(rd))) + 0.5;
643 r = lineErode(imOut, (
int) alpha, (
int) kalpha, imOut);
650 RES_T circleOpen(
const Image<T> &imIn,
const int radius, Image<T> &imOut)
654 r = circleErode(imIn, radius, imOut);
656 r = circleDilate(imOut, radius, imOut);
660 RES_T circleClose(
const Image<T> &imIn,
const int radius, Image<T> &imOut)
663 r = circleDilate(imIn, radius, imOut);
665 r = circleErode(imOut, radius, imOut);
669 RES_T squareDilate(
const Image<T> &imIn,
const int radius,
672 Image<T> imTmp(imIn);
674 RES_T res = lineDilate(imIn, 0, radius, imTmp);
676 res = lineDilate(imTmp, 90, radius, imOut);
680 RES_T squareErode(
const Image<T> &imIn,
const int radius, Image<T> &imOut)
682 Image<T> imTmp(imIn);
684 RES_T res = lineErode(imIn, 0, radius, imTmp);
686 res = lineErode(imTmp, 90, radius, imOut);
690 RES_T squareOpen(
const Image<T> &imIn,
const int radius, Image<T> &imOut)
692 Image<T> imTmp(imIn);
694 RES_T res = lineErode(imIn, 0, radius, imTmp);
696 res = lineErode(imTmp, 90, radius, imOut);
698 res = lineDilate(imOut, 0, radius, imTmp);
700 res = lineDilate(imTmp, 90, radius, imOut);
704 RES_T squareClose(
const Image<T> &imIn,
const int radius, Image<T> &imOut)
706 Image<T> imTmp(imIn);
708 RES_T res = lineDilate(imIn, 0, radius, imTmp);
710 res = lineDilate(imTmp, 90, radius, imOut);
712 res = lineErode(imOut, 0, radius, imTmp);
714 res = lineErode(imTmp, 90, radius, imOut);
729 RES_T lineDilate_Soille(
const Image<T> &imIn,
const int angle,
730 const int radius, Image<T> &imOut)
732 SoilleLineMorpho<T> soille;
733 return soille.lineDilate(imIn, angle, radius, imOut);
737 RES_T lineErode_Soille(
const Image<T> &imIn,
const int angle,
738 const int radius, Image<T> &imOut)
740 SoilleLineMorpho<T> soille;
741 return soille.lineErode(imIn, angle, radius, imOut);
745 RES_T lineOpen_Soille(
const Image<T> &imIn,
const int angle,
746 const int radius, Image<T> &imOut)
748 SoilleLineMorpho<T> soille;
749 return soille.lineOpen(imIn, angle, radius, imOut);
753 RES_T lineClose_Soille(
const Image<T> &imIn,
const int angle,
754 const int radius, Image<T> &imOut)
756 SoilleLineMorpho<T> soille;
757 return soille.lineClose(imIn, angle, radius, imOut);
764 RES_T circleDilate_Soille(
const Image<T> &imIn,
const int radius,
767 SoilleLineMorpho<T> soille;
768 return soille.circleDilate(imIn, radius, imOut);
772 RES_T circleErode_Soille(
const Image<T> &imIn,
const int radius,
775 SoilleLineMorpho<T> soille;
776 return soille.circleErode(imIn, radius, imOut);
780 RES_T circleOpen_Soille(
const Image<T> &imIn,
const int radius,
783 SoilleLineMorpho<T> soille;
784 return soille.circleOpen(imIn, radius, imOut);
788 RES_T circleClose_Soille(
const Image<T> &imIn,
const int radius,
791 SoilleLineMorpho<T> soille;
792 return soille.circleClose(imIn, radius, imOut);
799 RES_T squareDilate_Soille(
const Image<T> &imIn,
const int radius,
802 SoilleLineMorpho<T> soille;
803 return soille.squareDilate(imIn, radius, imOut);
807 RES_T squareErode_Soille(
const Image<T> &imIn,
const int radius,
810 SoilleLineMorpho<T> soille;
811 return soille.squareErode(imIn, radius, imOut);
815 RES_T squareOpen_Soille(
const Image<T> &imIn,
const int radius,
818 SoilleLineMorpho<T> soille;
819 return soille.squareOpen(imIn, radius, imOut);
823 RES_T squareClose_Soille(
const Image<T> &imIn,
const int radius,
826 SoilleLineMorpho<T> soille;
827 return soille.squareClose(imIn, radius, imOut);
Definition: FastLineSoille.hpp:37
RES_T inv(const Image< T > &imIn, Image< T > &imOut)
inv() - Invert an image.
Definition: DImageArith.hpp:70
Definition: FastLineSoille.hpp:48