1 /***************************************************************************
2 * This file is part of Tecorrec. *
3 * Copyright 2008 James Hogan <james@albanarts.com> *
5 * Tecorrec is free software: you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation, either version 2 of the License, or *
8 * (at your option) any later version. *
10 * Tecorrec is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with Tecorrec. If not, write to the Free Software Foundation, *
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
18 ***************************************************************************/
21 * @file tcShadowClassification.cpp
22 * @brief Shadow classification channel.
25 #include "tcShadowClassification.h"
26 #include "tcIlluminantDiscontinuity.h"
31 * Constructors + destructor
34 /// Primary constructor.
35 tcShadowClassification::tcShadowClassification(tcIlluminantDiscontinuity
* discontinuity
, tcChannel
* midIr
)
36 : tcChannel(tr("Shadow classification"),
37 tr("Tries to classify shadows using illuminant discontinuities and a mid IR channel"))
41 for (int i
= 0; i
< 2; ++i
)
43 m_discontinuity
[i
] = discontinuity
->channels()[i
];
44 m_discontinuity
[i
]->addDerivitive(this);
46 m_midIr
->addDerivitive(this);
50 tcShadowClassification::~tcShadowClassification()
52 for (int i
= 0; i
< 2; ++i
)
54 m_discontinuity
[i
]->removeDerivitive(this);
56 m_midIr
->removeDerivitive(this);
60 * Interface for derived class to implement
63 void tcShadowClassification::roundPortion(double* x1
, double* y1
, double* x2
, double* y2
)
65 m_midIr
->roundPortion(x1
, y1
, x2
, y2
);
68 tcAbstractPixelData
* tcShadowClassification::loadPortion(double x1
, double y1
, double x2
, double y2
, bool changed
)
70 // Get portions from both the discontinuity images and the mid ir
71 // multiply discontinuity by (1-midIr)
73 Reference
<tcPixelData
<float> > disc
[2] = {
74 dynamic_cast<tcPixelData
<float>*>(m_discontinuity
[0]->loadPortion(x1
, y1
, x2
, y2
, changed
)),
75 dynamic_cast<tcPixelData
<float>*>(m_discontinuity
[1]->loadPortion(x1
, y1
, x2
, y2
, changed
))
77 Reference
<tcPixelData
<GLubyte
> > midIr
= dynamic_cast<tcPixelData
<GLubyte
>*>(m_midIr
->loadPortion(x1
, y1
, x2
, y2
, changed
));
79 tcPixelData
<GLubyte
>* data
= 0;
80 if (0 != disc
[0] && 0 != disc
[1] && 0 != midIr
)
82 int width
= midIr
->width();
83 int height
= midIr
->height();
84 Q_ASSERT(width
== disc
[0]->width());
85 Q_ASSERT(height
== disc
[0]->height());
86 Q_ASSERT(width
== disc
[1]->width());
87 Q_ASSERT(height
== disc
[1]->height());
88 data
= new tcPixelData
<GLubyte
>(width
, height
);
89 for (int i
= 0; i
< width
*height
; ++i
)
91 float disc1Val
= disc
[0]->buffer()[i
];
92 float disc2Val
= disc
[1]->buffer()[i
];
93 float midIrVal
= (float)midIr
->buffer()[i
]/255.0f
;
94 float shadowiness
= fabs(disc1Val
+ disc1Val
) * 0.5f
97 //shadowiness = (shadowiness > 0.25f ? shadowiness : 0.0f);
98 data
->buffer()[i
] = shadowiness
;
99 /// @todo Have a parameter threshold
100 //data->buffer()[i] = (shadowiness > 0.25f ? 255 : 0);
103 // Linearly fill in the gaps
104 /// @todo fillSize should be a parameter
105 const int fillSize
= 2;
106 for (int d
= 0; d
< 0; ++d
)
109 int jMax
= (dir
? width
: height
);
110 int iMax
= (dir
? height
: width
);
111 for (int j
= 0; j
< jMax
; ++j
)
114 for (int i
= 0; i
< iMax
; ++i
)
116 int row
= (dir
? i
: j
);
117 int col
= (dir
? j
: i
);
118 int index
= row
*width
+ col
;
119 if (0 != data
->buffer()[index
])
121 if (blankCount
> 0 && blankCount
<= fillSize
)
123 int min
= i
-blankCount
;
126 for (int k
= min
; k
< i
; ++k
)
128 int kIndex
= (dir
?k
:row
)*width
+ (dir
?col
:k
);
129 data
->buffer()[kIndex
] = 255;