Продолжим знакомство с OpenCV с простой загрузки картинки из файла.
Этот пример будет основой почти всех будущих программ :)
Кстати, чтобы немного развеселить изложение материала рассказ будет вестись от имени знаменитого Чеширского Кота
Думается, что его возможность исчезать будет просто незаменимой для компьютерного зрения ;)
Пррррррррррошу, уважаемый…
Итак, для самого что ни на есть Чеширского OpenCV, рассмотрим простой тестовый пример, который просто выводит картинку, имя которой передано в виде первого параметра программы (если параметров нет — будет пытаться открыть файл Image0.jpg).
Но параметр я разумеется передам и это будет самый Чеширский параметр, а именно моя фотография :)
рассмотрим новые функции, которые использовались в данном примере:
IplImage* cvLoadImage( const char* filename, int iscolor=CV_LOAD_IMAGE_COLOR );
— загружает картинку из файла.
filename — имя файла
iscolor — определяет как представить картинку
iscolor > 0 — цветная картинка с 3-мя каналами
iscolor == 0 — картинка будет загружена в формате GRAYSCALE (градации серого)
iscolor < 0 — картинка будет загружена как есть:
/* 8bit, color or not */
#define CV_LOAD_IMAGE_UNCHANGED -1
/* 8bit, gray */
#define CV_LOAD_IMAGE_GRAYSCALE 0
/* ?, color */
#define CV_LOAD_IMAGE_COLOR 1
/* any depth, ? */
#define CV_LOAD_IMAGE_ANYDEPTH 2
/* ?, any color */
#define CV_LOAD_IMAGE_ANYCOLOR 4
функция поддерживает следующие форматы изображений:
— делает полную копию изображения image, включая заголовок, данные и ROI (Region Of Interest — регион интересов — интересующая область на рисунке).
Обе функции возвращают указатель на картинку IplImage.
Картинка, в OpenCV, представлена структурой вида:
// OpenCV2.0\include\opencv\cxtypes.h
typedef struct _IplImage
{
int nSize; /* sizeof(IplImage) */
int ID; /* version (=0)*/
int nChannels; /* Most of OpenCV functions support 1,2,3 or 4 channels */
int alphaChannel; /* Ignored by OpenCV */
int depth; /* Pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16S,
IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F are supported. */
char colorModel[4]; /* Ignored by OpenCV */
char channelSeq[4]; /* ditto */
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 align; /* Alignment of image rows (4 or 8).
OpenCV ignores it and uses widthStep instead. */
int width; /* Image width in pixels. */
int height; /* Image height in pixels. */
struct _IplROI *roi; /* Image ROI. If NULL, the whole image is selected. */
struct _IplImage *maskROI; /* Must be NULL. */
void *imageId; /* " " */
struct _IplTileInfo *tileInfo; /* " " */
int imageSize; /* Image data size in bytes
(==image->height*image->widthStep
in case of interleaved data)*/
char *imageData; /* Pointer to aligned image data. */
int widthStep; /* Size of aligned image row in bytes. */
int BorderMode[4]; /* Ignored by OpenCV. */
int BorderConst[4]; /* Ditto. */
char *imageDataOrigin; /* Pointer to very origin of image data
(not necessarily aligned) -
needed for correct deallocation */
}
IplImage;
т.о. вот какую информацию мы получаем в консоли:
image->nChannels // число каналов картинки (RGB, хотя в OpenCV - BGR ) (1-4)
image->depth // глубина в битах
image->width // ширина картинки в пикселях
image->height // высота картинки в пикселях
image->imageSize // память занимаемая картинкой (==image->height*image->widthStep)
image->widthStep // расстояние между соседними по вертикали точками изображения (число байт в одной строчке картинки
- может потребоваться для самостоятельного обхода всех пикселей изображения)
У меня проблема с загрузкой файла. Почему-то не загружается картинка или видео. cvLoadImage(«pic_my.jpg», 1) возвращает FALSE. В результате получаю окно, залитое просто серым цветом, картинка не отображается. Тоже самое и с видео. Использую версию библиотеки 1.0. Win7. VS2008. В чем может быть дело?
у меня .tif-файлы открывает без проблем.
Если вы программируете в Visual Studio и запускаете программу не из директории, а прямо из-под IDE (через F5), то картинка должна лежать в директории проекта.
функция cvShowImage выдает ошибку при запуске программы F5, если filename = argc == 2? argv[1]: «d:/Program Files/fig.tif»;
видимо, cvShowImage не работает с tif
Кроме того, при задании типа TIFF* image = 0 и далее cvShowImage(«original»,image); выдает ошибку, что не может преобразовать TIFF в IplImage.
Может быть не хватает tif-библиотек или t-f.h или cpp файлов?
Работаю в Windows XP, Visual Studio 2008. Текст программы в точности повторяет Ваш, я разместил картинку qwe.tif в папке проекта. Вместо image0.jpg написал qwe.TIF.
При запуске с F5 программа прерывается и в отдельном окне написано: Необработанное исключение в «0x7c812afb» в «01_openimage.exe»: Исключение Microsoft C++: cv::Exception по адресу 0x0011fcb4…
То же самое пишет, если бы я использовал картинку Image0.jpg, но ее бы не было в папке проекта.
Пожалуйста, помогите. Очень нужно настроить OpenCV 2.1.0 на открытие и работу с .TIF
только что проделал те же шаги :)
такое исключение вываливается, если не найдена картинка.
при запуске через F5 картинка должна лежать в папке, где и проектный файл с исходниками.
Или же проверьте проще — положите картинку в директорию к exe-ку и запустите exe-файл.
Картинки sf.jpg и qwe.TIF лежат во всех возможных папках проекта. При запуске через F5 окно original отображает правильно картинку sf.jpg, а в окне tiff — серый экран (даже форма окна не подстроилась под форму картинки qwe.TIF).
Я убрал cvCloneImage для картинки qwe.TIF, поскольку с ней выдается вышеописанная ошибка с прерыванием программы.
tif-файлы загружаются функцией TIFFOpen или TIFFReadRGBAImage(), а потому объект image должен иметь класс TIFF*, который, в свою очередь, не распознается функцией cvShowImage.
Все библиотеки tiff для OpenCV имеются у меня в наличии. Вопрос: какая функция заменяет cvShowImage для объектов класса TIFF* и файлов .tif, прикрепленных к ним посредством функции TIFFOpen или TIFFReadRGBAImage()?
думаю тут два варианта — или посмотреть как это сделано в OpenCV — благо исходники открыты, либо разобраться в формате возвращаемых данных TIFF* и написать функцию-конвертер из TIFF в IplImage
Я проверил работу вышеописанной программы на двух файлах tif глубиной 1 или 8 бит (черно-белое) или (градации серого). К сожалению, cvShowImage по-прежнему показывает пустое окно.
Играясь с преобразователем форматов AbleFaxTifView, я обнаружил, что функция cvShowImage отображает файлы tiff любой глубины, если они не меньше (!) чем 790 байт. Эта граница может быть чуть ниже, я еще не нашел ее минимальное значение, но tiff-файлы размером уже 9 байт не отображаются функцией cvShowImage
посредством множества магических манипуляций, я выяснил следующее:
Картинки, сохраненные из MS Paint или виндового окна «сохранить как» под форматом TIF или TIFF никогда не будут распознаны cvShowImage. Видимо на этом этапе возникают скрытые необратимые преобразования.
Картинки, приведенные к формату TIF или TIFF из других форматов посредством универсальной программы AbleFaxTifView (доступна в Open Source) могут быть отображены через cvShowImage при любом размере файла или глубине цвета. Полагаю, что через графические редакторы или Photoshop можно вполне безболезненно сохранять картинки в формате TIFF, так что они затем могут быть обработаны cvShowImage.
Все оказалось довольно нетривиально, но со счастливым концом :). Интересно, почему не работает ситуация из пункта 1, но это предмет дальнейших исследований. А пока начальство может быть спокойно. :)
Скажите, пожалуйста. А как можно реализовать следующую ситуацию: Пользователь вводит с клавиатуры путь к картинке, то есть значение filename, а затем программа запускается. Так, чтобы вводить путь не в самой программе.
:) не вижу проблемы — всё зависит от того — что и как вы реализуете:
под консоль — просто выводите сообщение и считываете введённую строчку, под win32 — выдаёте окошко для выбора файла.
Кстати, а как это относится к OpenCV? ;)
— обратите внимание, что используется ограниченный по длине массив, по-этому может быть реализовано переполнение буфера (buffer overflow).
Кстати, Вы не находите, что этот вопрос больше относится к основам программирования C/C++?
Спасибо. Но вопрос напрямую касается именно OpenCV. Переменная filename в функции cvLoadImage должна быть типа char* (не массив []), однако я пытаюсь ввести с клавиатуры её значение вручную так:
сразу после ввода любой строки (ввожу путь к картинке), программа прерывается с ошибкой, что filename — не правильный указатель. Не понятно, функция cvLoadImage требует Массив или символ в качестве filename? Как же тогда сделать ввод строки символов с клавиатуры?
Ура, спасибо, работает! Вот только ещё стришок бы:
Если действовать Вашим путем, то приходится все картинки размещать в папке с проектом. А мне хотелось бы вводить путь типа Q:/Program Files/imgs/img1.tiff
Как только я такой ввожу, программа вылетает (без ошибки :)). Хотя такой путь я могу указать в самой программе, когда объявляю filename, и программа дальше работает, запускает cvLoadImage и всё остальное.
Спасибо за уроки. Весьма полезны.
Можете подсказать, что означают в константах задающих глубину цвета буквы U, S, F?
Точнее, пытаюсь сопоставить IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F и вот это пречисление
хм… cvCopyImage в коде нету ни разу, а cvCloneImage — просто для примера :)
чтобы было с чем сравнить :)
фактически, отличий нет — просто перед копированием (cvCopyImage) вам уже нужно создать картинку, а cvCloneImage делает это за вас.
Скажите пожалуйста, как избавиться от константности указателя filename в функции cvLoadImage(filename, 1) ??
Мне нужно передать в DLL в качестве этого самого filename строку символов, обозначающую путь к данной картинке, но это приводит к ошибке — «попытка чтения\записи в защищенную память». Нужно убрать свойство const char* filename, и заменить на char* filename. Как это сделать?
Сама функция cvLoadImage описана в файле loadsave.cpp OpenCV
1. Спасибо за лучшую русскоязычную информацию по opencv.
2. Возникла проблемма — может что подскажете.
Столкнулся с тем, что функция cvPyrMeanShiftFiltering корректно работает только в случае входного файла в цветовой гамме sRGB, если же файл в гамме Adobe RGB — функция просто оставляет входное изображение без изменений.
Какие есть варианты обхода такого поведения?
Думал о том — что-бы принудительно конвертировать RGB в sRGB, но средствами opencv или pil — не нашел как сделать.
Спасибо.
Здравствуйте, я новенькая в этой сфере… Работаю с студио2010, вот вопрос: допустим у меня есть черно-белое изображение, загрузила и выводится на консоль, все правильно работает… а как считать число белых или черных пикселей на изображение?
В принципе, можно обойти пиксели и посчитать «вручную», а если картинка действительно чёрно-белая, то можно использовать мат.-функции cvSum() или даже cvCountNonZero().
Спасибо огромное, разбиралась, все понятно стало!!! наконец, после сессии вернулась я сюда! теперь у меня другие проблемы: мне надо построить гистограмму для черно-белой изображении, какую функцию можно тут использовать, с примерами использования если есть
откуда берется картинка? пытаюсь да пытаюсь вывести на экран картинку, но выдает или исключение, или, если закомментить исключение, серый экран. как быть?
Если запускаете из-под IDE, то картинка, обычно, должна лежать в каталоге проекта. Впрочем, ничто не мешает прописать абсолютный (полный) путь к файлу картинки.
Комментарии (52)
RSS свернуть / развернутьDeVOLT
и почему старая версия? попробуйте поработать с OpenCV 2.1
noonv
При этом ShowImage отображает серый экран (только окно), но не отображает картинку.
Как заставить opencv 2.1.0 открывать и работать с .tif?
orcchg
Если вы программируете в Visual Studio и запускаете программу не из директории, а прямо из-под IDE (через F5), то картинка должна лежать в директории проекта.
noonv
видимо, cvShowImage не работает с tif
Кроме того, при задании типа TIFF* image = 0 и далее cvShowImage(«original»,image); выдает ошибку, что не может преобразовать TIFF в IplImage.
Может быть не хватает tif-библиотек или t-f.h или cpp файлов?
orcchg
если вы не в Linux-е, нужно писать:
noonv
При запуске с F5 программа прерывается и в отдельном окне написано: Необработанное исключение в «0x7c812afb» в «01_openimage.exe»: Исключение Microsoft C++: cv::Exception по адресу 0x0011fcb4…
То же самое пишет, если бы я использовал картинку Image0.jpg, но ее бы не было в папке проекта.
Пожалуйста, помогите. Очень нужно настроить OpenCV 2.1.0 на открытие и работу с .TIF
Спасибо
orcchg
такое исключение вываливается, если не найдена картинка.
при запуске через F5 картинка должна лежать в папке, где и проектный файл с исходниками.
Или же проверьте проще — положите картинку в директорию к exe-ку и запустите exe-файл.
noonv
#include <cv.h>
#include <highgui.h>
#include <stdlib.h>
#include <stdio.h>
#include <tiffio.h>
IplImage* image = 0;
IplImage* image2 = 0;
IplImage* src = 0;
IplImage* src2 = 0;
TIFF* imgtiff = 0;
int main(int argc, char* argv[])
{
// имя картинки задаётся первым параметром
char* filename = argc == 2? argv[1]: «qwe.TIF»;
char* filename2 = argc == 2? argv[1]: «sf.jpg»;
// получаем картинку
image = cvLoadImage(filename,1);
image2 =cvLoadImage(filename2,1);
// окно для отображения картинки
cvNamedWindow(«original»,CV_WINDOW_AUTOSIZE);
cvNamedWindow(«tiff»,CV_WINDOW_AUTOSIZE);
// показываем картинку
cvShowImage(«tiff»,image);
cvShowImage(«original»,image2);
// ждём нажатия клавиши
cvWaitKey(0);
// освобождаем ресурсы
cvReleaseImage(&image);
cvReleaseImage(&image2);
cvReleaseImage(&src);
// удаляем окно
cvDestroyWindow(«original»);
cvDestroyWindow(«tiff»);
return 0;
}
orcchg
Я убрал cvCloneImage для картинки qwe.TIF, поскольку с ней выдается вышеописанная ошибка с прерыванием программы.
cvShowImage почему-то не работает с моим qwe.TIF
orcchg
( https://code.ros.org/trac/opencv/ticket/116 )
только что проверил — это действительно так.
noonv
orcchg
tif-файлы загружаются функцией TIFFOpen или TIFFReadRGBAImage(), а потому объект image должен иметь класс TIFF*, который, в свою очередь, не распознается функцией cvShowImage.
Все библиотеки tiff для OpenCV имеются у меня в наличии. Вопрос: какая функция заменяет cvShowImage для объектов класса TIFF* и файлов .tif, прикрепленных к ним посредством функции TIFFOpen или TIFFReadRGBAImage()?
Спасибо.
orcchg
noonv
noonv
orcchg
Я проверил работу вышеописанной программы на двух файлах tif глубиной 1 или 8 бит (черно-белое) или (градации серого). К сожалению, cvShowImage по-прежнему показывает пустое окно.
orcchg
orcchg
noonv
Картинки, сохраненные из MS Paint или виндового окна «сохранить как» под форматом TIF или TIFF никогда не будут распознаны cvShowImage. Видимо на этом этапе возникают скрытые необратимые преобразования.
Картинки, приведенные к формату TIF или TIFF из других форматов посредством универсальной программы AbleFaxTifView (доступна в Open Source) могут быть отображены через cvShowImage при любом размере файла или глубине цвета. Полагаю, что через графические редакторы или Photoshop можно вполне безболезненно сохранять картинки в формате TIFF, так что они затем могут быть обработаны cvShowImage.
Все оказалось довольно нетривиально, но со счастливым концом :). Интересно, почему не работает ситуация из пункта 1, но это предмет дальнейших исследований. А пока начальство может быть спокойно. :)
Всем спасибо!
orcchg
orcchg
Спасибо.
orcchg
под консоль — просто выводите сообщение и считываете введённую строчку, под win32 — выдаёте окошко для выбора файла.
Кстати, а как это относится к OpenCV? ;)
noonv
char* filename=0;
printf(«Insert string: \n»);
scanf("%s",filename);
IplImage* image=0;
image=cvLoadImage(filename,1);
Не работает. Пишет, что неправильный указатель filename.
orcchg
— обратите внимание, что используется ограниченный по длине массив, по-этому может быть реализовано
Кстати, Вы не находите, что этот вопрос больше относится к основам программирования C/C++?
noonv
char* filename=(char*)calloc(256,sizeof(char));
scanf(«s%»,filename);
IplImage* image = cvLoadImage(filename,1);
сразу после ввода любой строки (ввожу путь к картинке), программа прерывается с ошибкой, что filename — не правильный указатель. Не понятно, функция cvLoadImage требует Массив или символ в качестве filename? Как же тогда сделать ввод строки символов с клавиатуры?
Спасибо.
orcchg
а раз мы всё-таки программируем на С++:
noonv
Если действовать Вашим путем, то приходится все картинки размещать в папке с проектом. А мне хотелось бы вводить путь типа Q:/Program Files/imgs/img1.tiff
Как только я такой ввожу, программа вылетает (без ошибки :)). Хотя такой путь я могу указать в самой программе, когда объявляю filename, и программа дальше работает, запускает cvLoadImage и всё остальное.
Такая проблем как-нибудь решается?
Спасибо.
orcchg
Можете подсказать, что означают в константах задающих глубину цвета буквы U, S, F?
Точнее, пытаюсь сопоставить IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F и
_KoT_
чтобы было с чем сравнить :)
фактически, отличий нет — просто перед копированием (cvCopyImage) вам уже нужно создать картинку, а cvCloneImage делает это за вас.
Спасибо! Оперативные консультации — затруднительно :)
noonv
Мне нужно передать в DLL в качестве этого самого filename строку символов, обозначающую путь к данной картинке, но это приводит к ошибке — «попытка чтения\записи в защищенную память». Нужно убрать свойство const char* filename, и заменить на char* filename. Как это сделать?
Сама функция cvLoadImage описана в файле loadsave.cpp OpenCV
Спасибо.
orcchg
1. Спасибо за лучшую русскоязычную информацию по opencv.
2. Возникла проблемма — может что подскажете.
Столкнулся с тем, что функция cvPyrMeanShiftFiltering корректно работает только в случае входного файла в цветовой гамме sRGB, если же файл в гамме Adobe RGB — функция просто оставляет входное изображение без изменений.
Какие есть варианты обхода такого поведения?
Думал о том — что-бы принудительно конвертировать RGB в sRGB, но средствами opencv или pil — не нашел как сделать.
Спасибо.
yrik
admin
vomchik
nekitozzz
noonv
То есть хранит данные цвета в байтовом представлении?? То есть когда первый пиксель изображения красный то первые три char будут 255 0 0?
MrSantiaga
noonv
MrSantiaga
noonv
допустим у меня есть bmp изображение в 1 пиксель (0, 255, 0), т.е.
Но на выходе получаю все тот же зеленый пиксель
MrSantiaga
MrSantiaga
Erkenaz
noonv
Erkenaz
Вопросы, напрямую не относящиеся к статьям, лучше задавать на
noonv
setra2014
admin
setra2014
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.