вот я присобачил 2 версии в один модуль немного подкрутив одно к другому.
итак у нас программа и модуль
вот код модуля:
- Код: Выделить всё
unit RGB2HSV;
{$mode objfpc}{$H+}
interface
type
PFColor = ^TFColor;
TFColor = packed record
b, g, r: byte;
end;
THSBColor = record
hue,
saturnation,
brightness: double;
end;
procedure RGB2HSV(Src: PFColor; Out H, S, V: integer);
function rgbtohsb(var rgb: TFColor): THSBColor;
implementation
uses Math;
procedure RGB2HSV(Src: PFColor; out H, S, V: integer);
const
HSV_MAX_MUL = 360 shl 8;//это тоже не ясно что такое
var
Min, Max, Diff: integer;
begin
H := 0;
S := 0;
V := 0;
if (Src^.r < Src^.g) and (Src^.r < Src^.b) then
Min := Src^.r
else
if (Src^.g < Src^.b) then
Min := Src^.g
else
Min := Src^.b;
if (Src^.r > Src^.g) and (Src^.r > Src^.b) then
Max := Src^.r
else
if (Src^.g > Src^.b) then
Max := Src^.g
else
Max := Src^.b;
Diff := Max - Min;
if (Max <> 0) and (Diff <> 0) then
begin
S := ((Diff shl 8) div Max);
if S > 255 then
S := 255;
if Src^.r = Max then
H := ((Src^.g - Src^.b) shl 8) div Diff
else if Src^.g = Max then
H := $200 + ((Src^.b - Src^.r) shl 8) div Diff
else
H := $400 + ((Src^.r - Src^.g) shl 8) div Diff;
H := H * 60;
if H < 0 then
Inc(H, HSV_MAX_MUL)
else
if H >= HSV_MAX_MUL then
Dec(H, HSV_MAX_MUL);
H := H shr 8;
V := Max;
end;
end;
function rgbtohsb(var rgb: TFColor): THSBColor;
var
minrgb, maxrgb, delta: double;
h, s, b: double;
begin
h := 0.0;
minrgb := min(min(rgb.r, rgb.g), rgb.b);
maxrgb := max(max(rgb.r, rgb.g), rgb.b);
delta := (maxrgb - minrgb);
b := maxrgb;
if (maxrgb <> 0.0) then
s := 255.0 * delta / maxrgb
else
s := 0.0;
if (s <> 0.0) then
begin
if rgb.r = maxrgb then
h := (rgb.g - rgb.b) / delta
else
if rgb.g = maxrgb then
h := 2.0 + (rgb.b - rgb.r) / delta
else
if rgb.b = maxrgb then
h := 4.0 + (rgb.r - rgb.g) / delta;
end
else
h := -1.0;
h := h * 60;
if h < 0.0 then
h := h + 360.0;
with Result do
begin
hue := h;
saturnation := s * 100 / 255;
brightness := b * 100 / 255;
end;
end;
end.
вот код программы из которой видно, как эти функции использовать:
- Код: Выделить всё
program units_test;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes, RGB2HSV
{ you can add units after this };
var
h, s, v: integer;
aclr: TFColor;
r: THSBColor;
begin
aclr.r:= 100;
aclr.g:= 125;
aclr.b:= 255;
RGB2HSV.RGB2HSV(PFColor(@aclr), h, s, v);
r:= RGB2HSV.rgbtohsb(aclr);
writeln('R=', aclr.r, ' G=', aclr.g, ' B=', aclr.b, ' H= ', h,' S= ', s,' V= ', v);
writeln('R=', aclr.r, ' G=', aclr.g, ' B=', aclr.b, ' H= ', r.hue:2:3,' S= ', r.saturnation:2:3,' V= ', r.brightness:2:3);
writeln;
aclr.r:= 255;
aclr.g:= 125;
aclr.b:= 100;
r:= RGB2HSV.rgbtohsb(aclr);
RGB2HSV.RGB2HSV(PFColor(@aclr), h, s, v);
writeln('R=', aclr.r, ' G=', aclr.g, ' B=', aclr.b, ' H= ', h,' S= ', s,' V= ', v);
writeln('R=', aclr.r, ' G=', aclr.g, ' B=', aclr.b, ' H= ', r.hue:2:3,' S= ', r.saturnation:2:3,' V= ', r.brightness:2:3);
writeln;
aclr.r:= 255;
aclr.g:= 254;
aclr.b:= 253;
r:= RGB2HSV.rgbtohsb(aclr);
RGB2HSV.RGB2HSV(PFColor(@aclr), h, s, v);
writeln('R=', aclr.r, ' G=', aclr.g, ' B=', aclr.b, ' H= ', h,' S= ', s,' V= ', v);
writeln('R=', aclr.r, ' G=', aclr.g, ' B=', aclr.b, ' H= ', r.hue:2:3,' S= ', r.saturnation:2:3,' V= ', r.brightness:2:3);
writeln;
aclr.r:= 255;
aclr.g:= 255;
aclr.b:= 255;
r:= RGB2HSV.rgbtohsb(aclr);
RGB2HSV.RGB2HSV(PFColor(@aclr), h, s, v);
writeln('R=', aclr.r, ' G=', aclr.g, ' B=', aclr.b, ' H= ', h,' S= ', s,' V= ', v);
writeln('R=', aclr.r, ' G=', aclr.g, ' B=', aclr.b, ' H= ', r.hue:2:3,' S= ', r.saturnation:2:3,' V= ', r.brightness:2:3);
writeln;
aclr.r:= 0;
aclr.g:= 0;
aclr.b:= 0;
r:= RGB2HSV.rgbtohsb(aclr);
RGB2HSV.RGB2HSV(PFColor(@aclr), h, s, v);
writeln('R=', aclr.r, ' G=', aclr.g, ' B=', aclr.b, ' H= ', h,' S= ', s,' V= ', v);
writeln('R=', aclr.r, ' G=', aclr.g, ' B=', aclr.b, ' H= ', r.hue:2:3,' S= ', r.saturnation:2:3,' V= ', r.brightness:2:3);
writeln;
aclr.r:= 1;
aclr.g:= 1;
aclr.b:= 1;
r:= RGB2HSV.rgbtohsb(aclr);
RGB2HSV.RGB2HSV(PFColor(@aclr), h, s, v);
writeln('R=', aclr.r, ' G=', aclr.g, ' B=', aclr.b, ' H= ', h,' S= ', s,' V= ', v);
writeln('R=', aclr.r, ' G=', aclr.g, ' B=', aclr.b, ' H= ', r.hue:2:3,' S= ', r.saturnation:2:3,' V= ', r.brightness:2:3);
readln;
end.
исходя из вывода - результат второй функции (rgbtohsb) больше похож на правду
Добавлено спустя 8 минут 5 секунд:как это использовать в вашей задаче?
1. берете пиксел, получаете его значения rgb
2. с помощью одной из этих функций получаете значение оттенка - H (0 - 360)
3. определяете в какой цвет он "попал", например, "на глаз", если 0< H <20 - красный, если 21 < H < 40 - оранжевый и т.д., полученный цвет запоминаем
4. после того как просмотрели все пиксели - мы будем знать какие цвета присутствуют на картинке.
правильно ли я понял Вашу задачу? Понятно ли мое решение?