Трансформации и перестановки
Материал из CompVision
Содержание |
Reshape
Изменяет конфигурацию (форму) матрицы, без копирования данных
CvMat* cvReshape( const CvArr* arr, CvMat* header, int new_cn, int new_rows=0 );
arr - заголовок входной матрицы
header - сюда будет помещен результат
new_cn - новое количество каналов (0 - означает что количество не меняется)
new_rows - новое количество строк (0 - означает что количество не меняется, если к этому не ведет изменение new_cn)
Функция cvReshape инициализирует заголовок CvMat так что он указывает на те же данные что и заголовок входной матрицы, но задает матрице другую форму.Другое количество строк, другое количество каналов, или и то и другое. Например, следующий код создает один буфер изображения, и два заголовка, один описывает это изображение как изображение 320х240х3, а второй как изображение 960х240х1.
IplImage* color_img = cvCreateImage( cvSize(320,240), IPL_DEPTH_8U, 3 ); CvMat gray_mat_hdr; IplImage gray_img_hdr, *gray_img; cvReshape( color_img, &gray_mat_hdr, 1 ); gray_img = cvGetImage( &gray_mat_hdr, &gray_img_hdr );
Следующий пример преобразует матрицу 3х3 в вектор 1х9.
CvMat* mat = cvCreateMat( 3, 3, CV_32F ); CvMat row_header, *row; row = cvReshape( mat, &row_header, 0, 1 );
ReshapeMatND
Изменяет форму многомерного массива без копирования данных
CvArr* cvReshapeMatND( const CvArr* arr, int sizeof_header, CvArr* header, int new_cn, int new_dims, int* new_sizes ); #define cvReshapeND( arr, header, new_cn, new_dims, new_sizes ) \ cvReshapeMatND( (arr), sizeof(*(header)), (header), \ (new_cn), (new_dims), (new_sizes))
arr - заголовок входной матрицы
sizeof_header - для различения заголовков IplImage, CvMat и CvMatND.
header - сюда будет помещен результат
new_cn - новое количество каналов (0 - означает что количество не меняется)
new_dims - новое количество измерений (0 - означает что количество не меняется)
new_sizes - массив новых размеров измерений. Используется только new_dims-1 измерений, так как одно измерение необходимо для обеспечения постоянного количества данных. Таким образом если new_dims=1, new_sizes не используется.
cvReshapeMatND - продвинутая версия cvReshape которая так-же может работать с многомерными матрицами (также с изображениями и обычными 1D и 2D матрицами) плюс изменять количество измерений матрицы. Ниже два примера переписанные из описаия cvReshape с использованием cvReshapeMatND.
IplImage* color_img = cvCreateImage( cvSize(320,240), IPL_DEPTH_8U, 3 ); IplImage gray_img_hdr, *gray_img; gray_img = (IplImage*)cvReshapeND( color_img, &gray_img_hdr, 1, 0, 0 ); ... /* переводим матрицу 2x2x2 в вектор 8x1 */ int size[] = { 2, 2, 2 }; CvMatND* mat = cvCreateMatND( 3, size, CV_32F ); CvMat row_header, *row; row = cvReshapeND( mat, &row_header, 0, 1, 0 );
Repeat
Заполняет матрицу "плиткой" состоящей из элементов другой матрицы
void cvRepeat( const CvArr* src, CvArr* dst );
src - источник изображение или матрица (плитка которой заполняют).
dst - приемник изображение или матрица которую заполняют.
cvRepeat - заполняет матрицу "плиткой" состоящей из элементов другой матрицы
dst(i,j)=src(i mod rows(src), j mod cols(src))
Приемник может быть как больше так и меньше источника.
Flip
Переворачивает двумерную матрицу (изображение) относительно вертикальной, горизонтальной или обоих осей
void cvFlip( const CvArr* src, CvArr* dst=NULL, int flip_mode=0); #define cvMirror cvFlip
src - источник изображение или 2D матрица.
dst - приемник изображение или 2D матрица. Если dst=NULL результат помещается в src.
flip_mode - определяет как перевернуть матрицу (изображение)
flip_mode = 0 - переворот отностиельно оси x
flip_mode > 0 - переворот отностиельно оси y
flip_mode < 0 - переворот отностиельно оси x и y
то-же в коде:
dst(i,j)=src(rows(src)-i-1,j) if flip_mode = 0 dst(i,j)=src(i,cols(src1)-j-1) if flip_mode > 0 dst(i,j)=src(rows(src)-i-1,cols(src)-j-1) if flip_mode < 0
Основные случаи применения функции это:
Вертикальный переворот: используется для переключения между верхним-левым и нижним-левым началом координат.(Типичная операция для программирования под Windows)
Горизонтальный переворот с последующим горизонтальным сдвигом и вычислением разницы используется для определения вертикальной симметрии. Вертикальный и горизонтальный переворот с последующим сдвигом и вычислением разницы используется для проверки центральной симметрии.
Реверс порядка следования элементов в 1D -матрице.
Split
Разделяет многоканальную матрицу на несколько одноканальных, или извлекает один канал из массива.
void cvSplit( const CvArr* src, CvArr* dst0, CvArr* dst1, CvArr* dst2, CvArr* dst3 ); #define cvCvtPixToPlane cvSplit
src - исходная матрица.
dst0..dst3 - выходные матрицы, куда помещаются каналы. Функция cvSplit разделяет многоканальную матрицу на несколько одноканальных, или извлекает один канал из массива. Доступно два режима работы функции. Если исходная матрица имеет N каналов и первые N выходных матриц не равны NULL, то все каналы раскладываются по выходным массивам. Иначе, если только одна из выходных матриц не равна NULL, то извлекается канал, соответствующий номеру этой матрицы. Оставшиеся каналы (за первыми N) всегда должны быть равны NULL. В случае IplImage, для извлечения канальных данных может использоваться cvCopy с установленным COI (каналом интереса).
Merge
Комбинирует многоканальную матрицу из нескольких одноканальных
void cvMerge( const CvArr* src0, const CvArr* src1, const CvArr* src2, const CvArr* src3, CvArr* dst ); #define cvCvtPlaneToPix cvMerge
src0..src3 - входные матрицы
dst - выходной массив
Функция cvMerge - является противоположностью cvSplit, и служит для объединения одноканальных матриц в многоканальные. Если выходная матрица имеет N каналов тогда первые N входных матриц копируются в соответствующие каналы выходной матрицы, иначе только единственная входная матрица, которая не NULL, копируется в соответствующий канал выходной матрицы. Оставшиеся входные матрицы (за первыми N) всегда должны быть равны NULL. В случае IplImage, для изменения (вставки новых) канальных данных может использоваться cvCopy с установленным COI (каналом интереса).
MixChannels
Копирует несколько каналов источника в заданные каналы приемника, какие куда копировать, задается в параметрах ыункции. Параметры:
void cvMixChannels(const CvArr** src, int src_count, CvArr** dst, int dst_count, const int* from_to, int pair_count)
* src – Исходная матрица * src_count – количество входных матриц. * dst – Результирующая матрица * dst_count – Количество результирующих матриц. * from_to – Массив пар индексов копируемых плоскостей (каналов). from_to[k*2] индексы каналов исходной матрицы, а from_to[k*2+1] индексы канлаов результирующей матрицы (куда копируется соответствующий канал исходной матрицы). Здесь используется сквозная нумерация, начиная с 0 , следовательно, каналы первой входной матрицы нумеруются начиная с 0 до channels(src[0])-1, второй матрицы имеют номера от channels(src[0]) до (src[0]) + channels(src[1])-1 и т.д., та же схема используется для нумерации каналов результирующей матрицы. В особом случае, когда from_to[k*2] имеет отрицательное значение, соответствующие каналы результирующей матрицы заполняются нулями.
Эта функция является обобщением функций cvSplit() и cvMerge() а также некоторых форм функции cvCvtColor(). Она может применяться для изменения порядка следования плоскостей изображения, добавления/удаления альфа-канала, извлечения или вставки отдельных плоскостей (каналов) и т.д.
Код примера преобразует 4-четырехканальное RGBA изображение в 3-канальное BGR (т.е. R и B поменяли местами) отделяет альфа-канал:
CvMat* rgba = cvCreateMat( 100, 100, CV_8UC4 ); CvMat* bgr = cvCreateMat( rgba->rows, rgba->cols, CV_8UC3 ); CvMat* alpha = cvCreateMat( rgba->rows, rgba->cols, CV_8UC1 ); cvSet( rgba, cvScalar(1,2,3,4) ); CvArr* out[] = { bgr, alpha }; int from_to[] = { 0,2, 1,1, 2,0, 3,3 }; cvMixChannels( &bgra, 1, out, 2, from_to, 4 );