|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
Получить цвет которого больше всего в image
Добрый день Помогите пожалуйста.
Допустим есть на форме 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; If end Then begin; |
#3
|
|||
|
|||
Спасибо!! Проверил, работает. Но вот такого я не ожидал... както упустил из виду. Допустим изображение с моего раб. стола http://piccy.info/view3/3124218/1318...79d52281d9e59/ так код определяет белый цвет. а визуально больше синего же... тоесть градиент синего, это не точно синий, а разные.... не подскажите что в таком случае делать?
|
#4
|
||||
|
||||
Думаю, в таком случае логичнее было бы делать не цвет, которого больше всего, а среднее арифметическое всех цветов картинки. Или же сравнивать с допущениями (+/- столько-то по каждой компоненте цвета). Правда при этом сильно усложнится код, да и вести себя будет не всегда предсказуемо (будет немного зависеть от того, какой цвет раньше попался).
jmp $ ; Happy End! The Cake Is A Lie. |
#5
|
|||
|
|||
можно уменьшить качество картинки
|
Этот пользователь сказал Спасибо Pyro за это полезное сообщение: | ||
firewall (10.06.2012)
|
#6
|
|||
|
|||
Цитата:
|
#7
|
||||
|
||||
Цитата:
Тогда частенько цвет, который будет на выходе, не будет встречаться на самой картинке; это будет какой-то средний цвет для всего изображения. Для того скрина, скорее всего, это будет синий с небольшим отливом в бледно-желтый. Кстати, совет от Pyro тоже может помочь. jmp $ ; Happy End! The Cake Is A Lie. Последний раз редактировалось 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; If end Then begin; |
Этот пользователь сказал Спасибо 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 системе...и работать с ним))) |