1 /*
2  * Threelay0r
3  * 2009 Hedde Bosman
4  *
5  * This source code  is free software; you can  redistribute it and/or
6  * modify it under the terms of the GNU Public License as published by
7  * the Free Software  Foundation; either version 3 of  the License, or
8  * (at your option) any later version.
9  *
10  * This source code 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.  Please refer
13  * to the GNU Public License for more details.
14  *
15  * You should  have received  a copy of  the GNU Public  License along
16  * with this source code; if  not, write to: Free Software Foundation,
17  * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  *
19  */
20 #include "frei0r.hpp"
21 
22 #include <algorithm>
23 #include <vector>
24 #include <utility>
25 #include <cassert>
26 
27 #include <iostream>
28 
29 // based upon twolay0r with some tweaks.
30 class threelay0r : public frei0r::filter
31 {
32 private:
grey(unsigned int value)33 	static unsigned char grey(unsigned int value) {
34 		unsigned char* rgba = reinterpret_cast<unsigned char*>(&value);
35 		unsigned char gw= (rgba[0] + rgba[1] + 2*rgba[2])/4;
36 		return gw;
37 	}
38 
39 	struct histogram {
histogramthreelay0r::histogram40 		histogram()	: hist(256)	{
41 			std::fill(hist.begin(),hist.end(),0);
42 		}
43 
operator ()threelay0r::histogram44 		void operator()(uint32_t value)	{
45 			++hist[grey(value)];
46 		}
47 
48 		std::vector<unsigned int> hist;
49 	};
50 
51 public:
threelay0r(unsigned int width,unsigned int height)52 	threelay0r(unsigned int width, unsigned int height) {}
53 
update(double time,uint32_t * out,const uint32_t * in)54 	virtual void update(double time,
55 	                    uint32_t* out,
56                         const uint32_t* in) {
57 		histogram h;
58 
59 		// create histogramm
60 		for (const unsigned int* i=in; i != in + (width*height);++i)
61 			h(*i);
62 
63 		// calc th
64 		int th1 = 1;
65 		int th2 = 255;
66 
67 		unsigned num = 0;
68 		unsigned int num1div3 = 4*size/10; // number of pixels in the lower level
69 		unsigned int num2div3 = 8*size/10; // number of pixels in the lower two levels
70 		for (int i = 0; i < 256; i++) { // wee bit faster than a double loop
71 			num += h.hist[i];
72 			if (num < num1div3) th1 = i;
73 			if (num < num2div3) th2 = i;
74 		}
75 
76 		// create the 3 level image
77 		uint32_t* outpixel= out;
78 		const uint32_t* pixel=in;
79 		while(pixel != in+size) // size = defined in frei0r.hpp
80 		{
81 			if ( grey(*pixel) < th1 )
82 				*outpixel=0xFF000000;
83 			else if ( grey(*pixel) < th2)
84 				*outpixel=0xFF808080;
85 			else
86 				*outpixel=0xFFFFFFFF;
87 			++outpixel;
88 			++pixel;
89 		}
90 	}
91 };
92 
93 
94 frei0r::construct<threelay0r> plugin("threelay0r",
95 									"dynamic 3 level thresholding",
96 									"Hedde Bosman",
97 									0,2);
98 
99