![]() |
|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
|||
|
|||
![]() Доброго времени суток. Пишу программу, которая выполняет попиксельный анализ изображения. Суть проста - переводим из 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); Последний раз редактировалось c1pg, 29.11.2011 в 00:19. |
#2
|
||||
|
||||
![]() Честно говоря, непонятен смысл такой программы. Просто подсчитать количество используемых цветов недостаточно?
Je venus de nulle part 55.026263 с.ш., 73.397636 в.д. |
#3
|
|||
|
|||
![]() Нет, недостаточно. Этот код, по сути, должен ещё искать оттенки того или иного цвета ( например - синий и голубой ), а это, как я понимаю, возможно только в HSV. Поэтому пришлось писать таким образом.
|
#4
|
||||
|
||||
![]() Дык у тебя считает от 0 до 10 по обеим осям, а это 11 пикселей. 11*11 = 121, не? Вот тебе и ответ.
Оставайтесь хорошими людьми... VK id2634397, ds [at] phoenix [dot] dj |
#5
|
|||
|
|||
![]() Цитата:
Цитата:
Берём полностью белое изображение, получаем - Цитата:
|
#6
|
||||
|
||||
![]() Цитата:
Код:
for i:=0 to img1.Picture.Width do for j:=0 to img1.Picture.Height do Je venus de nulle part 55.026263 с.ш., 73.397636 в.д. |