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

IplImage и функция

Recommended Posts

Приветствую.

Борюсь(учусь) с MS VS2010 + openCV.

Проблема следующая: Передать получившуюся картинку IplImage из функции в основную программу (желательно без промежуточных файлов)

Как оформить функцию и основную программу?

Например:

Функция:

int SmoothTresholdFunc(_IplImage* image1, _IplImage* image2)

{

 cvSmooth(image1, image1, CV_MEDIAN,3,3,0,0);

 cvThreshold(image1,image2,0,255,CV_THRESH_BINARY|CV_THRESH_OTSU);

 return 1;

}
Основная программа:
IplImage *src, *dst = 0;

int main()

{

src = cvLoadImage( path ,CV_LOAD_IMAGE_GRAYSCALE);

SmoothTresholdFunc(src, dst);

dst=??? (что нужно сделать, чтобы в переменной dst после выполнения функции был результат - обработанная картинка?)

}

Функция и основная программа в разных .cpp файлах. Все необходимые инклюды подключил и h-файлы тоже. С другими функциями получается, но функцию с картинкой не могу победить.

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


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

IplImage *src, *dst = 0;
int main()
{
src = cvLoadImage( path ,CV_LOAD_IMAGE_GRAYSCALE);
dst=cvCreateImage(......); // надо выделить память
SmoothTresholdFunc(src, dst);
dst=??? (что нужно сделать, чтобы в переменной dst после выполнения функции был результат - обработанная картинка?)
}
[/code]

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


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

IplImage *src, *dst = 0;

int main()

{

 src = cvLoadImage( path ,CV_LOAD_IMAGE_GRAYSCALE);

 dst=cvCreateImage(cvSize(src ->width,src ->height), src ->depth, 1); // выделил память

 SmoothTresholdFunc(src, dst);


 cvSaveImage("test_crop.jpg",dst,0); //однотонное черное изображение //совсем не то

}
int SmoothTresholdFunc(_IplImage* image1, _IplImage* image2)

{

 cvSmooth(image1, image1, CV_MEDIAN,3,3,0,0);

 cvThreshold(image1,image2,0,255,CV_THRESH_BINARY|CV_THRESH_OTSU);

 cvSaveImage("test_crop2.jpg",image2,0); //хорошая картинка, которая и нужна

 return 1;

}

Выделил память но изображение почему то не передалось в основную программу

Может нужно поиграться со ссылками/указателями? но как?

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


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

Ну что то типа такого:

int SmoothTresholdFunc(_IplImage* image1,(_IplImage*)& image2)

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


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

Ну что то типа такого:

int SmoothTresholdFunc(_IplImage* image1,(_IplImage*)& image2)

Нет, так нельзя. Вообще, вариант Fresh должен работать, просто там много того, что не стоит делать.

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


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

Выделил память но изображение почему то не передалось в основную программу

Может нужно поиграться со ссылками/указателями? но как?

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

Например:


int SmoothTresholdFunc(const IplImage* image1, IplImage* image2)

{

	cvSmooth(image1, image2, CV_MEDIAN, 3, 3, 0, 0);

	cvThreshold(image2, image2, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);

	cvSaveImage("test_crop2.jpg", image2, 0);

	return 1;

}


int main()

{

	IplImage* src = cvLoadImage(path, CV_LOAD_IMAGE_GRAYSCALE);

	IplImage* dst = cvCreateImage(cvGetSize(src), src->depth, src->nChannels);

	SmoothTresholdFunc(src, dst);

	cvSaveImage("test_crop.jpg", dst, 0);

	cvReleaseImage(&dst);

	cvReleaseImage(&src);


	return 0;

}

  • Like 2

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


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

а что если так? или будет утечка?

IplImage* SmoothTresholdFunc(const IplImage* src)

{

IplImage* dst = cvCreateImage(cvGetSize(src), src->depth, src->nChannels);

        cvSmooth(src, dst, CV_MEDIAN, 3, 3, 0, 0);

        cvThreshold(dst, dst, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);

        cvSaveImage("test_crop2.jpg", dst, 0);

        return dst;

}


int main()

{

        IplImage* src = cvLoadImage(path, CV_LOAD_IMAGE_GRAYSCALE);

        cvSaveImage("test_crop.jpg", SmoothTresholdFunc(src), 0);

        cvReleaseImage(&src);


        return 0;

}

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


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

Да, так будет утечка.

Есть правило: "Кто ресурсы выделяет, то их и освобождает." Оно применяется по-разному в различных случаях, вообще говоря не обязательно, но его лучше соблюдать.

Например, в OpenCV выделяет и освобождает память под изображения opencv_corexxx.dll с помощью пары функций: cvCreateImage и cvReleaseImage. Или делает тоже самое с помощью конструктора с деструктором класса cv::Mat. Если делать какую-нибудь свою dll, то в интерфейсе надо делать функции выделения и освобождения ресурсов. Всё WinAPI также построено для бинарной совместимости (гарантировано используется один менеджер памяти).

Лучше этот принцип оставлять и на свой код. То есть не давать функции SmoothTresholdFunc выделять память и отдавать её другим. Надо либо:

1. сделать ещё функцию по очистке выделенного, что глупо;

2. подавать в неё уже созданное изображение (у меня там).

В твоём случае можно запомнить возвращаемое изображение и после для него вызвать cvReleaseImage, всё будет абсолютно корректно работать, но неочевидно чревато потенциальными ошибками.

  • Like 1

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


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

может быть флейм, лучше вместо iplImage использовать cv::Mat, все-таки этот класс упрощает работу с изображением, и во многих функциях его использовать проще( например, позволяет хранить контуры в векторах).

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


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

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

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

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

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

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

Войти

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

Войти сейчас


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

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

×