![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
|||
|
|||
|
Добрый день Помогите пожалуйста.
![]() Допустим есть на форме Image, в нём цветное изображение. Как мне узнать какого цвета там больше всего? Пробовал с помощью цыкла прочитать каждый пиксель (GetPixel), но как затем выбрать тот цвет, который больше всего повторяется? п.с. Может можно по другому это реализовать? Нужно чтобы побыстрее работало, а каждый пиксель однако будет долго проверять т.к. изображения будут обновлятся. п.п.с вообще изображение в image берётся с рабочего стола с помощью BitBlt (примерно 20х300 пикселей). Может можно напрямую работать? |
|
#2
|
||||
|
||||
|
Интересная задачка. Функция работает относительно быстро, я не оптимизировал. Проверял на рис(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; |
|
#3
|
|||
|
|||
|
Спасибо!! Проверил, работает. Но вот такого я не ожидал... както упустил из виду. Допустим изображение с моего раб. стола http://piccy.info/view3/3124218/1318...79d52281d9e59/ так код определяет белый цвет. а визуально больше синего же... тоесть градиент синего, это не точно синий, а разные.... не подскажите что в таком случае делать?
|
|
#4
|
||||
|
||||
|
Думаю, в таком случае логичнее было бы делать не цвет, которого больше всего, а среднее арифметическое всех цветов картинки. Или же сравнивать с допущениями (+/- столько-то по каждой компоненте цвета). Правда при этом сильно усложнится код, да и вести себя будет не всегда предсказуемо (будет немного зависеть от того, какой цвет раньше попался).
|
|
#5
|
|||
|
|||
|
можно уменьшить качество картинки
|
| Этот пользователь сказал Спасибо Pyro за это полезное сообщение: | ||
firewall (10.06.2012)
| ||
|
#6
|
|||
|
|||
|
Цитата:
|
|
#7
|
||||
|
||||
|
Цитата:
![]() Тогда частенько цвет, который будет на выходе, не будет встречаться на самой картинке; это будет какой-то средний цвет для всего изображения. Для того скрина, скорее всего, это будет синий с небольшим отливом в бледно-желтый. Кстати, совет от Pyro тоже может помочь. Последний раз редактировалось Bargest, 10.06.2012 в 18:06. |
| Этот пользователь сказал Спасибо Bargest за это полезное сообщение: | ||
firewall (10.06.2012)
| ||
|
#8
|
||||
|
||||
|
Средний цвет хорошо и быстро определяется на картинке где-то при 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; |
| Этот пользователь сказал Спасибо AND_REY за это полезное сообщение: | ||
firewall (10.06.2012)
| ||
|
#9
|
|||
|
|||
|
Спасибо всем кто отписался!! Отдельное спасибо AND_REY ! Твой код работает, скорее всего на нём и останусь! Спасибо!
|
|
#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 системе...и работать с ним))) |