Карта посещений

Счетчики

Реклама Google

 

Дискретные преобразования

Материал из CompVision

Перейти к: навигация, поиск

cvDCT

Производит прямое или обратное дискретное косинусное преобразование над одномерным или двумерным массивом чисел с плавающей точкой.

Используемые константы:

#define CV_DXT_FORWARD  0
#define CV_DXT_INVERSE  1
#define CV_DXT_ROWS     4

Определение функции:

void cvDCT(const CvArr* src, CvArr* dst, int flags);

Параметры:

  • src – исходный массив, одномерный или двумерный массив чисел с плавающей точкой.
  • dst – результирующий массив, того-же типа и размера что и входной.
  • flags – Флаги преобразования, могут быть комбинациями приведенных ниже значений:
 o CV_DXT_FORWARD - производить прямое преобразование.
 o CV_DXT_INVERSE - производить обратное преобразование.
 o CV_DXT_ROWS - производить прямое или обратное преобразование каждой отдельной строки входного массива. Этот флаг позволяет выполнить преобразование для группы векторов одновременно, что позволяет существенно улучшить производительность операции, производить преобразования над векторами, количество измерений которых больше двух и т.д.

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

LaTeX: Y={{C}^{(N)}}\cdot X

где

LaTeX: C_{jk}^{(N)}=\sqrt{\frac{{{\alpha }_{j}}}{N}}\cdot \cos \left( \frac{\pi \cdot (2\cdot k+1)\cdot j}{2\cdot N} \right)

и

LaTeX: \begin{align}
</p>
<pre> & {{\alpha }_{j}}=1 \\ 
</pre>
<p>\end{align} для LaTeX: \begin{align}
</p>
<pre>& j=0 \\ 
</pre>
<p>\end{align}


LaTeX: \begin{align}
</p>
<pre> & {{\alpha }_{j}}=2 \\ 
</pre>
<p>\end{align} для LaTeX: \begin{align}
</p>
<pre>& j>0 \\ 
</pre>
<p>\end{align}

Обратное косинусное преобразование массива одномерных векторов (обычного массива значений с плавающей точкой):

Так как LaTeX: {{C}^{(N)}} ортогональная матрица, то справедливо выражение:

LaTeX: {{C}^{(N)}}\cdot {{\left( {{C}^{(N)}} \right)}^{T}}=I

отюда следует что:

LaTeX: X={{({{C}^{(N)}})}^{-1}}\cdot Y={{({{C}^{(N)}})}^{T}}\cdot Y

Прямое преобразование для двумерной матрицы MxN:

LaTeX: Y={{C}^{(N)}}\cdot X\cdot {{\left( {{C}^{(N)}} \right)}^{T}}

Обратное преобразование для двумерной матрицы MxN:

LaTeX: X={{\left( {{C}^{(N)}} \right)}^{T}}\cdot Y\cdot {{C}^{(N)}}

cvDFT

Производит прямое или обратное дискретное преобразование Фурье над одномерным или двумерным массивом чисел с плавающей точкой.

Используемые константы:

#define CV_DXT_FORWARD  0
#define CV_DXT_INVERSE  1
#define CV_DXT_SCALE    2
#define CV_DXT_ROWS     4
#define CV_DXT_INV_SCALE (CV_DXT_SCALE|CV_DXT_INVERSE)
#define CV_DXT_INVERSE_SCALE CV_DXT_INV_SCALE

Определение функции:

void cvDFT(const CvArr* src, CvArr* dst, int flags, int nonzeroRows=0)

Параметры:

  • src – исходный массив, одномерный или двумерный массив чисел с плавающей точкой.
  • dst – результирующий массив, того-же типа и размера что и входной.
  • flags – Флаги преобразования, могут быть комбинациями приведенных ниже значений:
o CV_DXT_FORWARD - произвести прямое одномерное или двумерное преобразование. Результат не масштабируется.
o CV_DXT_INVERSE - произвести обратное одномерное или двумерное преобразование. Результат не масштабируется. CV_DXT_FORWARD и CV_DXT_INVERSE не должны быть установлены одновременно.
o CV_DXT_SCALE - масштабировать результат: делит результат на количество элементов. Обычно используется в комбинации с CV_DXT_INVERSE, в таком случае можно использовать просто CV_DXT_INV_SCALE (см. определения выше).
o CV_DXT_ROWS - производить прямое или обратное преобразование каждой отдельной строки входного массива. Этот флаг позволяет выполнить преобразование для группы векторов одновременно, что позволяет существенно улучшить производительность операции, производить преобразования над векторами, количество измерений которых больше двух и т.д.
  • nonzeroRows – количество ненулевых строк в исходном массиве (в случае прямого двумерного преобразования), или количество строк интереса в результирующем массиве (в случае обратного двумерного преобразования). Если значение отрицательное, нулевое, или больше общего количества строк, оно игнорируется. Параметр может использоваться для увеличения производительности операций двумерной свертки/корреляции(convolution/correlation) при вычислении через DFT.

Смотри пример ниже.

CvMat* A = cvCreateMat(M1, N1, CVg32F);
CvMat* B = cvCreateMat(M2, N2, A->type);
 
// также возможно получить только abs(M2-M1)+1 на abs(N2-N1)+1
// часть от полного результата свертки
CvMat* conv = cvCreateMat(A->rows + B->rows - 1, A->cols + B->cols - 1, A->type);
 
// инициализация A и B
...
int dftgM = cvGetOptimalDFTSize(A->rows + B->rows - 1);
int dftgN = cvGetOptimalDFTSize(A->cols + B->cols - 1);
 
CvMat* dftgA = cvCreateMat(dft_M, dft_N, A->type);
CvMat* dftgB = cvCreateMat(dft_M, dft_N, B->type);
CvMat tmp;
 
// копируем A в dftgA и заполняем dft_A нулями
cvGetSubRect(dftgA, &tmp, cvRect(0,0,A->cols,A->rows));
cvCopy(A, &tmp);
cvGetSubRect(dftgA, &tmp, cvRect(A->cols,0,dft_A->cols - A->cols,A->rows));
cvZero(&tmp);
// не нужно заполнять нижнюю часть dftgA нулями, потому что
// при вызове функции cvDFT() используется параметр nonzerogrows 
 
cvDFT(dftgA, dft_A, CV_DXT_FORWARD, A->rows);
 
// проделаем то-же со вторым массивом
cvGetSubRect(dftgB, &tmp, cvRect(0,0,B->cols,B->rows));
cvCopy(B, &tmp);
cvGetSubRect(dftgB, &tmp, cvRect(B->cols,0,dft_B->cols - B->cols,B->rows));
cvZero(&tmp);
 
// не нужно заполнять нижнюю часть dftgB нулями, потому что
// при вызове функции cvDFT() используется параметр nonzerogrows 
cvDFT(dftgB, dft_B, CV_DXT_FORWARD, B->rows);
 
cvMulSpectrums(dftgA, dft_B, dft_A, 0 /* или CV_DXT_MUL_CONJ чтобы получить корреляцию вместо свертки */);
 
cvDFT(dftgA, dft_A, CV_DXT_INV_SCALE, conv->rows); // вычисляем только
                                                   // верхнюю часть
cvGetSubRect(dftgA, &tmp, cvRect(0,0,conv->cols,conv->rows));
cvCopy(&tmp, conv);

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

LaTeX: Y={{F}^{(N)}}\cdot X

где

LaTeX: F_{jk}^{(N)}={{e}^{\frac{-i\cdot 2\cdot \pi \cdot j\cdot k}{N}}}

LaTeX: i=\sqrt{-1}

Обратное преобразование массива одномерных векторов (обычного массива значений с плавающей точкой):

LaTeX: {X}'={{\left( {{F}^{(N)}} \right)}^{-1}}\cdot Y=\left( \frac{1}{N} \right)\cdot X

Прямое преобразование для двумерной матрицы MxN:

LaTeX: Y={{F}^{(M)}}\cdot X\cdot {{F}^{(N)}}

Обратное преобразование для двумерной матрицы MxN:

LaTeX: {X}'=conj({{F}^{(M)}})\cdot Y\cdot conj({{F}^{(N)}})\cdot X=\left( \frac{1}{(M\cdot N)} \right)\cdot X

В случае одноканальных данных с плавающей точкой (single-channel), формат хранения результата прямого преобразования или аргумента для обратного преобразования заимствован из IPL и имеет вид:

LaTeX: \left[ \begin{matrix}
</p>
<pre>  \operatorname{Re}{{Y}_{0,0}} & \operatorname{Re}{{Y}_{0,1}} & \operatorname{Im}{{Y}_{0,1}} & \operatorname{Re}{{Y}_{0,2}} & \operatorname{Im}{{Y}_{0,2}} & ... & \operatorname{Re}{{Y}_{0,\frac{N}{2-1}}} & \operatorname{Im}{{Y}_{0,\frac{N}{2-1}}} & \operatorname{Re}{{Y}_{0,\frac{N}{2}}}  \\
  \operatorname{Re}{{Y}_{1,0}} & \operatorname{Re}{{Y}_{1,1}} & \operatorname{Im}{{Y}_{1,1}} & \operatorname{Re}{{Y}_{1,2}} & \operatorname{Im}{{Y}_{1,2}} & ... & \operatorname{Re}{{Y}_{1,\frac{N}{2-1}}} & \operatorname{Im}{{Y}_{1,\frac{N}{2-1}}} & \operatorname{Re}{{Y}_{1,\frac{N}{2}}}  \\
  \operatorname{Im}{{Y}_{1,0}} & \operatorname{Re}{{Y}_{2,1}} & \operatorname{Im}{{Y}_{2,1}} & \operatorname{Re}{{Y}_{2,2}} & \operatorname{Im}{{Y}_{2,2}} & ... & \operatorname{Re}{{Y}_{2,\frac{N}{2-1}}} & \operatorname{Im}{{Y}_{2,\frac{N}{2-1}}} & \operatorname{Im}{{Y}_{1,\frac{N}{2}}}  \\
  ... & ... & ... & ... & ... & ... & ... & ... & ...  \\
  \operatorname{Re}{{Y}_{\frac{M}{2-1},0}} & \operatorname{Re}{{Y}_{M-3,1}} & \operatorname{Im}{{Y}_{M-3,1}} & ... & ... & ... & \operatorname{Re}{{Y}_{M-3,\frac{N}{2-1}}} & \operatorname{Im}{{Y}_{M-3,\frac{N}{2-1}}} & \operatorname{Re}{{Y}_{\frac{M}{2-1},\frac{N}{2}}}  \\
  \operatorname{Im}{{Y}_{\frac{M}{2-1},0}} & \operatorname{Re}{{Y}_{M-1,1}} & \operatorname{Im}{{Y}_{M-2,1}} & ... & ... & ... & \operatorname{Re}{{Y}_{M-2,\frac{N}{2-1}}} & \operatorname{Im}{{Y}_{M-3,\frac{N}{2-1}}} & \operatorname{Im}{{Y}_{\frac{M}{2-1},\frac{N}{2}}}  \\
  \operatorname{Re}{{Y}_{\frac{M}{2},0}} & \operatorname{Re}{{Y}_{M-1,1}} & \operatorname{Im}{{Y}_{M-1,1}} & ... & ... & ... & \operatorname{Re}{{Y}_{M-1,\frac{N}{2-1}}} & \operatorname{Im}{{Y}_{M-3,\frac{N}{2-1}}} & \operatorname{Re}{{Y}_{\frac{M}{2},\frac{N}{2}}}  \\
</pre>
<p>\end{matrix} \right]

Замечание: последний столбец присутствует только когда N четное, последняя строка присутствует, когда M четное. В случае одномерного преобразования, результат выглядит как первая строка матрицы, приведенной выше.

 
Последние посты форума