|
Java форум JavaTalks форум программистов
|
|
|
|
| Предыдущая тема :: Следующая тема |
| Автор |
Сообщение |
svjatoslav : 4 Новичок
|
Май 25, 2011 0:00 |
|
|
Повышение/снижение контрастности – это, соответственно, умножение/деление значения каждого канала на некоторое фиксированное значение (в том числе действительное), что приводит к изменению соотношений между цветами и, соответственно, к более чётким цветовым границам. На практике же существует такой принцип: изменение контрастности не должно приводить к изменению средней яркости по изображению, поэтому пользуются следующей формулой:
NewY := K * (OldY - AvgY) + AvgY,
где NewY – новое значение одного из каналов, K – коэффициент контрастности (K=(0..1) – снижение, K>1 – повышение контрастности), OldY – текущее значение того же канала, AvgY – среднее значение того же канала по изображению (таким образом, алгоритм фактически является двухпроходовым). Обязательна всё та же коррекция нового значения при выходе его за границы 0..255.
Помогите с алгоритмом по контрасту(теория выше). Он должен работать при k от -2.0 до +2.0. Но он работает неправильно и я немогу понять в чем дело.
| Код: |
public class BrightnessContrast {
int[] input;
int[] output;
int progress;
int width;
int height;
public BrightnessContrast() {
}
public void init(int[] original, int widthIn, int heightIn) {
width=widthIn;
height=heightIn;
input = new int[width*height];
output = new int[width*height];
input=original;
}
public int[] process() {
char r = 0, g = 0, b = 0;
int rsum = 0, gsum = 0, bsum = 0;
char rmid, gmid, bmid; //среднее значение яркости
float k = 1.5f;
for(int x=0; x<width;x++) {
for(int y=0; y<height;y++) {
r = (char)((input[y*width+x] >> 16) & 0xff);
g = (char)((input[y*width+x] >> 8) & 0xff);
b = (char)(input[y*width+x] & 0xff);
rsum += r;
gsum += g;
bsum += b;
}
}
rmid = (char)(rsum / (width*height));
gmid = (char)(gsum / (width*height));
bmid = (char)(bsum / (width*height));
for(int x=0; x<width;x++) {
for(int y=0; y<height;y++) {
r = (char)((input[y*width+x] >> 16) & 0xff);
g = (char)((input[y*width+x] >> 8) & 0xff);
b = (char)(input[y*width+x] & 0xff);
rmid = (char)(0.30f*r + 0.59f*g + 0.11f*b);
gmid = (char)(0.30f*r + 0.59f*g + 0.11f*b);
bmid = (char)(0.30f*r + 0.59f*g + 0.11f*b);
r = (char)(k*(r-rmid)+rmid);
if (r < 0) r = 0;
else if (r > 255) r = 255;
g = (char)(k*(g-gmid)+gmid);
if (g < 0) g = 0;
else if (g > 255) g = 255;
b = (char)(k*(b-bmid)+bmid);
if (b < 0) b = 0;
else if (b > 255) b = 255;
output[y*width+x] = 255<<24 | r<<16 | g<<8 | b;
}
}
return output;
}
}
|
Или помогите с алгоритмом линейного контрастирования только не теорией, а алгоритмом. |
|
|
|
 |
svjatoslav : 4 Новичок
|
Май 26, 2011 23:22 |
|
|
Разобрался сам. Выкладываю код линейного изменения контраста, может кому пригодиться.
| Код: |
package temp;
public class Contrast extends Algorithm {
int[] input;
int[] output;
int width;
int height;
int gmin;
int gmax;
public void init(int[] original, int widthIn, int heightIn, int val1In, int val2In) {
gmin = val1In;
gmax = val2In;
width=widthIn;
height=heightIn;
input = new int[width*height];
output = new int[width*height];
input=original;
maxprogress = width;
}
public int[] process() {
char r = 0, g = 0, b = 0;
int fminR = 255, fmaxR = 1, fminG = 255, fmaxG = 1, fminB = 255, fmaxB = 1;
for(int x=0; x<width;x++) {
for(int y=0; y<height;y++) {
r = (char)((input[y*width+x] >> 16) & 0xff);
g = (char)((input[y*width+x] >> 8) & 0xff);
b = (char)(input[y*width+x] & 0xff);
if (r < fminR) fminR = r;
if (r > fmaxR) fmaxR = r;
if (g < fminG) fminG = g;
if (g > fmaxG) fmaxG = g;
if (b < fminB) fminB = b;
if (b > fmaxB) fmaxB = b;
}
}
for(int x=0; x<width;x++) {
progress++;
for(int y=0; y<height;y++) {
r = (char)((input[y*width+x] >> 16) & 0xff);
g = (char)((input[y*width+x] >> 8) & 0xff);
b = (char)(input[y*width+x] & 0xff);
r = (char)((r-fminR)*(gmax-gmin)/(fmaxR-fminR)+gmin);
if (r < 0) r = 0;
if (r > 255) r = 255;
g = (char)((g-fminG)*(gmax-gmin)/(fmaxG-fminG)+gmin);
if (g < 0) g = 0;
if (g > 255) g = 255;
b = (char)((b-fminB)*(gmax-gmin)/(fmaxB-fminB)+gmin);
if (b < 0) b = 0;
if (b > 255) b = 255;
output[y*width+x] = 255<<24 | r<<16 | g<<8 | b;
}
}
return output;
}
}
|
|
|
|
|
 |
|
|
|