Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Работа с изображением VC6 (C++), варианты...  (Прочитано 12028 раз)
0 Пользователей и 1 Гость смотрят эту тему.
SirT
Новенький

ru
Offline Offline

« : 08-05-2010 20:13 » 

Здраствуйте.

Есть некое изображение с USB камеры, которое обрабатывается с помощью Bitmap.
На относительно темной поверхности есть некое пятно света. Программа проводит фильтрацию,
делая то что относится к пятну былыми пикселями, остальное - черными. затем определяется геометрический
центр этого пятна.

Собственно первая версия программы у меня есть, она реализована через COLORREF.
В цикле первоначальной фильтрации у меня следующее:

COLORREF pixel_color = dc.GetPixel( i, j );

char r = GetRValue (pixel_color);
char g = GetGValue (pixel_color);
char b = GetBValue (pixel_color);

if (r >> 250 && g >> 250 && b >> 250) dc.SetPixel( i, j, RGB( 255, 255, 255 )),
else dc.SetPixel( i, j, RGB( 0, 0, 0 ) )


Впринципе работает. НО!
COLORREF pixel_color = dc.GetPixel( i, j ) отрабатывает очень медленно. Обработка всего изображения занимает
10-20 секунд, что для данного проекта недопустимо.

Поэтому вопрос у меня такой: есть ли какие-нибудь альтернативные варианты реализации данной части программы
чтобы это ускорило процесс?

Возможно, можно как-то обращатсья непосредсвенно к ячейке памяти, где храниться информация о конкретном пикселе,
чтобы это было быстрее? Если да, то как именно? в каком виде хранится эта информация и как к ней обращаться?
Был бы рад наглядным примерам.

заранее всем спасибо!
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 08-05-2010 20:48 » 

Цитата
r >> 250

SirT, а что это должно было значить?

Кстати, зачем функции? Не проще ли получить указатель на буфер битмапа и перебирать пиксели последовательно?
« Последнее редактирование: 08-05-2010 20:54 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 08-05-2010 22:01 » 

SirT, конечно возможно. Нужно из заголовка Bitmap получить указатель на кусок памяти с пикселями, и дальше по интересующим тебя координатам считать смещения. Но для этого тебе помимо всего прочего нужно знать размер пикселя в битах, размер картинки в пикселях и размер строчки картинки в байтах (последнее потому, что строчки имеют выравнивание, т.е. в конце могут иметь небольшие остатки неиспользуемых байтов) - это всё извлекается из заголовка Bitmap. На современной настольной машине этим методом можно получить десятки обработанных картинок в секунду, если картинки имеют разрешение около мегапикселя, а обработка имеет низкую сложность типа твоего бинарного квантования.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
SirT
Новенький

ru
Offline Offline

« Ответ #3 : 09-05-2010 04:35 » 

Цитата
SirT, а что это должно было значить?

Ну вот таким хитрым способом я пытался выделить светлые участки картинки.
Число получено экперементально....

Цитата
Кстати, зачем функции? Не проще ли получить указатель на буфер битмапа и перебирать пиксели последовательно?

SirT, конечно возможно. Нужно из заголовка Bitmap получить указатель на кусок памяти с пикселями, и дальше по интересующим тебя координатам считать смещения. Но для этого тебе помимо всего прочего нужно знать размер пикселя в битах, размер картинки в пикселях и размер строчки картинки в байтах (последнее потому, что строчки имеют выравнивание, т.е. в конце могут иметь небольшие остатки неиспользуемых байтов) - это всё извлекается из заголовка Bitmap. На современной настольной машине этим методом можно получить десятки обработанных картинок в секунду, если картинки имеют разрешение около мегапикселя, а обработка имеет низкую сложность типа твоего бинарного квантования.

Ну собственно видимо это мне и нужно. Попробую с этим разобраться...

Буду очень рад подробностям, наглядным примерам и полезным ссылочкам, где можно подробнее про все это прочитать,
потому что на данный момент у меня знаний очень мало по этому вопросу. Поледний раз я я делал простенькие программки на VC
лет 5ть тому назад, а с изображением вообще никогда не работал((
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #4 : 09-05-2010 05:21 » 

SirT, а что это должно было значить?

Ну вот таким хитрым способом я пытался выделить светлые участки картинки.
Число получено экперементально....

Сдается мне, что ты не знаешь языка.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
SirT
Новенький

ru
Offline Offline

« Ответ #5 : 09-05-2010 07:14 » 

RXL, можно сказать и так. Приходитсья разбираться на примерах, читать статьи, учебники.
Поэтому глупости не исключены...

А что именно здесь не так?
Записан
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 09-05-2010 08:16 » 

Не так, чтобы не так. Просто это мифом работает Улыбаюсь Если бы ты использовал тип BYTE (он же unsigned char), который возвращают функции GetXValue - то ничего бы не работало Улыбаюсь

>> - это операция побитового сдвига вправо. Сдвиг на 250 бит - это нонсенс, у типа char разрядность всего 8 бит.
Но char - тип знаковый, поэтому когда ты помещаешь туда значения 128-255, они воспринимаются как отрицательные. А отрицательные числа при сдвиге на 8 и более бит всегда дают -1 (0xFF). Тогда как неотрицательные дают 0. Поэтому по факту твой алгоритм будет всегда разделять числа на две части: до 127 и больше 127.  Число 250 с тем же успехом можно заменить на 8.
« Последнее редактирование: 09-05-2010 08:21 от Вад » Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 09-05-2010 08:21 » 

SirT, мне не совсем понятно, откуда у тебя взялся dc (контекст устройства). Более интересно посмотреть на то, в каком виде картинка приходит из камеры - это BITMAP или что-то другое?
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
SirT
Новенький

ru
Offline Offline

« Ответ #8 : 09-05-2010 09:40 » 

Вад, да, совсем напутал. Спутал операцию сравнения со сдвигом. Что самое интересное - при этом программа работала практически как надо, лажа вылезла, когда попробовал различные варианты освещения. А до этого у меня посути бы темный стол со светлой точкой от лазерной указки. При такой контрастности прога отрабатывала и я даже подумать немог что где-то налажал.

Но тогда вопрос такой: если имеется пиксель RGB цвета скажем 145 167 220 и char r = GetRValue (pixel_color), тогда r rкакое принимает значение?  145? Или я туплю....

Прошу меня простить за глупые вопросы, но я можно считать новичек в этом деле. Но мне поручено серьезное задание и я честно пытаюсь во всем разобраться.

Dimka, картинка из камеры приобразуется в BITMAP, далее уже идет работа с ним. Вот код, который предшествует циклу фильтрации:
Цитата

CPaintDC dc(GetDlgItem(IDC_STATIC_FRAME2));

   m_bmp.GetBitmap(&bm);

   dcMem.DeleteDC();
   dcMem.CreateCompatibleDC(&dc);
   dcMem.SelectObject(&m_bmp);

   dc.StretchBlt(0, 0, m2_rectFrame.Width() - 10, m2_rectFrame.Height() - 10,
      &dcMem, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);


Записан
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 09-05-2010 15:26 » new

Но тогда вопрос такой: если имеется пиксель RGB цвета скажем 145 167 220 и char r = GetRValue (pixel_color), тогда r rкакое принимает значение?  145? Или я туплю....
-111. А вообще, в таких случаях лучше попробовать и самостоятельно убедиться, что будет Ага
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines