Перейти к содержимому
Compvision.ru
mrgloom

boost thread and opencv

Recommended Posts

как передавать src кусками, а потом склеить?

можно как то на разных системах определять оптимальное кол-во потоков?

какой функцией лучше пользоваться для замера времени?

типа такого

void test_boost(IplImage* src,int N)

{

boost::thread_group tg;

const std::size_t thcount = N;

for ( std::size_t idx = 0; idx < thcount; ++idx )

{

tg.create_thread(boost::bind(&expand, src, 10,10));// вместо src должен быть кусок src

}

tg.join_all();

}

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

как передавать src кусками, а потом склеить?

А зачем лишние копирования памяти? Пусть каждый дочерний поток полностью копирует заголовок изображения и делает ему SetImageROI

можно как то на разных системах определять оптимальное кол-во потоков?

size_t num_threads = boost::thread::hardware_concurrency();

какой функцией лучше пользоваться для замера времени?

В общем случае: clock()

Если можно использовать WinAPI, то число вариантов возрастает. Например: QueryPerfomanceCounter или GetThreadTimes.

  • Like 2

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
А зачем лишние копирования памяти? Пусть каждый дочерний поток полностью копирует заголовок изображения и делает ему SetImageROI

а заголовком можно оперировать как то целиком? не очень понял, что значит его скопировать, ибо в ф-ию передается IplImage* и вроде бы заголовок однозначно привязан к данным.

или имеется ввиду, что можно для каждого треда делать setROI?

еще попробовал с разделением на части, и столкнулся с проблемой, как потом соединять куски?

т.е. проблема такая же как и с границами изображения по сути.

хотя тут наверно можно брать с заведомым перекрытием и потом при наложении перекрытия удалять.

наверно не для всех встроенных алгоритмов подойдет такой подход.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

IplImage* src указывает на структуру. Если ты сделаешь cvSetImageROI в одном потоке, то это изменение применится одновременно ко всем потокам, так как структура одна. Поэтому было бы логично сделать копию IplImage (не указателя, а скопировать всё содержимое структуры) и с ней работать. Так как сам буфер изображения не является частью IplImage, то он будет общий на все потоки, что и требуется.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
IPL image:

IplImage

|-- int nChannels; // Number of color channels (1,2,3,4)

|-- int depth; // Pixel depth in bits:

| // IPL_DEPTH_8U, IPL_DEPTH_8S,

| // IPL_DEPTH_16U,IPL_DEPTH_16S,

| // IPL_DEPTH_32S,IPL_DEPTH_32F,

| // IPL_DEPTH_64F

|-- int width; // image width in pixels

|-- int height; // image height in pixels

|-- char* imageData; // pointer to aligned image data

| // Note that color images are stored in BGR order

|-- int dataOrder; // 0 - interleaved color channels,

| // 1 - separate color channels

| // cvCreateImage can only create interleaved images

|-- int origin; // 0 - top-left origin,

| // 1 - bottom-left origin (Windows bitmaps style)

|-- int widthStep; // size of aligned image row in bytes

|-- int imageSize; // image data size in bytes = height*widthStep

|-- struct _IplROI *roi;// image ROI. when not NULL specifies image

| // region to be processed.

|-- char *imageDataOrigin; // pointer to the unaligned origin of image data

| // (needed for correct image deallocation)

|

|-- int align; // Alignment of image rows: 4 or 8 byte alignment

| // OpenCV ignores this and uses widthStep instead

|-- char colorModel[4]; // Color model - ignored by OpenCV

ну как я понял мы копируем все кроме char* imageData; самой "начинки" изображения?

допустим есть some_func(IplImage* src) принимает на вход IplImage*.

тогда

IplImage* new_src=cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, src->nChannels);

new_src->imageData=src->imageData;

и потом setROI.

или не достаточно cvCreateImage такого же размера, а надо все поля структуры перекопировать?

вообще я хотел бы для встроенных функций opencv написать сверху надстройку на boost thread.

чтобы можно было вызывать как то в виде DO_IN_PARALLEL(cvCanny,par1,par2);

т.е. чтобы внутрь не лезть и не переписывать руками сами функции, а просто распараллелить по данным.

хотя вот для warpAffine() например не получится так тупо сделать, надо будет наверно спуститься до remap().

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
IplImage tmp_src;

memcpy(&tmp_src, src, sizeof(IplImage));

IplImage src_ = &tmp_src;

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

я подумал, что может сделать все проще, просто загружать свое ядро своей задачей.(т.е. когда картинок много, каждому ядру своя картинка)

в бусте есть функция позволяющая определить незанятые ядра?

или определить загрузку ядра(как в таск мэнеджере)?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

я подумал, что может сделать все проще, просто загружать свое ядро своей задачей.(т.е. когда картинок много, каждому ядру своя картинка)

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

в бусте есть функция позволяющая определить незанятые ядра?

или определить загрузку ядра(как в таск мэнеджере)?

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

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте учётную запись или войдите для комментирования

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

Создать учётную запись

Зарегистрируйтесь для создания учётной записи. Это просто!

Зарегистрировать учётную запись

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу

×