Конференция "Media" » Принцип работы инструментов автокоррекции изображений
 
  • Pavia © (08.08.07 15:05) [20]
    При изменении контрасности яркость не должна меняться. Но когда мы делаем автоконтраст яркость у нас тоже меняется.

    Если уж не терпиться просто вычти из R,G,B значение  127-HMean. HMean - средне арефметическое по гистограмме.
    for i:=0 to 255 do HMean:=HMean+i*Hist[i];
    HMean:=HMean div 255;



    Есть еще выравнивание освещенности. Тут если не в доваться в теорию. То делаем размытие по некоторому радиусу. И делим исходное изоброжение на размытое. Есть и более сложные мотоды.
  • Pavia © (08.08.07 15:10) [21]
    Хотя чето с вычислением HMean я напутал,
  • DVM © (08.08.07 15:12) [22]

    > а как быть с автояркостью, ее как реализовать?

    В отличии от контраста, с яркостью не все так просто. Нет четкого определения достаточно или недостаточно яркого изображения. В том же фотошопе нет такого действия автояркость, но есть автоконтраст.

    Поэтому надо определиться сначала с нижней и верхней границей яркости и потом двигать яркость изображения в зону между этими границами.
  • leonid (09.08.07 16:47) [23]
    сделал так:

    //считаем ср. арифм. по гистограмме
    for i:=0 to 255 do HMean:=HMean+i*Hist[i];
    HMean:=HMean div 255;

    for i:=0 to bp.Height-1 do
    begin
    p:=bp.ScanLine[i];
    for j:=0 to bp.Width-1 do
    begin
    B:=Round(p[j*3+0]-(127-HMean));
    G:=Round(p[j*3+1]-(127-HMean));
    R:=Round(p[j*3+2]-(127-HMean));

    p[j*3+0]:=B;
    p[j*3+1]:=G;
    p[j*3+2]:=R;
    end;
    end;
    end;

    но почему-то вместо осветления получил какое-то странное смещение цветов.  Но в общем сам аглоритм осветления или затемнения всей фотографии я нашел, вопрос в другом, как принять решении о применеии того или иного алгоритма, и насколько именно затемнять или осветлять фотку... а что если гистограммы разделить на две части и посчитать среднее значение слева и справо, соотв. если слева значение больше, то фотка темная, если справа больше - то светлая. Как вы считаете это реально?
  • DVM © (09.08.07 17:00) [24]

    > Как вы считаете это реально?

    Реально, но что будет в результате сказать сложно.
  • leonid (09.08.07 17:25) [25]
    А какие еще приемлемые способы существуют?
  • Pavia © (09.08.07 19:44) [26]
    Реально, просто я тогда малость ошибся.
    s:=0;
    HMean:=0;
    for i:=0 to 255 do
    begin
    HMean:=HMean+i*Hist[i];
    s:=s+Hist[i];
    end;
    HMean:=Round(HMean/S);


    Но вот насчет осветления. Осветление не обязана быть линейной операцией. Почитай про гаммо коррекцию.
  • Pavia © (09.08.07 19:56) [27]
    А вообще там нет проверки выхода за границу если меньше 0 то пишем 0 если больше 255 то 255
  • leonid (09.08.07 22:39) [28]
    >А вообще там нет проверки выхода за границу
    Где нету проверки?
  • leonid (11.08.07 18:01) [29]
    >Pavia  сейчас экспериментировал с фотошоповским инструментом "автоконтраст", и как вы верно заметили автоконтраст делается за счет равномерного растяжения гистограммы и заполнения нулевых или близким к нулю элементов гистограммы. Однако я сейчас сверил фотошопом картинку до преобразования вашим кодом и после, гистограмма практически одинаковая, хотя сам фотошоп на тойже картинке автоконтраст не сильный но делает, и гистограмма там явно смещается. Гдеже загвоздка? Фотку могу выложить на которой проводил эксперимент.
  • Ricks © (12.08.07 21:09) [30]
    Помучался я над вашей проблемой и вот что получилось:
    http://www.ricks.pisem.net/test.zip

    улучшал в два прохода.
    в первом выравниваются цвета, для чего по каждому каналу находиться среднее значение (можно и с помощью гистограммы), потом находится общее среднее mean = (meanR + meanG + meanB) / 3 и для каждого канала
    делаем
    new[R, G, B]:=old[R, G, B] - (mean[R, G, B] - mean)
    (на моем тестовом рисунке убирается излишек синего цвета)

    во втором проходе выравниваются контраст (наверное ;))
    для чего находим минимум и максимум "светлоты" и для каждого канала
    new[R, G, B]:=255 * (old[R, G, B] - minL) / (maxL - minL)
    формулу эту спер отсюда же, у Pavia :)

    вроде бы неплохо выравнивает :)
  • Ricks © (12.08.07 21:11) [31]

    > во втором проходе выравниваются контраст (наверное ;))
    для чего находим минимум и максимум "светлоты" и для каждого
    канала



    загнался :)

    находим не для каждого канала min и max светлоты (т.к это бред :)), а просто минимум и максимум светлоты изображения
  • leonid (14.08.07 17:18) [32]
    Ricks большое спасибо за потраченное время, сейчас буду смотреть.
  • leonid (14.08.07 17:20) [33]
    Ricks а можно код глянуть?
  • Ricks © (16.08.07 19:18) [34]
    только код почти весь в моих типах, догадайся сам :)

    var
      HIST : ImageHistogram;
      HISR : ImageHistogram;
      HISG : ImageHistogram;
      HISB : ImageHistogram;

    ...

    var D : PRGBAArray;
       V : array [0..2] of PRGBAArray;
       H : tagBITMAPINFO;
       B : TBitmap;
       N : Cardinal;
       J : Cardinal;
       L : TLabRec;
       A : TRGBARec;
       lMin, lMax : single;
       hMean      : array [0..3] of single;
       sMean      : array [0..2] of single;
    begin
    N:=ExtractImageData(SourceImage.Picture.Bitmap.Handle, H, D);
    V[0]:=AllocMem( N * 4 );
    V[1]:=AllocMem( N * 4 );
    V[2]:=AllocMem( N * 4 );

    lMax:=0;
    lMin:=255;
    FillChar(HIST, SizeOf(HIST), 0);
    for J:=0 to pred(N) do begin
     L:=RGBAtoLab( D^[J] );
     if L.L > lMax then lMax:=L.L;
     if L.L < lMin then lMin:=L.L;
     Inc(HIST[ Round(L.L)  ]);
     Inc(HISR[ D^[J].Red   ]);
     Inc(HISG[ D^[J].Green ]);
     Inc(HISB[ D^[J].Blue  ]);
    end;

    FillChar(hMean, SizeOf(hMean), 0);
    FillChar(sMean, SizeOf(sMean), 0);
    for J:=0 to 255 do begin
     hMean[0]:=hMean[0] + j * HISR[J]; sMean[0]:=sMean[0] + HISR[J];
     hMean[1]:=hMean[1] + j * HISG[J]; sMean[1]:=sMean[1] + HISG[J];
     hMean[2]:=hMean[2] + j * HISB[J]; sMean[2]:=sMean[2] + HISB[J];
    end;

    hMean[0]:=hMean[0] / sMean[0];
    hMean[1]:=hMean[1] / sMean[1];
    hMean[2]:=hMean[2] / sMean[2];
    hMean[3]:=(hMean[0] + hMean[1] + hMean[2]) / 3;

    for J:=0 to pred(N) do begin
     V[0]^[J]:=D^[J];

     A.Blue:= ByteLim( D^[J].Blue  - (hMean[2] - hMean[3]) );
     A.Green:=ByteLim( D^[J].Green - (hMean[1] - hMean[3]) );
     A.Red:=  ByteLim( D^[J].Red   - (hMean[0] - hMean[3]) );
     V[1]^[J]:=A;
    end;

    for J:=0 to pred(N) do begin
     L:=RGBAtoLab( V[1]^[J] );
     if L.L > lMax then lMax:=L.L;
     if L.L < lMin then lMin:=L.L;
    end;
    for J:=0 to pred(N) do begin
     A.Blue:= ByteLim( 255 * (V[1]^[J].Blue  - lMin) / (lMax - lMin) );
     A.Green:=ByteLim( 255 * (V[1]^[J].Green - lMin) / (lMax - lMin) );
     A.Red:=  ByteLim( 255 * (V[1]^[J].Red   - lMin) / (lMax - lMin) );
     V[2]^[J]:=A;
    end;
    .....

 
Конференция "Media" » Принцип работы инструментов автокоррекции изображений
Есть новые Нет новых   [134431   +10][b:0][p:0.002]