1 #ifndef __FAST_LINE_MORARD_T_HPP__
2 #define __FAST_LINE_MORARD_T_HPP__
12 #include "Core/include/DCore.h"
30 int wp, size, *LineIdx;
32 inline void BuildOpeningFromPoint(T F,
int Ind,
Node *MyStack,
33 int *stackSize, T *bufferOut)
40 if (F > MyStack[*stackSize - 1].Value) {
41 (MyStack[*stackSize]).StartPos = wp;
42 (MyStack[*stackSize]).Passed = 0;
43 (MyStack[*stackSize]).Value = F;
46 while (F < (MyStack[*stackSize - 1]).Value) {
51 if (MyStack[*stackSize].Passed ||
52 (wp - (MyStack[*stackSize]).StartPos >= size)) {
53 for (
int j = 0; j < *stackSize; j++) {
54 for (
int i = (MyStack[j]).StartPos; i < (MyStack[j + 1]).StartPos;
56 bufferOut[LineIdx[i]] = (MyStack[j]).Value;
58 for (
int i = (MyStack[*stackSize]).StartPos; i < wp; i++)
59 bufferOut[LineIdx[i]] = (MyStack[*stackSize]).Value;
61 (MyStack[0]).StartPos = wp;
62 (MyStack[0]).Passed = 1;
63 (MyStack[0]).Value = F;
68 if (*stackSize == 0 || F > (MyStack[*stackSize - 1]).Value) {
69 (MyStack[*stackSize]).Value = F;
78 void EndProcess(Node *MyStack,
int *stackSize, T *bufferOut)
80 while (*stackSize != 0) {
81 if (wp - (MyStack[*stackSize - 1]).StartPos >= size) {
82 for (
int j = 0; j < *stackSize - 1; j++) {
83 for (
int i = (MyStack[j]).StartPos; i < (MyStack[j + 1]).StartPos;
85 bufferOut[LineIdx[i]] = (MyStack[j]).Value;
88 for (
int i = (MyStack[*stackSize - 1]).StartPos; i < wp; i++)
89 bufferOut[LineIdx[i]] = (MyStack[*stackSize - 1]).Value;
97 for (
int i = (MyStack[0]).StartPos; i < wp; i++)
98 bufferOut[LineIdx[i]] = (MyStack[0]).Value;
101 int ComputeLinePosDiag(T *bufferIn,
int W,
int H,
int x,
int y,
102 Node *MyStack,
int *stackSize, T *bufferOut)
118 if ((x < W) && (y < H)) {
120 MyStack[0].Passed = 0;
121 MyStack[0].Value = bufferIn[idx];
122 MyStack[0].StartPos = 0;
131 for (; (x < W) && (y < H); x++) {
132 BuildOpeningFromPoint(bufferIn[idx], idx, MyStack, stackSize,
140 int ComputeLineNegDiag(T *bufferIn,
int W,
int H,
int x,
int y,
141 Node *MyStack,
int *stackSize, T *bufferOut)
156 MyStack[0].Passed = 0;
157 MyStack[0].Value = bufferIn[idx];
158 MyStack[0].StartPos = 0;
165 while ((x < W - 1) && (y > 0)) {
171 BuildOpeningFromPoint(bufferIn[idx], idx, MyStack, stackSize,
177 int ComputeBresenhamLinePX(T *bufferIn,
int W,
int H,
int x,
int y,
178 int dx,
int dy, Node *MyStack,
int *stackSize,
183 int dp = 2 * dy - 2, twody = 2 * dy, twodydx = 2 * dy - 2 * dx;
185 while ((x < 0) || (y < 0)) {
196 if (x >= 0 && x < W && y >= 0 && y < H) {
198 MyStack[0].Passed = 0;
199 MyStack[0].Value = bufferIn[idx];
200 MyStack[0].StartPos = 0;
215 while ((x < W) && (y < H)) {
216 BuildOpeningFromPoint(bufferIn[idx], idx, MyStack, stackSize,
231 int ComputeBresenhamLineNX(T *bufferIn,
int W,
int H,
int x,
int y,
232 int dx,
int dy, Node *MyStack,
int *stackSize,
235 int x0 = x, idx = y * W + x;
236 int dp = 2 * dy - 2, twody = 2 * dy, twodydx = 2 * dy - 2 * dx;
252 MyStack[0].Passed = 0;
253 MyStack[0].Value = bufferIn[idx];
254 MyStack[0].StartPos = 0;
260 while ((x < W - 1) && (y > 0)) {
270 BuildOpeningFromPoint(bufferIn[idx], idx, MyStack, stackSize,
276 int ComputeBresenhamLinePY(T *bufferIn,
int W,
int H,
int x,
int y,
277 int dx,
int dy, Node *MyStack,
int *stackSize,
281 int dp = 2 * dx - 2, twodx = 2 * dx, twodxdy = 2 * dx - 2 * dy;
283 while ((x < 0) || (y < 0)) {
295 if (x >= 0 && x < W && y >= 0 && y < H) {
297 MyStack[0].Passed = 0;
298 MyStack[0].Value = bufferIn[idx];
299 MyStack[0].StartPos = 0;
314 while ((y < H) && (x < W)) {
315 BuildOpeningFromPoint(bufferIn[idx], idx, MyStack, stackSize,
329 int ComputeBresenhamLineNY(T *bufferIn,
int W,
int H,
int x,
int y,
330 int dx,
int dy, Node *MyStack,
int *stackSize,
334 int dp = 2 * dx - 2, twodx = 2 * dx, twodxdy = 2 * dx - 2 * dy;
350 MyStack[0].Passed = 0;
351 MyStack[0].Value = bufferIn[idx];
352 MyStack[0].StartPos = 0;
358 while ((y < H - 1) && (x > 0) && (x < W)) {
368 BuildOpeningFromPoint(bufferIn[idx], idx, MyStack, stackSize,
374 void LineOpeningHorz(T *bufferIn,
int W,
int H,
int radius, T *bufferOut)
376 size = radius * 2 + 1;
385 for (j = 0; j < H; j++)
388 MyStack[0].Passed = 0;
389 MyStack[0].Value = bufferIn[j * W];
390 MyStack[0].StartPos = 0;
393 for (i = 1; i < W; i++)
394 BuildOpeningFromPoint(bufferIn[i + j * W], i + j * W, MyStack,
395 &stackPos, bufferOut);
396 EndProcess(MyStack, &stackPos, bufferOut);
400 void LineOpeningVert(T *bufferIn,
int W,
int H,
int radius, T *bufferOut)
402 size = radius * 2 + 1;
409 for (i = 0; i < W; i++)
412 MyStack[0].Passed = 0;
413 MyStack[0].Value = bufferIn[i];
414 MyStack[0].StartPos = 0;
417 for (j = 1; j < H; j++)
418 BuildOpeningFromPoint(bufferIn[i + j * W], i + j * W, MyStack,
419 &stackPos, bufferOut);
420 EndProcess(MyStack, &stackPos, bufferOut);
424 void LineOpeningDiag(T *bufferIn,
int W,
int H,
int dx,
int dy,
425 int radius, T *bufferOut)
427 size = radius * 2 + 1;
433 if (abs(dx) == abs(dy)) {
437 nx = ComputeLineNegDiag(bufferIn, W, H, 0, y++, MyStack,
438 &stackPos, bufferOut);
439 EndProcess(MyStack, &stackPos, bufferOut);
445 nx = ComputeLinePosDiag(bufferIn, W, H, 0, y--, MyStack,
446 &stackPos, bufferOut);
447 EndProcess(MyStack, &stackPos, bufferOut);
450 }
else if (abs(dx) > abs(dy)) {
451 if (((dx > 0) && (dy > 0)) || ((dx < 0) && (dy < 0))) {
457 nx = ComputeBresenhamLinePX(bufferIn, W, H, 0, y--, dx, dy,
458 MyStack, &stackPos, bufferOut);
459 EndProcess(MyStack, &stackPos, bufferOut);
467 nx = ComputeBresenhamLineNX(bufferIn, W, H, 0, y++, dx, dy,
468 MyStack, &stackPos, bufferOut);
469 EndProcess(MyStack, &stackPos, bufferOut);
473 if (((dx > 0) && (dy > 0)) || ((dx < 0) && (dy < 0))) {
479 nx = ComputeBresenhamLinePY(bufferIn, W, H, x--, 0, dx, dy,
480 MyStack, &stackPos, bufferOut);
481 EndProcess(MyStack, &stackPos, bufferOut);
489 nx = ComputeBresenhamLineNY(bufferIn, W, H, x++, 0, dx, dy,
490 MyStack, &stackPos, bufferOut);
491 EndProcess(MyStack, &stackPos, bufferOut);
500 RES_T ImFastLineOpen(
const Image<T> &imIn,
const int angle,
501 const int radius, Image<T> &imOut)
504 ASSERT_ALLOCATED(&imIn);
505 ASSERT_ALLOCATED(&imOut);
506 ASSERT_SAME_SIZE(&imIn, &imOut);
511 H = imIn.getHeight();
513 typename Image<T>::lineType bufferIn = imIn.getPixels();
514 typename Image<T>::lineType bufferOut = imOut.getPixels();
516 int rd = (int) (angle * PI / 180.);
517 int r = (int) (radius * std::max(fabs(cos(rd)), fabs(sin(rd))) + 0.5);
519 int maxnx = std::max(W, H);
520 LineIdx =
new int[maxnx + 3];
521 int dx = (int) (cos(angle * PI / 180.0) * maxnx);
522 int dy = (int) (-sin(angle * PI / 180.0) * maxnx);
525 LineOpeningVert(bufferIn, W, H, r, bufferOut);
527 LineOpeningHorz(bufferIn, W, H, r, bufferOut);
529 LineOpeningDiag(bufferIn, W, H, dx, dy, r, bufferOut);
541 RES_T imFastLineOpen(
const Image<T> &imIn,
const int angle,
542 const int radius, Image<T> &imOut)
544 MorardLineMorpho<T> morard;
546 return morard.ImFastLineOpen(imIn, angle, radius, imOut);
Definition: FastLineMorard.hpp:17
Definition: FastLineMorard.hpp:23