Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2011.12.11;
Скачать: CL | DM;

Вниз

(Y:=0.3*R+0.59*G+0.11*B)   Найти похожие ветки 

 
анонимус   (2011-08-21 20:42) [0]

Преобразование к оттенкам серого заключается в получении яркости каждой точки по известной формуле (Y:=0.3*R+0.59*G+0.11*B) и последующем копировании полученного значения по все три канала (R=G=B:=Y).

Пытаясь воспользоваться данным утверждением, на выходе получаю черный экран. Что же на самом деле делать с этой формулой? )

procedure ConvertBmpToGray(tBmp: TBitmap);
var
  QP: TQuickPixels;
  Pixel1: Cardinal;
  Pixel2: Cardinal;
  r1: byte;
  g1: byte;
  b1: byte;
  r2: byte;
  g2: byte;
  b2: byte;
  Intensity:byte;
  br2:byte;
  x:integer;
  y:integer;

begin

       QP := TQuickPixels.Create;
       QP.Attach(tBmp);

       //num:=0;
       for y := 0 to QP.Height-1 do
       begin
         for x := 0 to QP.Width-1 do
           begin
               Pixel1 := QP.GetPixels24(x,y);

               // Y (in YIQ) = 0.299R + 0.587G + 0.114B, which can be performed in
               // integer arithmetic as Y = (77R + 150G + 29B) DIV 256
               // See [Foley96, pp. 589-590]

//                r1 := (Pixel1 shr 23);
//                g1 := (Pixel1 shr 15);
//                b1 := (Pixel1 shr 7);

               r1 := (Pixel1 and $000000FF);
               g1 := (Pixel1  and $0000FF00) shr 8;
               b1 := (Pixel1 and $00FF0000) shr 16;

               Intensity:=byte(77*r1 + 150*g1 + 29*b1) SHR 8;
               //Intensity:= g1;

               IF   Intensity < 0
               THEN Intensity := 0
               ELSE
               IF   Intensity > 255
               THEN Intensity := 255;

               //br2:=r1+g1+b1;

               //br1:=FloatToDecimal(br2);
               r1:=Intensity;
               g1:=Intensity;
               b1:=Intensity;

               QP.SetPixels24(X, Y, RGB(r1,g1,b1));
           end;
        end;
        tBmp.SavetoFile("E:\test.bmp");
        qp.Free;

end;


 
анонимус   (2011-08-21 20:43) [1]

ах и да, если просто присвоить значение одного канала всем остальным, то на выходе как раз и получается серый цвет. Причем пофиг значение какого канала присваивать.


 
анонимус   (2011-08-21 20:46) [2]

Формула в коде выглядит так странно, ибо если умножать ее на коэффициэнты будет проблемма с преобразованием типов, поэтому нашел такой способ...


 
Anatoly Podgoretsky ©   (2011-08-21 21:15) [3]

> анонимус  (21.08.2011 20:42:00)  [0]

Убери byte(


 
анонимус   (2011-08-21 21:43) [4]

да, в оригинале было integer теперь стало лучше ))


 
Юрий Зотов ©   (2011-08-22 11:02) [5]


Intensity: byte;

Intensity := byte(77*r1 + 150*g1 + 29*b1) SHR 8; // Всегда 0

IF Intensity < 0 // Никогда не выполнится
 THEN Intensity := 0
ELSE
 IF Intensity > 255 // Никогда не выполнится
   THEN Intensity := 255;


 
Dimka Maslov ©   (2011-08-22 11:33) [6]

Intensity:=byte((77*r1 + 150*g1 + 29*b1) SHR 8)


 
Sha ©   (2011-08-22 15:16) [7]

По идее немного упростить и ускорить можно,
если списать преобразование цвета отсюда

function ShaColorToGray(Pixel: cardinal): cardinal;
begin;
  Result:=(Pixel and $0000FF00) * (150 * 256)
        + (Pixel and $00FF00FF) * (77 * 256 * 256 + 29);
  Result:=(Result shr 24) * (65536 + 256 + 1);
 end;


 
Sha ©   (2011-08-22 20:57) [8]

Или еще короче (но не быстрее) в 6 команд:
3 умножения, 1 сдвиг, 1 сложение, 1 "and"

function ShaRGBToGray(Pixel: integer): integer;
begin;
 Result:=(( Pixel * (150 * 256)
         + (Pixel and $00FF00FF) * (77 * 256 * 256 - 150 * 256 + 29)
          ) shr 24
         ) * (65536 + 256 + 1);
 end;


 
анонимус   (2011-08-23 05:43) [9]

нифига себе упростил.

выше же уже написали, что правильно не так
Intensity:=byte((77*r1 + 150*g1 + 29*b1) SHR 8)

а вот так

Intensity:=Integer(77*r1 + 150*g1 + 29*b1) SHR 8

Тогда работает.

проверка на 255 думаю лишняя, т.к. Intensity:byte и оно полюбому не выскочит за диапазон.


 
анонимус   (2011-08-23 06:05) [10]

мдя все таки лучше проверку оставить, а Intensity определить как Integer


 
Омлет ©   (2011-08-23 07:21) [11]

> анонимус   (23.08.11 05:43) [9]
> нифига себе упростил.


А ты посчитай количество операций. И сравни скорость.


 
Sha ©   (2011-08-23 09:37) [12]

> анонимус   (23.08.11 05:43) [9]

Попробуй заменить нутро своего цикла на


Pixel := QP.GetPixels24(x,y);
Pixel:=(( Pixel * (150 * 256)
         + (Pixel and $00FF00FF) * (77 * 256 * 256 - 150 * 256 + 29)
          ) shr 24
         ) * (65536 + 256 + 1);
QP.SetPixels24(X, Y, Pixel);


 
Sha ©   (2011-08-26 19:42) [13]

> Что же на самом деле делать с этой формулой? )

Вот тут подробно все расписал
http://guildalfa.ru/alsha/node/14



Страницы: 1 вся ветка

Текущий архив: 2011.12.11;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.01 c
15-1314131399
Юрий
2011-08-24 00:29
2011.12.11
С днем рождения ! 24 августа 2011 среда


15-1313785804
Юрий
2011-08-20 00:30
2011.12.11
С днем рождения ! 20 августа 2011 суббота


1-1276837690
Kukolev
2010-06-18 09:08
2011.12.11
Кнопки на панели задач


2-1314548803
Gu
2011-08-28 20:26
2011.12.11
Console


15-1314217798
Юрий
2011-08-25 00:29
2011.12.11
С днем рождения ! 25 августа 2011 четверг