Обычная версия
Java форум JavaTalks
форум программистов

Поиск   Пользователи   Группы   Регистрация 
 Профиль   Личные сообщения 

 Вход 

Повышение/снижение контрастности
Список форумов
 ->  Работа с изображениями (Advanced Imaging API)


 
Начать новую тему 
Предыдущая тема :: Следующая тема  
Автор Сообщение
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;
   }
}

К началу Посмотреть профиль Отправить личное сообщение
 
Начать новую тему  Ответить на тему
Страница 1 из 1
Список форумов
 -> Работа с изображениями (Advanced Imaging API)


 
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах


Java and all Java-related trademarks and logos are trademarks or registered trademarks of Oracle Corporation in the United States and other countries.
Это сайт не относится к фирме Oracle Corporation и не поддерживается ею.

© 2006-2010 www.javatalks.ru: форум java программистов
Используется скрипт phpBB © 2001, 2010 phpBB Group

Хостинг от bizname.ru