Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > C++ Builder
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 26.08.2010, 03:18   #1
JDredd
Пользователь
 
Регистрация: 07.08.2010
Сообщений: 13
Радость Быстрый парсинг картинки

У меня есть картинка в Graphics::TBitmap - надо найти хотя бы один пиксель заданного цвета

Код работает слишком медленно. Как ускорить ?

Код:
bool TImgParser::check( int x, int y, int color )
{
	return ( img->Canvas->Pixels[x][y] == color );
}
.....

	for (int i = xMin; i < xMax; i++)
		for (int j = yMin; j < yMax; j++)
			if ( check( i, j, 0xF25D3A ) ) {
				flag = true;
				pt = TPoint(i,j);
			}
JDredd вне форума Ответить с цитированием
Старый 26.08.2010, 03:43   #2
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

ScanLine юзаем
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 27.08.2010, 00:08   #3
JDredd
Пользователь
 
Регистрация: 07.08.2010
Сообщений: 13
По умолчанию

провел замеры времени - скан лайн тормозит
Код:
// дефайны для замера времени
#define sbros() time = GetTickCount();
#define zamer() userIO->log( IntToStr((int)(GetTickCount()-time)) );
..........
	int color,prevcolor;
	int time ;
	Byte *ptr;
	userIO->log("start");

	sbros();

	ptr = (Byte *) img->ScanLine[42];

	zamer();
	sbros();

	for (int y = 50; y < 526; y++)
		ptr = (Byte *) img->ScanLine[y];

	zamer();
	sbros();

	for (int y = 50; y < 526; y++)
		for (int x = 36; x < 825; x++)
		{
			prevcolor=color;
			color = img->Canvas->Pixels[x][y];
		}

    zamer();
результат выполнения
Цитата:
start
31
16875
1922
т.е
вызов сканлайна - 31мс
макет парсинга со сканлайн - 16.8 сек == 35мс на итерацию
парсинг через пиксели - 1.9 сек
JDredd вне форума Ответить с цитированием
Старый 27.08.2010, 10:10   #4
evgn
Разрабатываюсь....
Пользователь
 
Регистрация: 16.11.2008
Сообщений: 68
По умолчанию

Не может такого быть, чтобы доступ через указатель был медленнее доступа через методы класса. И у TImage нет свойства ScanLine.
Вот
Код:
// дефайны для замера времени
#define sbros() time = GetTickCount();
#define zamer() Memo1->Lines->Add( IntToStr((int)(GetTickCount()-time)) );

	int color,prevcolor;
	int time ;
	int *ptr;
	sbros();
	ptr = (int *) img->Picture->Bitmap->ScanLine[42];
	zamer();
	sbros();
	for (int y = 50; y < 526; y++){
		ptr =  (int *)img->Picture->Bitmap->ScanLine[y];
		for (int x = 36; x < 825; x++){
			prevcolor=color;
			color = ptr[x];
		}
	}
	zamer();
	sbros();
	for (int y = 50; y < 526; y++)
		for (int x = 36; x < 825; x++)
		{
			prevcolor=color;
			color = img->Canvas->Pixels[x][y];
		}
	zamer();
И результаты:
Цитата:
15
2485
15578
Как и следовало ожидать доступ к пикселям через ScanLine и указатель почти в 6,5 раз быстрее.
evgn вне форума Ответить с цитированием
Старый 28.08.2010, 17:56   #5
JDredd
Пользователь
 
Регистрация: 07.08.2010
Сообщений: 13
По умолчанию

1)
Цитата:
Не может такого быть, чтобы доступ через указатель был медленнее доступа через методы класса.
Может, т.к. указатель надо еще получить
Код:
	__property void * ScanLine[int Row] = {read=GetScanline};
2)
Цитата:
у TImage нет свойства ScanLine.
Согласен, но я не использую TImage
Цитата:
картинка в Graphics::TBitmap
Код:
void TImgParser::parse( Graphics::TBitmap *image )
3)
Скомпилировал Ваш код в Embarcadero® C++Builder® 2010 Version 14.0.3513.24210
Цитата:
Memo1
15
5282
1390
т.е. результат наоборот - пиксели быстрее
4)
Мне надо распознать много картинок, потому можно вынести ScanLine в предподсчет, а в самом парсинге работать только с указателями.
Проблема решена.

Большое спасибо
JDredd вне форума Ответить с цитированием
Старый 01.09.2010, 17:55   #6
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

на будущее, вызвали ScanLine и обрабатывайте всю строку через указатель, а не по тысяче раз вызывать.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 09.02.2011, 12:27   #7
ImmortalAlexSan
Участник клуба
 
Аватар для ImmortalAlexSan
 
Регистрация: 13.01.2009
Сообщений: 1,353
По умолчанию

Сам начал С++ учить, работаю с указателями сейчас. Сделал вот так:
Код:
void paint_wireless(Graphics::TBitmap *changeble_bmp, TMemo *memo)
{
	int i,j;
	void *colors;
	unsigned long time;
	changeble_bmp->PixelFormat=pf24bit;
	time=GetTickCount();
	for (i = 0; i < changeble_bmp->Height; i++)
	{
		colors=(unsigned char*)changeble_bmp->ScanLine[i];
		for (j = 0; j < changeble_bmp->Width; j++)
		{
			*((unsigned char*)colors)=0;
			colors=(unsigned char*)colors+1;
			*((unsigned char*)colors)=0;
			colors=(unsigned char*)colors+1;
			*((unsigned char*)colors)=0;
			if (j<changeble_bmp->Width)
				((char*)colors)++;
		}
	}
	memo->Lines->Add(IntToStr((int)(GetTickCount()-time)));
}
Битмап 1024Х768 результаты замера меня просто поразили!!!
Цитата:
16
Да, и если можно укажите мои недочеты пожалуйста.
"Тебе то может на меня и насрать, но твои глаза меня обожают!"
ImmortalAlexSan вне форума Ответить с цитированием
Старый 09.02.2011, 12:52   #8
Obey-Kun
Линуксоид
Участник клуба
 
Аватар для Obey-Kun
 
Регистрация: 31.07.2009
Сообщений: 1,403
По умолчанию

Из недочётов хотелось бы отметить непонятно зачем использованный void-указатель и приведение типов в стиле C. А также отсутствие комментариев.
Также, разве должно быть не void paint_wireless(const Graphics::TBitmap *changeble_bmp, TMemo *memo)?
Я схожу с ума или это глючит реальность?
Jabber ID: obey@obey.su

Последний раз редактировалось Obey-Kun; 09.02.2011 в 12:59.
Obey-Kun вне форума Ответить с цитированием
Старый 09.02.2011, 20:54   #9
ImmortalAlexSan
Участник клуба
 
Аватар для ImmortalAlexSan
 
Регистрация: 13.01.2009
Сообщений: 1,353
По умолчанию

Obey-Kun, использовал нетипизированный указатель потому, что скан лайн возвращает такой же (сейчас попробую просто unsigned char), объяни пожалуйста почему:
Код:
...const Graphics::...
аааа, вкурил, конст для того чтобы битмап не менять первоначальный? Мне надо менять его, по этому и не конст. А как лучше по-твоему сделать?
P.S. Исправил, куда понятнее стал код, а время не изменилось.
"Тебе то может на меня и насрать, но твои глаза меня обожают!"

Последний раз редактировалось ImmortalAlexSan; 09.02.2011 в 21:03.
ImmortalAlexSan вне форума Ответить с цитированием
Старый 09.02.2011, 21:01   #10
Obey-Kun
Линуксоид
Участник клуба
 
Аватар для Obey-Kun
 
Регистрация: 31.07.2009
Сообщений: 1,403
По умолчанию

Цитата:
аааа, вкурил, конст для того чтобы битмап не менять первоначальный? Мне надо менять его, по этому и не конст. А как лучше по-твоему сделать?
Ok, тогда не const. Я-то думал, ты просто считываешь. А что ты там меняешь? Ты же хочешь найти координаты пиксела заданного цвета?

Цитата:
Obey-Kun, использовал нетипизированный указатель потому, что скан лайн возвращает такой же (сейчас попробую просто unsigned char), объяни пожалуйста почему:
Ну указатель используй того типа, к которому можно привести этот указатель (кстати, а нахрена эти индусы из MS сделали так, что эта функция возвращает void*?). Ну и, опять же, static_cast делай, так лучше.
Я схожу с ума или это глючит реальность?
Jabber ID: obey@obey.su
Obey-Kun вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Отображение картинки на кнопке WPF. Загрузка картинки из ресурсов. Проблема с Uri. Casper-SC Общие вопросы .NET 0 27.06.2010 23:11
Быстрый запуск. Chudo4258 Помощь студентам 4 09.04.2010 20:30
Быстрый перевод сайта ! Slappy Помощь студентам 0 24.01.2010 16:09
Размер Image изменяется на размер картинки, а сама она рисуется на области первой картинки RPGer Мультимедиа в Delphi 6 20.10.2008 19:54
Быстрый поиск по индексу valerij Microsoft Office Excel 1 21.04.2008 11:04