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