Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Графика и игры
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 10.06.2012, 14:50
firewall firewall вне форума
Прохожий
 
Регистрация: 10.06.2012
Сообщения: 4
Репутация: 10
По умолчанию Получить цвет которого больше всего в image

Добрый день Помогите пожалуйста.

Допустим есть на форме Image, в нём цветное изображение. Как мне узнать какого цвета там больше всего?

Пробовал с помощью цыкла прочитать каждый пиксель (GetPixel), но как затем выбрать тот цвет, который больше всего повторяется?

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

п.п.с вообще изображение в image берётся с рабочего стола с помощью BitBlt (примерно 20х300 пикселей). Может можно напрямую работать?
Ответить с цитированием
  #2  
Старый 10.06.2012, 16:49
Аватар для AND_REY
AND_REY AND_REY вне форума
Активный
 
Регистрация: 31.03.2009
Адрес: Украина, г.Днепропетровск
Сообщения: 324
Версия Delphi: Delphi7
Репутация: 3877
По умолчанию

Интересная задачка. Функция работает относительно быстро, я не оптимизировал. Проверял на рис(1920х1080) 2-3 сек гдето.
Код:
Function GetMaxColorBmp(B: TBitmap): TColor;
Const
 Pixels = MaxInt div SizeOf(TRGBTriple);
Type
 PRGBArray = ^TRGBArray;
 TRGBArray = Array[0..Pixels - 1] of TRGBTriple;
Var
 Line: PRGBArray;
 Mx, My: Array of Integer;
 i, j: Integer;
 Function GetMaxPovtor(M: Array of Integer): Integer;
 Var
  x, y, mi, mk, k: Integer;
 begin
  mi:= M[1]; mk:= 1; k:= 0;
  For x:= 0 To High(M) Do
   begin
    For y:= 0 To High(M) Do if M[x] = M[y] Then Inc(k);
    if ((mk = k) And (mi > M[x])) Or (mk < k) Then
     begin
      mi:= M[x];
      mk:= k;
     end;
    k:= 0;
   end;
  Result:= mi;
 end;
begin
 Result:= clWhite;
 B.PixelFormat:= pf24bit;
 SetLength(Mx, B.Width);
 SetLength(My, B.Height);
 For j:= 0 To B.Height - 1 Do
  begin
   Line:= B.ScanLine[j];
   For i:= 0 To B.Width - 1 Do
    begin
     Mx[i]:= Line[i].rgbtRed + (Line[i].rgbtGreen Shl 8) + (Line[i].rgbtBlue Shl 16);
    end;
   My[j]:= GetMaxPovtor(Mx);
  end;
 Result:= GetMaxPovtor(My);
end;
__________________
If end Then begin;
Ответить с цитированием
  #3  
Старый 10.06.2012, 17:36
firewall firewall вне форума
Прохожий
 
Регистрация: 10.06.2012
Сообщения: 4
Репутация: 10
По умолчанию

Спасибо!! Проверил, работает. Но вот такого я не ожидал... както упустил из виду. Допустим изображение с моего раб. стола http://piccy.info/view3/3124218/1318...79d52281d9e59/ так код определяет белый цвет. а визуально больше синего же... тоесть градиент синего, это не точно синий, а разные.... не подскажите что в таком случае делать?
Ответить с цитированием
  #4  
Старый 10.06.2012, 17:43
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Думаю, в таком случае логичнее было бы делать не цвет, которого больше всего, а среднее арифметическое всех цветов картинки. Или же сравнивать с допущениями (+/- столько-то по каждой компоненте цвета). Правда при этом сильно усложнится код, да и вести себя будет не всегда предсказуемо (будет немного зависеть от того, какой цвет раньше попался).
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
Ответить с цитированием
  #5  
Старый 10.06.2012, 17:48
Pyro Pyro вне форума
Так проходящий
 
Регистрация: 18.07.2011
Сообщения: 805
Версия Delphi: 7Lite
Репутация: 6063
По умолчанию

можно уменьшить качество картинки
Ответить с цитированием
Этот пользователь сказал Спасибо Pyro за это полезное сообщение:
firewall (10.06.2012)
  #6  
Старый 10.06.2012, 17:49
firewall firewall вне форума
Прохожий
 
Регистрация: 10.06.2012
Сообщения: 4
Репутация: 10
По умолчанию

Цитата:
Сообщение от Bargest
Думаю, в таком случае логичнее было бы делать не цвет, которого больше всего, а среднее арифметическое всех цветов картинки.
а как примерно такое реализовать? просто с таким я ещё не встречался, поэтому даже не знаю(
Ответить с цитированием
  #7  
Старый 10.06.2012, 18:03
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Цитата:
а как примерно такое реализовать? просто с таким я ещё не встречался, поэтому даже не знаю
Пройти по всем пикселям, просуммировать компоненты RGB в соответствующие переменные и поделить все 3 переменные на количество пикселей.
Тогда частенько цвет, который будет на выходе, не будет встречаться на самой картинке; это будет какой-то средний цвет для всего изображения. Для того скрина, скорее всего, это будет синий с небольшим отливом в бледно-желтый.
Кстати, совет от Pyro тоже может помочь.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.

Последний раз редактировалось Bargest, 10.06.2012 в 18:06.
Ответить с цитированием
Этот пользователь сказал Спасибо Bargest за это полезное сообщение:
firewall (10.06.2012)
  #8  
Старый 10.06.2012, 18:51
Аватар для AND_REY
AND_REY AND_REY вне форума
Активный
 
Регистрация: 31.03.2009
Адрес: Украина, г.Днепропетровск
Сообщения: 324
Версия Delphi: Delphi7
Репутация: 3877
По умолчанию

Средний цвет хорошо и быстро определяется на картинке где-то при 75% одинакового цвета.
Код:
Function GetMaxColorBmp(B: TBitmap): TColor;
Type
 PRGBArray = ^TRGBArray;
 TRGBArray = Array[0..65535] of TRGBTriple;
Var
 Line: PRGBArray;
 i, j, Pix: Integer;
 _r, _g, _b: Extended;
begin
 _r:= 0; _g:= 0; _b:= 0;
 Result:= clWhite;
 B.PixelFormat:= pf24bit;
 For j:= 0 To B.Height - 1 Do
  begin
   Line:= B.ScanLine[j];
   For i:= 0 To B.Width - 1 Do
    begin
     _r:= _r + Line[i].rgbtRed;
     _g:= _g + Line[i].rgbtGreen;
     _b:= _b + Line[i].rgbtBlue;
    end;
  end;
 Pix:= B.Width*B.Height;
 Result:= RGB(Round(_r/Pix), Round(_g/Pix), Round(_b/Pix));
end;
__________________
If end Then begin;
Ответить с цитированием
Этот пользователь сказал Спасибо AND_REY за это полезное сообщение:
firewall (10.06.2012)
  #9  
Старый 10.06.2012, 19:05
firewall firewall вне форума
Прохожий
 
Регистрация: 10.06.2012
Сообщения: 4
Репутация: 10
По умолчанию

Спасибо всем кто отписался!! Отдельное спасибо AND_REY ! Твой код работает, скорее всего на нём и останусь! Спасибо!
Ответить с цитированием
  #10  
Старый 24.09.2012, 15:06
QT8 QT8 вне форума
Прохожий
 
Регистрация: 05.11.2010
Сообщения: 2
Репутация: 10
По умолчанию

а что если вначале усреднить цвет...

Следующим немаловажным этапом нормализации изображения, явля-
ется нормирование яркости. Выполнение данного преобразования направ-
лено на снижение нестабильности яркостных параметров изображения, ко-
торое особо негативно сказывается на результатах работы тех методов
распознавания, в которых исходными признаками являются значения пик-
селей.
Одним из методов нормализации такого рода, является изменение гис-
тограммы распределения яркости. Операция нормирования гистограммы
направлена на то, чтобы распределить значения интенсивности пикселей
по всему диапазону уровней яркости от 0 до 255. Операция нормирования
яркости изображений была реализована следующим образом:
Gi j =255(Zij –Zmin)/(Zmax –Zmin ), (2)
где Zij – пиксель исходного изображения,i=1, 2, …, H и j = 1, 2, …, W;
H и W – высота и ширина изображения соответственно; Zmin – минималь-
ное значение яркости исходного изображения; Zmax – максимальное зна-
чение яркости исходного изображения; Gij – пиксель изображения с видо-
измененной гистограммой [1].


только вначале пройтись по картинке, по всех пикселях и найти самый большой и маленький код в 16 системе...и работать с ним)))
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 20:17.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter