Форум по 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 пиксель белого цвета. Уже давно мучаюсь, но не могу понять в чем проблема. С остальными цветами всё впорядке - считает довольно точно.
код ниже.

Код:
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  
Старый 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
... Цикл построен правильно ...
Уверен?
Код:
  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 в.д.
Ответить с цитированием
Ответ


Delphi Sources

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

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

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

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


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


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

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