00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "filterpixel8.h"
00031 #include <cmath>
00032
00033 Pixel8Filter::Pixel8Filter() : ChannelFilter<unsigned char>()
00034 {
00035 alreadyChanged2 = 0;
00036 alreadyChanged4 = 0;
00037 alreadyChanged8 = 0;
00038 average2 = 0;
00039 average4 = 0;
00040 average8 = 0;
00041 }
00042
00043 Pixel8Filter::~Pixel8Filter()
00044 {
00045 delete alreadyChanged2;
00046 delete alreadyChanged4;
00047 delete alreadyChanged8;
00048 delete average2;
00049 delete average4;
00050 delete average8;
00051 }
00052
00053 ChannelFilter<unsigned char>* Pixel8Filter::EmptyClone()
00054 {
00055 Pixel8Filter *copy = new Pixel8Filter();
00056 copy->SetSubChannel(GetSubChannel());
00057 return(copy);
00058 }
00059
00060 void Pixel8Filter::OnMouseEvent(const int button, const int state, int x, int y)
00061 {
00062 if(state != 0 || button != 0)
00063 return;
00064 int width = GetWidth();
00065 int height = GetHeight();
00066
00067 alreadyChanged2 = new Channel<int>(height/2+5,width/2+5);
00068 alreadyChanged4 = new Channel<int>(height/4+5,width/4+5);
00069 alreadyChanged8 = new Channel<int>(height/8+5,width/8+5);
00070 average2 = new Channel<int>(height/2+5,width/2+5);
00071 average4 = new Channel<int>(height/4+5,width/4+5);
00072 average8 = new Channel<int>(height/8+5,width/8+5);
00073
00074 for(int i=0;i<width/2+1;i++)
00075 for(int j=0;j<height/2+1;j++)
00076 {
00077 alreadyChanged2->Set(i,j,0xFFFFFF);
00078 average2->Set(i,j,0);
00079 }
00080 for(int i=0;i<width/4+1;i++)
00081 for(int j=0;j<height/4+1;j++)
00082 {
00083 alreadyChanged4->Set(i,j,0xFFFFFF);
00084 average4->Set(i,j,0);
00085 }
00086 for(int i=0;i<width/8+1;i++)
00087 for(int j=0;j<height/8+1;j++)
00088 {
00089 alreadyChanged8->Set(i,j,0xFFFFFF);
00090 average8->Set(i,j,0);
00091 }
00092
00093 for (int j=0; j<=(height/8-1); j++)
00094 for (int i=0; i<=(width/8-1); i++)
00095 {
00096 Analyze8x8Area(i*8, j*8);
00097
00098
00099 if (alreadyChanged8->Get(i,j)<PIX8_HIGLIM)
00100 {
00101 DrawPixel(i*8, j*8, 8, average8->Get(i,j), 40);
00102 }
00103 else
00104 {
00105 if (alreadyChanged4->Get(i*2+1,j*2+1)<PIX8_MEDLIM)
00106 DrawPixel(i*8+4, j*8+4, 4, average4->Get(i*2+1,j*2+1), 30);
00107 else
00108 {
00109 DrawPixel(i*8+4+2, j*8+4+2, 2, average2->Get(i*4+2+1 ,j*4+2+1), 20);
00110 DrawPixel(i*8+4 , j*8+4+2, 2, average2->Get(i*4+2 ,j*4+2+1), 20);
00111 DrawPixel(i*8+4 , j*8+4 , 2, average2->Get(i*4+2 ,j*4+2 ), 20);
00112 DrawPixel(i*8+4+2, j*8+4 , 2, average2->Get(i*4+2+1 ,j*4+2 ), 20);
00113 }
00114
00115 if (alreadyChanged4->Get(i*2,j*2+1)<PIX8_MEDLIM)
00116 DrawPixel(i*8 , j*8+4, 4, average4->Get(i*2,j*2+1), 30);
00117 else
00118 {
00119 DrawPixel(i*8+2, j*8+4+2, 2, average2->Get(i*4+1 ,j*4+2+1), 20);
00120 DrawPixel(i*8 , j*8+4+2, 2, average2->Get(i*4 ,j*4+2+1), 20);
00121 DrawPixel(i*8 , j*8+4 , 2, average2->Get(i*4 ,j*4+2 ), 20);
00122 DrawPixel(i*8+2, j*8+4 , 2, average2->Get(i*4+1 ,j*4+2 ), 20);
00123 }
00124
00125 if (alreadyChanged4->Get(i*2,j*2)<PIX8_MEDLIM)
00126 DrawPixel(i*8 , j*8 , 4, average4->Get(i*2,j*2), 30);
00127 else
00128 {
00129 DrawPixel(i*8+2, j*8+2, 2, average2->Get(i*4+1 ,j*4+1), 20);
00130 DrawPixel(i*8 , j*8+2, 2, average2->Get(i*4 ,j*4+1), 20);
00131 DrawPixel(i*8 , j*8 , 2, average2->Get(i*4 ,j*4 ), 20);
00132 DrawPixel(i*8+2, j*8 , 2, average2->Get(i*4+1 ,j*4 ), 20);
00133 }
00134
00135 if (alreadyChanged4->Get(i*2+1,j*2)<PIX8_MEDLIM)
00136 DrawPixel(i*8+4, j*8 , 4, average4->Get(i*2+1,j*2), 30);
00137 else
00138 {
00139 DrawPixel(i*8+4+2, j*8+2, 2, average2->Get(i*4+2+1 ,j*4+1), 20);
00140 DrawPixel(i*8+4 , j*8+2, 2, average2->Get(i*4+2 ,j*4+1), 20);
00141 DrawPixel(i*8+4 , j*8 , 2, average2->Get(i*4+2 ,j*4 ), 20);
00142 DrawPixel(i*8+4+2, j*8 , 2, average2->Get(i*4+2+1 ,j*4 ), 20);
00143 }
00144 }
00145 }
00146
00147 delete alreadyChanged2;
00148 delete alreadyChanged4;
00149 delete alreadyChanged8;
00150 delete average2;
00151 delete average4;
00152 delete average8;
00153 alreadyChanged2 = 0;
00154 alreadyChanged4 = 0;
00155 alreadyChanged8 = 0;
00156 average2 = 0;
00157 average4 = 0;
00158 average8 = 0;
00159 }
00160
00161 void Pixel8Filter::AnalyzeArea(int *deviation, int *average, int x, int y, int size)
00162 {
00163 *average = *deviation = 0;
00164 for(int i=(x - (x % size)); i<=(x | (size-1)); i++)
00165 for(int j=(y - (y % size)); j<=(y | (size-1)); j++)
00166 *average+=Get(i,j);
00167 if (size<8)
00168 *average=*average>>size;
00169 else
00170 *average=*average>>6;
00171 for(int i=(x - (x % size)); i<=(x | (size-1)); i++)
00172 for(int j=(y - (y % size)); j<=(y | (size-1)); j++)
00173 *deviation+=abs(Get(i,j)-*average);
00174 }
00175
00176 void Pixel8Filter::Analyze8x8Area(int x, int y)
00177 {
00178 int myX, myY, divX, divY;
00179 int i,j;
00180 int avg=0, dev=0;
00181
00182 myX=x-(x%8);
00183 myY=y-(y%8);
00184 divX=x/8;
00185 divY=y/8;
00186
00187 for (i=0; i<4; i++)
00188 for (j=0; j<4; j++)
00189 {
00190 avg = average2->Get(divX*4+i,divY*4+j);
00191 AnalyzeArea(&dev,&avg, myX+2*i, myY+2*j, 2);
00192 alreadyChanged2->Set(divX*4+i,divY*4+j,dev);
00193 average2->Set(divX*4+i,divY*4+j,avg);
00194 }
00195
00196 for (i=0; i<2; i++)
00197 for (j=0; j<2; j++)
00198 if ((alreadyChanged2->Get(divX*4+i*2,divY*4+ j*2) < PIX8_LOWLIM) && (alreadyChanged2->Get(divX*4+1+i*2,divY*4+j*2) < PIX8_LOWLIM) &&
00199 (alreadyChanged2->Get(divX*4+i*2,divY*4+1+j*2) < PIX8_LOWLIM) && (alreadyChanged2->Get(divX*4+1+i*2,divY*4+1+j*2) < PIX8_LOWLIM) )
00200 {
00201 avg = average4->Get(divX*2+i,divY*2+j);
00202 AnalyzeArea(&dev,&avg, myX+4*i, myY+4*j, 4);
00203 alreadyChanged4->Set(divX*2+i,divY*2+j,dev);
00204 average4->Set(divX*2+i,divY*2+j,avg);
00205 }
00206 else
00207 alreadyChanged4->Set(divX*2+i,divY*2+j,0xFFFFFF);
00208 average4->Set(divX*2+i,divY*2+j,200);
00209
00210 if (alreadyChanged4->Get(divX*2,divY*2) < PIX8_MEDLIM && alreadyChanged4->Get(divX*2+1,divY*2) < PIX8_MEDLIM &&
00211 alreadyChanged4->Get(divX*2,divY*2+1) < PIX8_MEDLIM && alreadyChanged4->Get(divX*2+1,divY*2+1) < PIX8_MEDLIM )
00212 {
00213 avg = average8->Get(divX,divY);
00214 AnalyzeArea(&dev,&avg, myX, myY, 8);
00215 alreadyChanged8->Set(divX,divY,dev);
00216 average8->Set(divX,divY,avg);
00217 }
00218 else
00219 alreadyChanged8->Set(divX, divY, 0xFFFFFF);
00220
00221 }
00222
00223 void Pixel8Filter::DrawPixel(int x, int y, int size, int average, int borderIntensityPercent)
00224 {
00225 int intermediate;
00226
00227 if (size<=1)
00228 {
00229 for (int i=x; i<=x + size -1; i++)
00230 for (int j=y; j<= y + size -1; j++)
00231 {
00232 Set(i,j,Get(i,j)/2+average/2+3);;
00233 }
00234 }
00235 else
00236 {
00237 for (int i=x; i<x + size -1; i++)
00238 for (int j=y; j< y + size -1; j++)
00239 {
00240 intermediate=Get(i,j)/2+average/2+4;
00241 Set(i,j, intermediate >= 255 ? Get(i,j)/2+average/2 : intermediate);
00242 }
00243
00244 for (int i=x; i<=x + size-1; i++)
00245 Set(i,y+size-1, average>borderIntensityPercent ? Get(i,y+size-1)/2 + (average-borderIntensityPercent)/2 : 0);
00246
00247 for (int j=y; j<y +size -1; j++)
00248 Set(x+size-1,j,average>borderIntensityPercent ? Get(x+size-1,j)/2 + (average-borderIntensityPercent)/2 : 0);
00249 }
00250 }
00251
00252
00253