Skip to content

Commit d15294a

Browse files
committed
mt_hysteresis: new "corners" - Issue #23
1 parent 2af5f7a commit d15294a

File tree

2 files changed

+63
-34
lines changed

2 files changed

+63
-34
lines changed

masktools/filters/mask/hysteresis/hysteresis.cpp

Lines changed: 48 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ struct Coordinates {
1212

1313
typedef std::vector<Coordinates> CoordinatesList;
1414

15-
template<typename pixel_t, int bits_per_pixel>
16-
static void expand_mask(pixel_t *pDst, ptrdiff_t nDstPitch, const pixel_t *pSrc2, ptrdiff_t nSrc2Pitch, Byte *pTemp, int x, int y, int nWidth, int nHeight, CoordinatesList &coordinates)
15+
template<typename pixel_t, int bits_per_pixel, bool corners>
16+
static void expand_mask(pixel_t* pDst, ptrdiff_t nDstPitch, const pixel_t* pSrc2, ptrdiff_t nSrc2Pitch, Byte* pTemp, int x, int y, int nWidth, int nHeight, CoordinatesList& coordinates)
1717
{
1818
//CoordinatesList coordinates;
1919
coordinates.clear();
@@ -34,25 +34,33 @@ static void expand_mask(pixel_t *pDst, ptrdiff_t nDstPitch, const pixel_t *pSrc2
3434
coordinates.pop_back();
3535

3636
/* check surrounding positions */
37-
int x_min = current.x == -x ? current.x : current.x - 1;
38-
int x_max = current.x == nWidth - x - 1 ? current.x + 1 : current.x + 2;
37+
int x_min = current.x == -x ? current.x : current.x - 1;
38+
int x_max = current.x == nWidth - x - 1 ? current.x : current.x + 1;
3939
int y_min = current.y == -y ? current.y : current.y - 1;
40-
int y_max = current.y == nHeight - y - 1 ? current.y + 1 : current.y + 2;
41-
42-
for (int i = y_min; i < y_max; i++) {
43-
for (int j = x_min; j < x_max; j++) {
44-
if (!pTemp[j + i * nWidth] && pSrc2[j + i * nSrc2Pitch]) {
45-
coordinates.emplace_back(j, i);
46-
pTemp[j + i * nWidth] = 1;
47-
pDst[j + i * nDstPitch] = mask_value;
48-
}
40+
int y_max = current.y == nHeight - y - 1 ? current.y : current.y + 1;
41+
42+
for (int i = y_min; i <= y_max; i++) {
43+
for (int j = x_min; j <= x_max; j++) {
44+
// corners:
45+
// false true
46+
// + + + +
47+
// + O + + O +
48+
// + + + +
49+
if (corners || (i == current.y || j == current.x))
50+
{
51+
if (!pTemp[j + i * nWidth] && pSrc2[j + i * nSrc2Pitch]) {
52+
coordinates.emplace_back(j, i);
53+
pTemp[j + i * nWidth] = 1;
54+
pDst[j + i * nDstPitch] = mask_value;
55+
}
4956
}
57+
}
5058
}
5159
}
5260
}
5361

5462
namespace Filtering { namespace MaskTools { namespace Filters { namespace Mask { namespace Hysteresis {
55-
template<typename pixel_t, int bits_per_pixel>
63+
template<typename pixel_t, int bits_per_pixel, bool corners>
5664
void hysteresis_c(Byte *pDst, ptrdiff_t nDstPitch, const Byte *pSrc1, ptrdiff_t nSrc1Pitch,
5765
const Byte *pSrc2, ptrdiff_t nSrc2Pitch, Byte *pTemp, int width, int height)
5866
{
@@ -65,7 +73,7 @@ void hysteresis_c(Byte *pDst, ptrdiff_t nDstPitch, const Byte *pSrc1, ptrdiff_t
6573
{
6674
for (int x = 0; x < width; x++) {
6775
if (!pTemp[x] && ((pixel_t *)pSrc1)[x] && ((pixel_t *)pSrc2)[x]) {
68-
expand_mask<pixel_t, bits_per_pixel>((pixel_t *)pDst + x, nDstPitch, (pixel_t *)pSrc2 + x, nSrc2Pitch, pTemp + x, x, y, width, height, coordinates);
76+
expand_mask<pixel_t, bits_per_pixel, corners>((pixel_t *)pDst + x, nDstPitch, (pixel_t *)pSrc2 + x, nSrc2Pitch, pTemp + x, x, y, width, height, coordinates);
6977
}
7078

7179
}
@@ -76,18 +84,30 @@ void hysteresis_c(Byte *pDst, ptrdiff_t nDstPitch, const Byte *pSrc1, ptrdiff_t
7684
}
7785
}
7886

79-
template void hysteresis_c<Byte, 8>(Byte *pDst, ptrdiff_t nDstPitch, const Byte *pSrc1, ptrdiff_t nSrc1Pitch, const Byte *pSrc2, ptrdiff_t nSrc2Pitch, Byte *pTemp, int width, int height);
80-
template void hysteresis_c<Word, 10>(Byte *pDst, ptrdiff_t nDstPitch, const Byte *pSrc1, ptrdiff_t nSrc1Pitch, const Byte *pSrc2, ptrdiff_t nSrc2Pitch, Byte *pTemp, int width, int height);
81-
template void hysteresis_c<Word, 12>(Byte *pDst, ptrdiff_t nDstPitch, const Byte *pSrc1, ptrdiff_t nSrc1Pitch, const Byte *pSrc2, ptrdiff_t nSrc2Pitch, Byte *pTemp, int width, int height);
82-
template void hysteresis_c<Word, 14>(Byte *pDst, ptrdiff_t nDstPitch, const Byte *pSrc1, ptrdiff_t nSrc1Pitch, const Byte *pSrc2, ptrdiff_t nSrc2Pitch, Byte *pTemp, int width, int height);
83-
template void hysteresis_c<Word, 16>(Byte *pDst, ptrdiff_t nDstPitch, const Byte *pSrc1, ptrdiff_t nSrc1Pitch, const Byte *pSrc2, ptrdiff_t nSrc2Pitch, Byte *pTemp, int width, int height);
84-
template void hysteresis_c<Float, 0>(Byte *pDst, ptrdiff_t nDstPitch, const Byte *pSrc1, ptrdiff_t nSrc1Pitch, const Byte *pSrc2, ptrdiff_t nSrc2Pitch, Byte *pTemp, int width, int height);
85-
86-
Processor *hysteresis_8_c = &hysteresis_c<Byte, 8>;
87-
Processor *hysteresis_10_c = &hysteresis_c<Word, 10>;
88-
Processor *hysteresis_12_c = &hysteresis_c<Word, 12>;
89-
Processor *hysteresis_14_c = &hysteresis_c<Word, 14>;
90-
Processor *hysteresis_16_c = &hysteresis_c<Word, 16>;
91-
Processor *hysteresis_32_c = &hysteresis_c<Float, 0>; // float: bit_per_pixel n/a
87+
template void hysteresis_c<Byte, 8, true>(Byte *pDst, ptrdiff_t nDstPitch, const Byte *pSrc1, ptrdiff_t nSrc1Pitch, const Byte *pSrc2, ptrdiff_t nSrc2Pitch, Byte *pTemp, int width, int height);
88+
template void hysteresis_c<Word, 10, true>(Byte *pDst, ptrdiff_t nDstPitch, const Byte *pSrc1, ptrdiff_t nSrc1Pitch, const Byte *pSrc2, ptrdiff_t nSrc2Pitch, Byte *pTemp, int width, int height);
89+
template void hysteresis_c<Word, 12, true>(Byte *pDst, ptrdiff_t nDstPitch, const Byte *pSrc1, ptrdiff_t nSrc1Pitch, const Byte *pSrc2, ptrdiff_t nSrc2Pitch, Byte *pTemp, int width, int height);
90+
template void hysteresis_c<Word, 14, true>(Byte *pDst, ptrdiff_t nDstPitch, const Byte *pSrc1, ptrdiff_t nSrc1Pitch, const Byte *pSrc2, ptrdiff_t nSrc2Pitch, Byte *pTemp, int width, int height);
91+
template void hysteresis_c<Word, 16, true>(Byte *pDst, ptrdiff_t nDstPitch, const Byte *pSrc1, ptrdiff_t nSrc1Pitch, const Byte *pSrc2, ptrdiff_t nSrc2Pitch, Byte *pTemp, int width, int height);
92+
template void hysteresis_c<Float, 0, true>(Byte *pDst, ptrdiff_t nDstPitch, const Byte *pSrc1, ptrdiff_t nSrc1Pitch, const Byte *pSrc2, ptrdiff_t nSrc2Pitch, Byte *pTemp, int width, int height);
93+
template void hysteresis_c<Byte, 8, false>(Byte* pDst, ptrdiff_t nDstPitch, const Byte* pSrc1, ptrdiff_t nSrc1Pitch, const Byte* pSrc2, ptrdiff_t nSrc2Pitch, Byte* pTemp, int width, int height);
94+
template void hysteresis_c<Word, 10, false>(Byte* pDst, ptrdiff_t nDstPitch, const Byte* pSrc1, ptrdiff_t nSrc1Pitch, const Byte* pSrc2, ptrdiff_t nSrc2Pitch, Byte* pTemp, int width, int height);
95+
template void hysteresis_c<Word, 12, false>(Byte* pDst, ptrdiff_t nDstPitch, const Byte* pSrc1, ptrdiff_t nSrc1Pitch, const Byte* pSrc2, ptrdiff_t nSrc2Pitch, Byte* pTemp, int width, int height);
96+
template void hysteresis_c<Word, 14, false>(Byte* pDst, ptrdiff_t nDstPitch, const Byte* pSrc1, ptrdiff_t nSrc1Pitch, const Byte* pSrc2, ptrdiff_t nSrc2Pitch, Byte* pTemp, int width, int height);
97+
template void hysteresis_c<Word, 16, false>(Byte* pDst, ptrdiff_t nDstPitch, const Byte* pSrc1, ptrdiff_t nSrc1Pitch, const Byte* pSrc2, ptrdiff_t nSrc2Pitch, Byte* pTemp, int width, int height);
98+
template void hysteresis_c<Float, 0, false>(Byte* pDst, ptrdiff_t nDstPitch, const Byte* pSrc1, ptrdiff_t nSrc1Pitch, const Byte* pSrc2, ptrdiff_t nSrc2Pitch, Byte* pTemp, int width, int height);
99+
100+
Processor *hysteresis_8_c = &hysteresis_c<Byte, 8, true>;
101+
Processor *hysteresis_10_c = &hysteresis_c<Word, 10, true>;
102+
Processor *hysteresis_12_c = &hysteresis_c<Word, 12, true>;
103+
Processor *hysteresis_14_c = &hysteresis_c<Word, 14, true>;
104+
Processor *hysteresis_16_c = &hysteresis_c<Word, 16, true>;
105+
Processor *hysteresis_32_c = &hysteresis_c<Float, 0, true>; // float: bit_per_pixel n/a
106+
Processor* hysteresis_8_nocorner_c = &hysteresis_c<Byte, 8, false>;
107+
Processor* hysteresis_10_nocorner_c = &hysteresis_c<Word, 10, false>;
108+
Processor* hysteresis_12_nocorner_c = &hysteresis_c<Word, 12, false>;
109+
Processor* hysteresis_14_nocorner_c = &hysteresis_c<Word, 14, false>;
110+
Processor* hysteresis_16_nocorner_c = &hysteresis_c<Word, 16, false>;
111+
Processor* hysteresis_32_nocorner_c = &hysteresis_c<Float, 0, false>; // float: bit_per_pixel n/a
92112

93113
} } } } }

masktools/filters/mask/hysteresis/hysteresis.h

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ extern Processor *hysteresis_12_c;
1414
extern Processor *hysteresis_14_c;
1515
extern Processor *hysteresis_16_c;
1616
extern Processor *hysteresis_32_c;
17+
extern Processor* hysteresis_8_nocorner_c;
18+
extern Processor* hysteresis_10_nocorner_c;
19+
extern Processor* hysteresis_12_nocorner_c;
20+
extern Processor* hysteresis_14_nocorner_c;
21+
extern Processor* hysteresis_16_nocorner_c;
22+
extern Processor* hysteresis_32_nocorner_c;
1723

1824
class Hysteresis : public MaskTools::Filter
1925
{
@@ -34,13 +40,15 @@ class Hysteresis : public MaskTools::Filter
3440
public:
3541
Hysteresis(const Parameters &parameters, CpuFlags cpuFlags) : MaskTools::Filter(parameters, FilterProcessingType::CHILD, (CpuFlags)cpuFlags), stack(nullptr) {
3642
int bits_per_pixel = bit_depths[C];
43+
const bool corners = parameters["corners"].toBool();
44+
3745
switch (bits_per_pixel) {
38-
case 8: processor = hysteresis_8_c; break;
39-
case 10: processor = hysteresis_10_c; break;
40-
case 12: processor = hysteresis_12_c; break;
41-
case 14: processor = hysteresis_14_c; break;
42-
case 16: processor = hysteresis_16_c; break;
43-
case 32: processor = hysteresis_32_c; break;
46+
case 8: processor = corners ? hysteresis_8_c : hysteresis_8_nocorner_c; break;
47+
case 10: processor = corners ? hysteresis_10_c : hysteresis_8_nocorner_c; break;
48+
case 12: processor = corners ? hysteresis_12_c : hysteresis_8_nocorner_c; break;
49+
case 14: processor = corners ? hysteresis_14_c : hysteresis_8_nocorner_c; break;
50+
case 16: processor = corners ? hysteresis_16_c : hysteresis_8_nocorner_c; break;
51+
case 32: processor = corners ? hysteresis_32_c : hysteresis_8_nocorner_c; break;
4452
}
4553

4654
stack = reinterpret_cast<Byte*>(_aligned_malloc(nWidth*nHeight, 16));
@@ -58,6 +66,7 @@ class Hysteresis : public MaskTools::Filter
5866

5967
signature.add(Parameter(TYPE_CLIP, "", false));
6068
signature.add(Parameter(TYPE_CLIP, "", false));
69+
signature.add(Parameter(true, "corners", false)); // default true
6170

6271
return add_defaults(signature);
6372
}

0 commit comments

Comments
 (0)