Модераторы: Snowy, MetalFan, bems, Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Обработка изображений 
:(
    Опции темы
Neighbour
Дата 18.11.2008, 00:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 28
Регистрация: 20.3.2006

Репутация: нет
Всего: нет



Доброго времени суток, господа.

Пишу (пытаюсь  smile ) программу обработки изображений. Ну, фильтры там всякие и т.д. 

Возникает ряд вопросов, некоторые оч. тупые. Просто получилось совмещение изучения Delphi с написанием такой (на мой взгляд  для новичка не простой) программы. Но делать нечего.... Порыскал по поисковикам, почитал книжки, умыкнул куски кода  smile . Сорри, в  ощем сабж:

1. Преобразование изображения в оттенки серого
Код

procedure TForm1.mnuFilterGrayscaleClick(Sender: TObject);
 type
   TRGBTripleArray = array[0..10000] of TRGBTriple;
   PRGBTripleArray = ^TRGBTripleArray;
 var
   SL: PRGBTripleArray;
   l,p: Integer;
   R, G, B,Middle: Byte;

 begin
   with Image1.Canvas do
   begin
     Brush.Style  := bsClear;
     Pixels[1, 1] := Pixels[1, 1];
     for l := 0 to Image1.Picture.Bitmap.Height - 1 do
     begin
       SL := Image1.Picture.Bitmap.ScanLine[l];
       for p := 1 to Image1.Picture.Bitmap.Width - 1 do
       begin
         R := SL[p].rgbtRed;
         G := SL[p].rgbtGreen;
         B := SL[p].rgbtBlue;
         Middle:=round(R*0.222+G*0.707+B*0.071);
         SL[p].rgbtRed := Middle;
         SL[p].rgbtGreen := Middle;
         SL[p].rgbtBlue := Middle;
       end;
     end;
   end;
 end;



Все работает, но непонятно что делает 
Код

Pixels[1, 1] := Pixels[1, 1];

без него отказывается работать 

Кто-нибудь на пальцах про указатель на массив (да и просто про указатели) рассказать может? А то что скрывается за 
Код

 TRGBTripleArray = array[0..10000] of TRGBTriple;
   PRGBTripleArray = ^TRGBTripleArray;
 var
   SL: PRGBTripleArray;

для меня остается не то чтобы совсем непонятным, но чисто интуитивно догадываюсь.


2. В вышеуказанном примере изображение меняется так сказать "на лету". А если нужно наложить фильтр (или вычислить среднее значение яркости или еще чего) как организовать хранение промежуточного изображения? В общем, если можно, какую-нибудь заготовочку с пояснениями или пример хороший с пояснениями же. Т.е. с логикой я справлюсь, а вот техническая реализация для меня сложновата. 
 
Может быть вопросы изложены слишком сумбурно, но, поверьте, сформулировать поточнее то, о чем лишь догадываешься сложновато. В общем, приму любые советы по организации программы.

Заранее благодарен.





PM MAIL   Вверх
Alexeis
Дата 18.11.2008, 10:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 34
Всего: 459



Цитата(Neighbour @  17.11.2008,  23:18 Найти цитируемый пост)
Все работает, но непонятно что делает 
Выделить всёкод Pascal/Delphi
1:
    
Pixels[1, 1] := Pixels[1, 1];

без него отказывается работать 


Попробуй заменить ее на Image1.Picture.Bitmap.PixelFormat := Pf24Bit;
Т.е. указать явное преобразование из аппаратно зависимого растра в Dib секцию (прямая адресация картинки можно только для Dib секции) 

Цитата(Neighbour @  17.11.2008,  23:18 Найти цитируемый пост)
Кто-нибудь на пальцах про указатель на массив (да и просто про указатели) рассказать может? А то что скрывается за 

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


Цитата(Neighbour @  17.11.2008,  23:18 Найти цитируемый пост)
2. В вышеуказанном примере изображение меняется так сказать "на лету". А если нужно наложить фильтр (или вычислить среднее значение яркости или еще чего) как организовать хранение промежуточного изображения? В общем, если можно, какую-нибудь заготовочку с пояснениями или пример хороший с пояснениями же. Т.е. с логикой я справлюсь, а вот техническая реализация для меня сложновата. 

  Сумбурно.



--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
AntonN
Дата 18.11.2008, 13:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 491
Регистрация: 8.8.2006

Репутация: 3
Всего: 18



красивше так smile
Код

const
  MaxPixelCount = MaxInt div SizeOf(TRGBTriple);
type
  PRGBArray = ^TRGBArray;
  TRGBArray = array[0..MaxPixelCount-1] of TRGBTriple;


по второму - храни исходное изображение в битмапе, работу проводи над буфером (второй битмап).


--------------------
user posted image
PM MAIL WWW   Вверх
Neighbour
Дата 18.11.2008, 21:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 28
Регистрация: 20.3.2006

Репутация: нет
Всего: нет



Цитата

Попробуй заменить ее на Image1.Picture.Bitmap.PixelFormat := Pf24Bit;
Т.е. указать явное преобразование из аппаратно зависимого растра в Dib секцию (прямая адресация картинки можно только для Dib секции)


Не работает сволочь...

Еще вопросик. Как сделать максимальную Saturation в HSL представлении? Допустим, текущую насыщенность пикселя я вычислю S = sqrt(R*R+G*G+B*B-R*G-R*B-G*B), Как вычислить новые R G B при которых S была бы максимальноЙ? 
PM MAIL   Вверх
Neighbour
Дата 27.11.2008, 23:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 28
Регистрация: 20.3.2006

Репутация: нет
Всего: нет



В продолжение темы:

Делаю RGB->HSL->Saturation Max->RGB.

Код

procedure TForm1.mnuMaxSaturationClick(Sender: TObject);
 type
   TRGBTripleArray = array[0..10000] of TRGBTriple;
   PRGBTripleArray = ^TRGBTripleArray;
 var
   SL: PRGBTripleArray;
   line,p: Integer;
   R, G, B, ColorMin, ColorMax, DeltaMax: Single;
   H, S, L: Single;
   DeltaR, DeltaG, DeltaB: Single;
 begin
   with Image1.Canvas do
   begin
     Brush.Style:= bsClear;
     Pixels[1, 1]:= Pixels[1, 1];
     for line:= 0 to Image1.Picture.Bitmap.Height - 1 do
     begin
       SL:= Image1.Picture.Bitmap.ScanLine[line];
       for p:= 0 to Image1.Picture.Bitmap.Width - 1 do
       begin
         R:= SL[p].rgbtRed/255;
         G:= SL[p].rgbtGreen/255;
         B:= SL[p].rgbtBlue/255;
         ColorMin:= Min(Min(R,G),B);
         ColorMax:= Max(Max(R,G),B);
         DeltaMax:= ColorMax-ColorMin;
         L:= (ColorMin+ColorMax)/2;
           if DeltaMax=0 then
             begin
             H:=0;
             S:=0;
             end
           else begin
             if L<0.5 then S:=DeltaMax/(ColorMin+ColorMax)
             else S:=(DeltaMax/(2-ColorMax-ColorMin));

             DeltaR:=(((ColorMax-R)/6)+(ColorMax/2))/DeltaMax;
             DeltaG:=(((ColorMax-G)/6)+(ColorMax/2))/DeltaMax;
             DeltaB:=(((ColorMax-B)/6)+(ColorMax/2))/DeltaMax;

             if R=ColorMax then
               H:=DeltaB-DeltaG
             else
               if G=ColorMax then
               H:=(1/3)+DeltaR-DeltaB
             else
               if B=ColorMax then
               H:=(2/3)+DeltaG-DeltaR;

             if H<0 then
               H:=H+1
             else
               if H>1 then
               H:=H-1
           end;
       end;
         {SL[p].rgbtRed := Middle;}
         {SL[p].rgbtGreen := Middle;}
         {SL[p].rgbtBlue := Middle;}
     end;
   end;
 end;


Готов, как видите, лишь перевод из RGB в HSL.
Алгоритм взят с easyrgb.com

var_R = ( R / 255 )                     //RGB from 0 to 255
var_G = ( G / 255 )
var_B = ( B / 255 )

var_Min = min( var_R, var_G, var_B )    //Min. value of RGB
var_Max = max( var_R, var_G, var_B )    //Max. value of RGB
del_Max = var_Max - var_Min             //Delta RGB value

L = ( var_Max + var_Min ) / 2

if ( del_Max == 0 )                     //This is a gray, no chroma...
{
   H = 0                                //HSL results from 0 to 1
   S = 0
}
else                                    //Chromatic data...
{
   if ( L < 0.5 ) S = del_Max / ( var_Max + var_Min )
   else           S = del_Max / ( 2 - var_Max - var_Min )

   del_R = ( ( ( var_Max - var_R ) / 6 ) + ( del_Max / 2 ) ) / del_Max
   del_G = ( ( ( var_Max - var_G ) / 6 ) + ( del_Max / 2 ) ) / del_Max
   del_B = ( ( ( var_Max - var_B ) / 6 ) + ( del_Max / 2 ) ) / del_Max

   if      ( var_R == var_Max ) H = del_B - del_G
   else if ( var_G == var_Max ) H = ( 1 / 3 ) + del_R - del_B
   else if ( var_B == var_Max ) H = ( 2 / 3 ) + del_G - del_R

   if ( H < 0 ) ; H += 1
   if ( H > 1 ) ; H -= 1
}


Компилятор выдает, что значение переменной S never used и она равна 0 при любом условии,
а переменной H может быть не определено.

Где у меня ошибка, подскажите, пожалуйста.

Это сообщение отредактировал(а) Neighbour - 27.11.2008, 23:21
PM MAIL   Вверх
AntonN
Дата 28.11.2008, 01:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 491
Регистрация: 8.8.2006

Репутация: 3
Всего: 18



если не выполнится условие 
Код

if R=ColorMax then
               H:=DeltaB-DeltaG
             else
               if G=ColorMax then
               H:=(1/3)+DeltaR-DeltaB
             else
               if B=ColorMax then
               H:=(2/3)+DeltaG-DeltaR;

то Н будет неопределено


--------------------
user posted image
PM MAIL WWW   Вверх
Alexeis
Дата 28.11.2008, 10:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 34
Всего: 459



Модератор: Пожалуйста, один топик - один вопрос.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Для новичков"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0548 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.