Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2011.12.11;
Скачать: [xml.tar.bz2];

Вниз

(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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.48 MB
Время: 0.004 c
4-1252784613
Ruzzz
2009-09-12 23:43
2011.12.11
Фишки Vista/Win7 в Delphi (типа прогресс в панеле задач)


3-1268216193
Xmen
2010-03-10 13:16
2011.12.11
Экспорт из Excel в FireBird


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


6-1246793442
__Алексей__
2009-07-05 15:30
2011.12.11
впорос по SNMP v3


4-1242382646
Игорь
2009-05-15 14:17
2011.12.11
Функция IsProcessInJob в Windows 2000





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский