HSV. Проблема с подсчетом белого цвета
Доброго времени суток. Пишу программу, которая выполняет попиксельный анализ изображения. Суть проста - переводим из rgb в hvs, и находим кол-во пикселей определённых цветов (red,yellow,green,blue,purple,orange,black,gray,wh ite).
Возникла проблема с подсчётом белого цвета. Для проверки использовал изображение абсолютно белого цвета 10*10 pix, программа считает и находит на 100 возможный пикселей 121 пиксель белого цвета. Уже давно мучаюсь, но не могу понять в чем проблема. С остальными цветами всё впорядке - считает довольно точно.
код ниже.
Код:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Math, StdCtrls, Buttons, ExtCtrls, Jpeg;
type
TForm1 = class(TForm)
BitBtn1: TBitBtn;
OpenDialog1: TOpenDialog;
SaveDialog1: TSaveDialog;
img1: TImage;
procedure BitBtn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
type
{user defined types here}
TRGBColor = record //тип для хранения отдельных значений rgb-цвета
R,
G,
B : Byte;
end;
{тип для хранения HSB-цвета. Hue, Saturation, Brightness — оттенок, насыщенность, яркость}
THSBColor = record
Hue, //оттенок
Sat, //насыщенность
Br : Double; // яркость
end;
var red,yellow,green,blue,purple,
orange,black,gray,white,picsize{размер изображения}: Integer;
picpr{сколько пикселей в одном проценте площади изображения}: Double;
function RGBToHSB(rgb : TRGBColor) : 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;
Sat := s * 100 / 255;
Br := b * 100 / 255;
end;
end;
procedure TForm1.BitBtn1Click(Sender: TObject);
var
i,j,k: Integer;
c: TColor;
col: TRGBColor; //объявляем переменную для хранения rgb-цвета
colhsb: THSBColor; //аналогично для hsb-цвета
f:TextFile;
pred,pyellow,pgreen,pblue,ppurple,
porange,pblack,pgray:double;
psum:integer;
begin
if OpenDialog1.Execute
then
if SaveDialog1 .Execute then
begin
AssignFile(f, SaveDialog1.FileName+'.txt');
ReWrite(f);
for k:=0 to OpenDialog1.Files.Count-1 do
begin
{обнуляем количества пикселей, считаем размер изображения и количество пикселей в одном его проценте}
red:=0;
yellow:=0;
green:=0;
blue:=0;
purple:=0;
orange:=0;
black:=0;
gray:=0;
white:=0;
img1.Picture:=nil;
img1.Picture.LoadFromFile(OpenDialog1.Files[k]);
picsize:=img1.Picture.Width * img1.Picture.Height;
picpr:=picsize/100;
for i:=0 to img1.Picture.Width do
for j:=0 to img1.Picture.Height do
begin
c:= img1.Canvas.Pixels[i, j]; // попиксельно считываем цвет
col.R:=GetRValue(c); //берем красную составляющую
col.G:=GetGValue(c); //берем зеленую составляющую
col.B:=GetBValue(c); //берем синюю составляющую
colhsb:=RGBToHSB(col); //преобразуем цвет
{блок условий для красного, оранжевого, желтого, зеленого, синего и фиолетового цветов}
if (colhsb.Sat>10) and (colhsb.Br>50) then
begin
if (colhsb.Hue<25) or ((colhsb.Hue>340) and (colhsb.Hue<360)) then
Inc(red);
if (colhsb.Hue>25) and (colhsb.Hue<44) then
Inc(orange);
if (colhsb.Hue>44) and (colhsb.Hue<70) then
Inc(yellow);
if (colhsb.Hue>70) and (colhsb.Hue<140) then
Inc(green);
if (colhsb.Hue>140) and (colhsb.Hue<250) then
Inc(blue);
if (colhsb.Hue>250) and (colhsb.Hue<320) then
Inc(purple);
end;
//условия для белого и серого цветов.
if ((((colhsb.Sat>=0) and (colhsb.Sat<=10))) and (((colhsb.Br>90) and (colhsb.Br<=100)))) then
Inc(white);
if ((((colhsb.Sat>=0) and (colhsb.Sat<=10))) and (((colhsb.Br>=11) and (colhsb.Br<=89)))) then
Inc(gray);
{условия для черного цвета - яркость меньше 10}
if (colhsb.Br<10) then
Inc(black);
end;
writeln(f,' Yellow Red Green Blue Purple Orange Black Gray White TotalPixCount');
writeln(f,OpenDialog1.Files[k]+' '+IntToStr(yellow)+' '+IntToStr(red)+' '+IntToStr(green)+' '+IntToStr(blue)+' '+IntToStr(purple)+' '+IntToStr(orange)+' '+IntToStr(black)+' '+IntToStr(gray)+' '+IntToStr(white)+' '+IntToStr(picsize));
writeln(f, ' ')
end; // cycle
CloseFile(f);
end; //saveFdlg
end;
end.
Заранее спасибо за помощь.
З.Ы.
Считаю, что проблема в этом участке, но не могу понять как её решить.
Код:
if ((((colhsb.Sat>=0) and (colhsb.Sat<=10))) and (((colhsb.Br>90) and (colhsb.Br<=100)))) then
Inc(white);
|