Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Графика и игры
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 29.11.2011, 00:17
c1pg c1pg вне форума
Прохожий
 
Регистрация: 28.11.2011
Сообщения: 4
Репутация: 10
По умолчанию HSV. Проблема с подсчетом белого цвета

Доброго времени суток. Пишу программу, которая выполняет попиксельный анализ изображения. Суть проста - переводим из rgb в hvs, и находим кол-во пикселей определённых цветов (red,yellow,green,blue,purple,orange,black,gray,wh ite).
Возникла проблема с подсчётом белого цвета. Для проверки использовал изображение абсолютно белого цвета 10*10 pix, программа считает и находит на 100 возможный пикселей 121 пиксель белого цвета. Уже давно мучаюсь, но не могу понять в чем проблема. С остальными цветами всё впорядке - считает довольно точно.
код ниже.

Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
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.
Заранее спасибо за помощь.

З.Ы.
Считаю, что проблема в этом участке, но не могу понять как её решить.
Код:
1
2
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  
Старый 29.11.2011, 00:23
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Честно говоря, непонятен смысл такой программы. Просто подсчитать количество используемых цветов недостаточно?
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #3  
Старый 29.11.2011, 00:28
c1pg c1pg вне форума
Прохожий
 
Регистрация: 28.11.2011
Сообщения: 4
Репутация: 10
По умолчанию

Нет, недостаточно. Этот код, по сути, должен ещё искать оттенки того или иного цвета ( например - синий и голубой ), а это, как я понимаю, возможно только в HSV. Поэтому пришлось писать таким образом.
Ответить с цитированием
  #4  
Старый 29.11.2011, 01:16
Аватар для PhoeniX
PhoeniX PhoeniX вне форума
Always hardcore!
 
Регистрация: 04.03.2009
Адрес: СПб
Сообщения: 3,239
Версия Delphi: GCC/FPC/FASM
Репутация: 62149
По умолчанию

Дык у тебя считает от 0 до 10 по обеим осям, а это 11 пикселей. 11*11 = 121, не? Вот тебе и ответ.
__________________
Оставайтесь хорошими людьми...
VK id2634397, ds [at] phoenix [dot] dj
Ответить с цитированием
  #5  
Старый 29.11.2011, 01:29
c1pg c1pg вне форума
Прохожий
 
Регистрация: 28.11.2011
Сообщения: 4
Репутация: 10
По умолчанию

Цитата:
Дык у тебя считает от 0 до 10 по обеим осям, а это 11 пикселей. 11*11 = 121, не? Вот тебе и ответ.
всмысле? Цикл построен правильно - проблема только с белым цветом. например берём рисунок абсолютно красного цвета, получаем -
Цитата:
Yellow Red Green Blue Purple Orange Black Gray White TotalPixCount
C:\Users\1\Desktop\Безымянный.bmp 0 100 0 0 0 0 0 0 0 100

Берём полностью белое изображение, получаем -

Цитата:
Yellow Red Green Blue Purple Orange Black Gray White TotalPixCount
C:\Users\1\Desktop\Безымянный.bmp 0 0 0 0 0 0 0 0 121 100
Ответить с цитированием
  #6  
Старый 29.11.2011, 01:37
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Цитата:
Сообщение от c1pg
... Цикл построен правильно ...
Уверен?
Код:
1
2
for i:=0 to img1.Picture.Width do
  for j:=0 to img1.Picture.Height do
что даст? От 0 до размеров изображения, то есть, на 1 больше.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #7  
Старый 29.11.2011, 01:45
c1pg c1pg вне форума
Прохожий
 
Регистрация: 28.11.2011
Сообщения: 4
Репутация: 10
По умолчанию

Так, да. понял ошибку. Спасибо. Непонятно только одно - почему остальные цвета, кроме белого, считало правильно?
Ответить с цитированием
  #8  
Старый 29.11.2011, 01:47
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Ну попробуй прошагай, куда уйдёт за пределы изображения.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 00:40.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025