Придётся сделать ещё одну остановку перед рассмотрением действительно интересных функций компьютерного зрения.
Рассмотрим функции OpenCV для сохранения/считывания данных в файлы.
OpenCV имеет механизмы сериализации/десериализации данных и возможность сохранять/считывать эти данные из XML-файлов.
— сохранение объекта в файл
filename — название файла
struct_ptr — указатель на объект для сохранения
name — название объекта (если NULL — будет сформировано из названия файла filename)
comment — комментарий для размещения в начале файла
attributes — атрибуты передаваемые функции cvWrite()
— считывание объекта из файла
filename — название файла
memstorage — хранилище памяти для динамических структур типа CvSeq (не используется для матриц или изображений)
name — название объекта (если NULL — самый первый объект будет загружен)
real_name — выходной параметр, который будет содержать название загруженного объекта (полезно в случае name=NULL)
функция загружает и возвращает объект из файла (обёртка вокруг cvRead()).
Простой пример использования — сохранение/загрузка данных матриц.
В приведённой программе сначала создаётся матрица, затем она сохраняется в xml-файл, а затем другая матрица загружается из этого файла.
//
// пример сохранения/загрузки
// данных из XML-файла
// и 3 способа получения элементов матрицы
//
#include <cv.h>
#include <highgui.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
// массив, содержащий данные матрицы
float kernel[9];
kernel[0]=1;
kernel[1]=0;
kernel[2]=0;
kernel[3]=0;
kernel[4]=2;
kernel[5]=0;
kernel[6]=0;
kernel[7]=0;
kernel[8]=3;
// создаём матрицу
CvMat kernel_matrix=cvMat(3,3,CV_32FC1,kernel);
// сохраняем матрицу в XML-файл
cvSave("kernel.xml", &kernel_matrix);
// а теперь загрузим данные из XML-файла
CvMat* matrix = (CvMat*)cvLoad("kernel.xml");
// покажем содержимое матрицы
//
int i=0, j=0;
// 1 вариант: с использованием макроса CV_MAT_ELEM
for(i=0; i<matrix->rows; i++){
for(j=0; j<matrix->cols; j++){
printf("%.0f ", CV_MAT_ELEM( *matrix, float, i, j));
}
printf("\n");
}
printf("-----\n");
// 2 вариант: с использованием cvGet2D(), cvGetReal2D()
for(i=0; i<matrix->rows; i++){
for(j=0; j<matrix->cols; j++){
printf("%.0f ", cvGet2D(matrix, i, j));//cvGetReal2D(matrix, i, j));
}
printf("\n");
}
printf("-----\n");
// 3 вариант: прямой доступ к элементам
for(i=0; i<matrix->rows; i++){
float* ptr = (float*)(matrix->data.ptr + i*matrix->step);
for(j=0; j<matrix->cols; j++){
printf("%.0f ", ptr[j]);
}
printf("\n");
}
// освобождаем ресурсы
cvReleaseMat(&matrix);
return 0;
}
— открытие файлового хранилища для чтения/записи данных
filename — название файла
memstorage — хранилище памяти, используемое для временных данных и для сохранения динамических структур (CvSeq). Если NULL, то создаётся временное хранилище.
flags — флаг:
#define CV_STORAGE_READ 0 // открыть для чтения
#define CV_STORAGE_WRITE 1 // открыть для записи
#define CV_STORAGE_WRITE_TEXT CV_STORAGE_WRITE
#define CV_STORAGE_WRITE_BINARY CV_STORAGE_WRITE
#define CV_STORAGE_APPEND 2
тип чтения/записи определяется расширением файла xml/yml
— записывает пользовательский объект
fs — файловое хранилище
name — название записываемого объекта (должно быть NULL, если родительская структура — последовательность)
ptr — указатель на объект
attributes — аттрибуты (свои для каждого типа)
— начало записи новой структуры
fs — указатель на файловое хранилище
name — название записываемой структуры
struct_flags — флаг:
#define CV_NODE_SEQ 5 // последовательность
#define CV_NODE_MAP 6 // карта
type_name — название типа объекта
attributes — не используется
— завершение записи структуры
fs — указатель на файловое хранилище
CVAPI(void) cvWriteInt( CvFileStorage* fs, const char* name, int value );
— запись целочисленного значения
fs — указатель на файловое хранилище
name — название записываемой величины (может быть NULL только в случае если родительская структура — последовательность)
value — записываемое значение
CVAPI(void) cvWriteReal( CvFileStorage* fs, const char* name, double value );
— запись значения c плавающей точкой (float)
fs — указатель на файловое хранилище
name — название записываемой величины (может быть NULL только в случае если родительская структура — последовательность)
value — записываемое значение
— записывает строчку
fs — указатель на файловое хранилище
name — название записываемой величины (может быть NULL только в случае если родительская структура — последовательность)
str — записываемая строчка
quote — если отлично от 0, то записываемая строчка обрамляется в кавычки
CVAPI(void) cvWriteComment( CvFileStorage* fs, const char* comment,
int eol_comment );
— записывает комментарий
fs — указатель на файловое хранилище
comment — комментарий
eol_comment — если отлично от 0, функция пытается поместить комментарий в конце текущей линии. Если 0, если комментраий многострочный или он не помещается в конце строки — он записывается с новой строчки.
— записывает числа
fs — указатель на файловое хранилище
src — указатель на массив данных для записи
len — число элементов в массиве (для записи)
dt — спецификация каждого элемента массива формата:
([count]f’u’|’c’|’w’|’s’|’i’|’f’|’d’g)…
, где буквы определяют тип данных:
u — 8-битный беззнаковый
c — 8-битный знаковый
w — 16-битный беззнаковый
s — 16-битный знаковый
i — 32-битный знаковый
f — float
d — double
r — указатель (32-битный знаковый целочисленный)
int cvReadInt( const CvFileNode* node, int default_value CV_DEFAULT(0) );
int cvReadIntByName( const CvFileStorage* fs, const CvFileNode* map,
const char* name, int default_value CV_DEFAULT(0) );
— считывает безымянное/именованное целочисленное значение
fs — указатель на файловое хранилище
map — родительская карта. Если NULL — функция считывает самое верхнее значение
name — название узла
default_value — значение по-умолчанию
— считывает безымянное/именованное значение с плавающей точкой
fs — указатель на файловое хранилище
map — родительская карта. Если NULL — функция считывает самое верхнее значение
name — название узла
default_value — значение по-умолчанию
-считываем безымянное/именованное значение строки
fs — указатель на файловое хранилище
map — родительская карта. Если NULL — функция считывает самое верхнее значение
name — название узла
default_value — значение по-умолчанию
/* starts reading data from sequence or scalar numeric node */
CVAPI(void) cvStartReadRawData( const CvFileStorage* fs, const CvFileNode* src,
CvSeqReader* reader );
/* reads multiple numbers and stores them to array */
CVAPI(void) cvReadRawDataSlice( const CvFileStorage* fs, CvSeqReader* reader,
int count, void* dst, const char* dt );
CVAPI(void) cvReadRawData( const CvFileStorage* fs, const CvFileNode* src,
void* dst, const char* dt );
— считывает числа
fs — указатель на файловое хранилище
src — файловый узел для считывания данных
dst — указатель на массив для хранения данных
dt — спецификация каждого элемента массива (аналогична cvWriteRawData())
— находит узел в файловом хранилище по имени
fs — указатель на файловое хранилище
map — родительская карта. Если NULL — функция считывает самое верхнее значение
name — имя узла
Пример создания конфигурационного xml-файла:
// Несколько модифицированный пример Example 3-17.
// демонстрирующий запись значений в xml-файл
//
// из книги:
// Learning OpenCV: Computer Vision with the OpenCV Library
// by Gary Bradski and Adrian Kaehler
// Published by O'Reilly Media, October 3, 2008
// p83
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
int main(int argc, char** argv)
{
CvMat *cmatrix = cvCreateMat(5,5,CV_32FC1);
float element_3_2 = 7.7;
*((float*)CV_MAT_ELEM_PTR( *cmatrix, 3,2) ) = element_3_2;
cvmSet(cmatrix,4,4,0.5000);
cvSetReal2D(cmatrix,3,3,0.5000);
printf("Example 3_17, writing cfg.xml\n");
// открываем файл для записи
CvFileStorage* fs = cvOpenFileStorage(
"cfg.xml",
0,
CV_STORAGE_WRITE
);
// записываем значения
cvWriteInt( fs, "frame_count", 10 );
cvStartWriteStruct( fs, "frame_size", CV_NODE_SEQ);
cvWriteInt( fs, 0, 320 );
cvWriteInt( fs, 0, 200 );
cvEndWriteStruct(fs);
cvWrite( fs, "color_cvt_matrix", cmatrix );
cvReleaseFileStorage( &fs );
return 0;
}
Комментарии (1)
RSS свернуть / развернутьТолько зарегистрированные и авторизованные пользователи могут оставлять комментарии.