Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Очень долго строится гистограмма

27K
09 августа 2007 года
aush
4 / / 04.06.2007
Всем доброго времени суток!

Столкнулся со следующей проблемой: постоение гистограммы изображения (размеры около 3500х2500) занимает ну очень много времени - больше 40 секунд, по-моему, это много.

Строю следующим образом:

1) Ну, во-первых у меня исходное изображение jpeg, поэтому сначала перекодирую
 
Код:
Graphics::TBitmap* Bitm = new Graphics::TBitmap;
TJPEGImage* jpgmage = new TJPEGImage;
jpgmage->LoadFromFile(OpenDialog1->FileName);
Bitm->Assign(jpgmage);
imj->Picture->Graphic = Bitm;
imj->Canvas->Draw(0,0,Bitm);


2) Теперь непосредственно постоение:
 
Код:
for (j=0;j<imj->Picture->Bitmap->Height;j++)
  for (i=0;i<imj->Picture->Bitmap->Width;i++)
    {
    r=GetRValue(imj->Picture->Bitmap->Canvas->Pixels[j]);
    g=GetGValue(imj->Picture->Bitmap->Canvas->Pixels[j]);
    b=GetBValue(imj->Picture->Bitmap->Canvas->Pixels[j]);
    y=(int) (0.299*r+0.587*g+0.114*b);
    Yarr[y]++;
    }


Понятно, что есть и более очевидный подход: Сначала так jpgmage->Grayscale=true; а потом просто брать любую компоненту, НО, когда я делаю так, мне выдается весьма странный результат (ниже две картинки, соответственно при первом и втором подходе). Да и работает не сильно быстрее.

Мне почему-то кажется, что есть более быстрый способ построения гистограммы.

Заранее спасибо за помощь.

Картинка_1
Картинка_2
3.2K
10 августа 2007 года
nikipelovav
152 / / 12.04.2006
Попробуй такой код

Код:
// насколько Я знаю, TImage->Picture умеет загружать Jpeg
  imj->Picture->LoadFromFile(OpenDialog1->FileName);

  TMemoryStream* MS = new TMemoryStream();

  // загрузим образ в поток памяти, чтобы работать с ним как с char массивом
  imj->Picture->Bitmap->SaveToStream( MS );
  MS->Position = 0; // по-моему надо "на старт" сделать

  unsigned char *pixel = (unsigned char*)MS->Memory;

  BITMAPFILEHEADER bmp_hdr1;
  BITMAPINFOHEADER bmp_hdr2;

  memcpy ( &bmp_hdr1, pixel, 14); pixel +=14; // копируем заголовок BMP и смещаем указатель
  memcpy ( &bmp_hdr2, pixel, 40); pixel +=40; // копируем заголовок BMP и смещаем указатель

  // если BMP без палитры, то pixel указывает на первую точку изображения

  int pixelsize = bmp_hdr2.biBitCount / 8;
  // например для biBitCount = 24 bit /8 = 3 байта
  // например для biBitCount = 32 bit /8 = 4 байта

  // всего точек ...
  int count     = bmp_hdr2.biWidth * bmp_hdr2.biHeight;

  int y;

  // цикл по всем точкам ...
  for (int i = 0; i < count; i++)
  {
    y =(int) ( 0.299*pixel[0]+0.587*pixel[1]+0.114*pixel[2] );
    Yarr[y]++;

    pixel += pixelsize; // смещаем указатель на следующий пиксел
  }

  delete MS; // удалим поток
2.0K
11 августа 2007 года
WidowMaker
212 / / 05.04.2005
Использование прямого доступа к пикселам через Pixels самый медленный способ. Используй например ScanLine. Надеюсь ты хоть гистограмму не выводишь по пикселам?

ЗЫ: Насчет медленности алгоритма подсчета распределения, то не переживай узкое место не здесь
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог