Directorio de artículos
- Creación e inicialización
- Adición y sustracción de matrices
- multiplicación de matrices
- Transposición de matriz
- inversión de matriz
- El número de elementos distintos de cero en la matriz.
- Desviación estándar y media de la matriz
- Posición y extremo global de la matriz
- Multiplicación de matrices generales GEMM
- Transform realiza una transformación de matriz en cada elemento de la matriz
- MulTransposed Calcula el producto de una matriz y la transposición de una matriz
- Trace devuelve la traza de la matriz.
- Transponer la transpuesta de la matriz
- Det devuelve el valor determinante de la matriz.
- Invert encuentra la inversa o pseudoinversa de una matriz
- Resolver resuelve problemas de sistemas lineales o mínimos cuadrados
- SVD Descomposición en valores singulares de matrices reales de punto flotante
- Algoritmo de sustitución hacia atrás de valor singular SVBkSb (sustitución hacia atrás)
- EigenVV calcula los valores propios y los vectores propios de una matriz simétrica
- CalcCovarMatrix Calcula la matriz de covarianza de una colección de vectores
- Mahalanobis calcula la distancia de Mahalanobis entre dos vectores (distancia de Mahalanobis)
- CalcPCA realiza la transformación PCA en un conjunto de vectores
- ProjectPCA proyecta un vector en un subespacio
- operación matricial
- manipulación de secuencias de vídeo
- Obtener/establecer información del marco
- almacenar archivos de video
- Lista de otras funciones de operaciones matriciales
Creación e inicialización
Las operaciones con matrices en OpenCV son muy importantes. Este artículo resume la creación, la inicialización y las operaciones básicas con matrices de las matrices, y brinda códigos de muestra. Los contenidos principales incluyen:
1.1 Tipos de datos
Para establecer una matriz, debe especificar el tipo de datos almacenados en la matriz.Varios tipos de datos comúnmente utilizados en el procesamiento de imágenes son los siguientes:
CV_8UC1// 8位无符号单通道
CV_8UC3// 8位无符号3通道
CV_8UC4
CV_32FC1// 32位浮点型单通道
CV_32FC3// 32位浮点型3通道
CV_32FC4
Incluye profundidad de bits de datos de 8 bits, 32 bits, tipo de datos U: uchar, F: tipo flotante y número de canales C1: canal único, C3: tres canales, C4: cuatro canales.
1.2 Método básico
Podemos crear una matriz tipo Mat cargando una imagen, por supuesto, también podemos crear una matriz directamente manualmente, el método básico es especificar el tamaño de la matriz y el tipo de datos:
// 基本方法
cv::Mat a(cv::Size(5,5),CV_8UC1); // 单通道
cv::Mat b = cv::Mat(cv::Size(5,5),CV_8UC3); //3通道每个矩阵元素包含3个uchar值
cout<<"a = "<<endl<<a<<endl<<endl;
cout<<"b = "<<endl<<b<<endl<<endl;
system("pause");`
En una matriz de 3 canales, un elemento de matriz contiene 3 variables.
1.3 Método de inicialización
El método anterior no inicializa los datos de la matriz, por lo que aparecerán valores aleatorios. Si desea evitar esta situación, puede utilizar varios métodos de inicialización de la clase Mat para crear matrices:
// 初始化方法
cv::Mat mz = cv::Mat::zeros(cv::Size(5,5),CV_8UC1);
// 全零矩阵
cv::Mat mo = cv::Mat::ones(cv::Size(5,5),CV_8UC1);
// 全1矩阵
cv::Mat me = cv::Mat::eye(cv::Size(5,5),CV_32FC1);
// 对角线为1的对角矩阵
cout<<"mz = "<<endl<<mz<<endl<<endl;
cout<<"mo = "<<endl<<mo<<endl<<endl;
cout<<"me = "<<endl<<me<<endl<<endl;
resultado de la operación:
Adición y sustracción de matrices
Podemos usar los símbolos "+" y "-" para la suma y resta de matrices.
cv::Mat a= Mat::eye(Size(3,2), CV_32F);
cv::Mat b= Mat::ones(Size(3,2), CV_32F);
cv::Mat c= a+b;
cv::Mat d= a-b;
multiplicación de matrices
Use "*" para calcular la multiplicación de matriz y escalar, y la multiplicación de matriz y matriz (debe cumplir con las reglas correspondientes para el número de filas y columnas de la multiplicación de matriz)
Mat m1= Mat::eye(2,3, CV_32F); //使用cv命名空间可省略cv::前缀,下同
Mat m2= Mat::ones(3,2, CV_32F);
cout<<"m1 = "<<endl<<m1<<endl<<endl;
cout<<"m2 = "<<endl<<m2<<endl<<endl;
// Scalar by matrix
cout << "\nm1.*2 = \n" << m1*2 << endl;
// matrix per element multiplication
cout << "\n(m1+2).*(m1+3) = \n" << (m1+1).mul(m1+3) << endl;
// Matrix multiplication
cout << "\nm1*m2 = \n" << m1*m2 << endl;
Transposición de matriz
La transposición de matrices consiste en invertir el orden de las filas y columnas de la matriz (la i-ésima fila se convierte en la i-ésima columna) para formar una nueva matriz. OpenCV se implementa a través de la función t() de la clase Mat.
// Transponer
Mat m1= Mat::eye(2,3, CV_32F);
Mat m1t = m1.t();
cout<<"m1 = "<<endl<<m1<<endl<<endl;
cout<<"m1t = "<<endl<<m1t<<endl<<endl;
system("pause");
resultado de la operación:
inversión de matriz
La matriz inversa aparece a menudo en algunos algoritmos y se implementa mediante el método inv() de la clase Mat en OpenCV.
// 求逆
Mat meinv = me.inv();
cout<<"me = "<<endl<<me<<endl<<endl;
cout<<"meinv = "<<endl<<meinv<<endl<<endl;
system("pause");
La inversa de la matriz identidad es ella misma.
El número de elementos distintos de cero en la matriz.
Calcular el píxel o el área de un objeto a menudo requiere la cantidad de elementos distintos de cero en la matriz de cálculo, que se implementa en OpenCV mediante la función countNonZero().
// número de elementos distintos de cero
int nonZerosNum = countNonZero(me); // me es la matriz o imagen de entrada
cout<<"me = "<<endl<<me<<endl;
el número de elementos distintos de cero en cout<<"me="< <nonZerosNum< <endl<<endl;
system("pause");
resultado de la operación:
Desviación estándar y media de la matriz
OpenCV proporciona funciones de cálculo de desviación estándar y media de matriz, que se pueden implementar mediante la función meanStdDev(src, mean, stddev) Parámetros
src
: matriz de entrada o imagen
media: media, OutputArray
stddev: desviación estándar, OutputArray
// 均值方差
Mat mean;
Mat stddev;
meanStdDev(me, mean, stddev); //me为前文定义的5×5对角阵
cout<<"mean = "<<mean<<endl;
cout<<"stddev = "<<stddev<<endl;
system("pause");
Cabe señalar que si src es una imagen multicanal o una matriz multidimensional, la función calcula la media y la desviación estándar de diferentes canales respectivamente, por lo que los valores devueltos mean y stddev son vectores de dimensiones correspondientes.
Mat mean3;
Mat stddev3;
Mat m3(cv::Size(5,5),CV_8UC3,Scalar(255,200,100));
cout<<"m3 = "<<endl<<m3<<endl<<endl;
meanStdDev(m3, mean3, stddev3);
cout<<"mean3 = "<<mean3<<endl;
cout<<"stddev3 = "<<stddev3<<endl;
system("pause");
Resultado de la operación de matriz multicanal:
Posición y extremo global de la matriz
求输入矩阵的全局最大最小值及其位置,可使用函数:
void minMaxLoc(InputArray src, CV_OUT double* minVal,
CV_OUT double* maxVal=0, CV_OUT Point* minLoc=0,
CV_OUT Point* maxLoc=0, InputArray mask=noArray());
参数:
src – 输入单通道矩阵(图像).
minVal – 指向最小值的指针, 如果未指定则使用NULL
maxVal – 指向最大值的指针, 如果未指定则使用NULL
minLoc – 指向最小值位置(2维情况)的指针, 如果未指定则使用NULL
maxLoc – 指向最大值位置(2维情况)的指针, 如果未指定则使用NULL
mask – 可选的蒙版,用于选择待处理子区域
// 求极值 最大、最小值及其位置
Mat img = imread("Lena.jpg",0);
imshow("original image",img);
double minVal=0,maxVal=0;
cv::Point minPt, maxPt;
minMaxLoc(img,&minVal,&maxVal,&minPt,&maxPt);
cout<<"min value = "<<minVal<<endl;
cout<<"max value = "<<maxVal<<endl;
cout<<"minPt = ("<<minPt.x<<","<<minPt.y<<")"<<endl;
cout<<"maxPt = ("<<maxPt.x<<","<<maxPt.y<<")"<<endl;
cout<<endl;
cv::Rect rectMin(minPt.x-10,minPt.y-10,20,20);
cv::Rect rectMax(maxPt.x-10,maxPt.y-10,20,20);
cv::rectangle(img,rectMin,cv::Scalar(200),2);
cv::rectangle(img,rectMax,cv::Scalar(255),2);
imshow("image with min max location",img);
cv::waitKey();
resultado de la operación:
Multiplicación de matrices generales GEMM
void cvGEMM( const CvArr* src1, const CvArr* src2, doble alfa,
const CvArr* src3, doble beta, CvArr* dst, int tABC=0 );
#define cvMatMulAdd( src1, src2, src3, dst ) cvGEMM( src1, o
_
_
_
_
_
_
_ NULL si no hay compensación.
dst
matriz de salida
tABC
Indicador de operación T, que puede ser 0 o una combinación de los valores enumerados a continuación:
CV_GEMM_A_T - transponer src1
CV_GEMM_B_T - transponer src2
CV_GEMM_C_T - transponer src3
Por ejemplo, CV_GEMM_A_T+CV_GEMM_C_T corresponde a la función
alfa src1T src2 + beta*src3T
Ejecución de cvGEMM Multiplicación general de matrices:
dst = alpha*op(src1) op(src2) + beta op(src3), donde op(X) es X o XT
Todas las matrices deben tener el mismo tipo de datos y tamaño de matriz coordinado. Admite matrices de punto flotante reales o matrices de punto flotante complejas.
Transform realiza una transformación de matriz en cada elemento de la matriz
void cvTransform( const CvArr* src, CvArr* dst, const CvMat* transmat, const CvMat* shiftvec=NULL );
src
matriz de entrada
dst
matriz de salida
transmat
matriz de transformación
shiftvec función
de vector de desplazamiento opcional
cvTransform realiza la matriz en cada elemento de la matriz src Transformar y almacenar el resultado en dst:
dst(I)=transmat*src(I) + shiftvec
o
dst(I)k=sumj(transmat(k,j)*src(I)j) + shiftvec(k) Cada
elemento de la matriz de N-canales src se considera como un vector de N-elementos, usando un M×N El la matriz de transformación transmat y el vector de desplazamiento shiftvec lo transforman en un elemento de una matriz de canales M dst. Aquí puede optar por incrustar el vector de compensación shiftvec en transmat. En este caso, transmat debe ser una matriz de M × N + 1, y la columna más a la derecha se considera como el vector de compensación.
Las matrices de entrada y salida deben tener la misma profundidad y el mismo tamaño o tamaño de ROI. transmat y shiftvec deberían ser matrices reales de punto flotante.
Esta función se puede utilizar para la transformación geométrica del conjunto de puntos ND, la transformación del espacio de color lineal arbitrario, la transformación del canal, etc.
MulTransposed Calcula el producto de una matriz y la transposición de una matriz
void cvMulTransposed( const CvArr* src, CvArr* dst, int order, const CvArr* delta=NULL );
src
matriz de entrada
dst
destino matriz
orden
multiplicación orden
delta
una matriz opcional para restar de src antes de la multiplicación.
La función cvMulTransposed calcula el producto de src y su transpuesta.
Fórmula de evaluación de funciones:
si orden=0
dst=(src-delta)*(src-delta)T
más
dst=(origen-delta)T*(origen-delta)
Trace devuelve la traza de la matriz.
CvScalar cvTrace( const CvArr* mat );
mat
matriz de entrada
La función cvTrace devuelve la suma de los elementos diagonales de la matriz mat.
tr(origen) = ∑ mat(i,i)
i
Transponer la transpuesta de la matriz
void cvTranspose( const CvArr* src, CvArr* dst );
#define cvT cvTranspose
src
matriz de entrada
dst
matriz objetivo
La función cvTranspose busca la transposición de la matriz src:
dst(i,j)=src(j,i)
Tenga en cuenta que si es una matriz compleja, no se obtendrá el conjugado del número complejo. La conjugación debe ser independiente: consulte el código de ejemplo de cvXorS.
Det devuelve el valor determinante de la matriz.
double cvDet( const CvArr* mat );
mat
matriz de entrada
La función cvDet devuelve el valor determinante de la matriz cuadrada mat. Calcule directamente para matrices pequeñas y utilice el método de eliminación gaussiana (GAUSSIAN) para matrices grandes. Para una matriz simétrica positivamente determinada, también puede usar la función SVD, U=V=NULL, y luego usar el producto de los elementos diagonales de w para calcular el determinante.
Invert encuentra la inversa o pseudoinversa de una matriz
double cvInvert( const CvArr* src, CvArr* dst, int method=CV_LU );
#define cvInv cvInvert
src
input matrix
dst
target matrix
method
método de inversión:
CV_LU - Método de eliminación gaussiana para una selección de pivote óptima
CV_SVD - Método de descomposición de valores singulares (SVD)
CV_SVD_SYM - Método SVD para matrices simétricas definidas positivas
La función cvInvert invierte la matriz src y almacena el resultado en dst.
Si es el método LU, la función devuelve el valor determinante de src (src debe ser una matriz cuadrada). Si es 0, la matriz no se invierte y dst se llena con ceros.
Si el método SVD, la función devuelve el recíproco del número de condición de src (la proporción del valor singular más pequeño al valor singular más grande), y devuelve 0 si src es todo 0. Si src es singular, el método SVD calcula una matriz pseudo-inversa.
Resolver resuelve problemas de sistemas lineales o mínimos cuadrados
int cvSolve( const CvArr* src1, const CvArr* src2, CvArr* dst, int method=CV_LU );
src1 matriz de entrada
src2 parte derecha del sistema lineal
dst método de solución de salida
Solución (inversión de matriz) :
CV_LU - Eliminación gaussiana para selección de pivote óptima
CV_SVD - Descomposición en valores singulares (SVD)
CV_SVD_SYM - Método SVD para matrices simétricas definidas positivas
Función cvSolve para sistemas lineales o mínimos cuadrados (este último se puede resolver mediante el método SVD):
/mbox{dst} = /arg /min_X |/mbox{src1}/cdot X-/mbox{src2}|
si usa el método CV_LU. La función devuelve 1 si src1 no es singular y 0 en caso contrario, en cuyo caso dst no es válido.
SVD Descomposición en valores singulares de matrices reales de punto flotante
void cvSVD( CvArr* A, CvArr* W, CvArr* U=NULL, CvArr* V=NULL, int flags=0 );
Matriz de entrada AM×N W Matriz de valor singular resultante (M×N o N×N) o vector (N×1) U Matriz ortogonal izquierda opcional (M×M o M×N) Si CV_SVD_U_T es Especifica que el número
de las filas y columnas mencionadas anteriormente deben intercambiarse. V matriz ortogonal derecha opcional (N×N)
banderas
bandera de operación, puede ser 0 o una combinación de los siguientes valores:
CV_SVD_MODIFY_A La matriz src1 puede ser modificada por operación. De esta manera, la velocidad de procesamiento será más rápida.
CV_SVD_U_T significa que se devolverá la matriz transpuesta U, especificar este indicador acelerará el procesamiento.
CV_SVD_V_T significa que se devolverá la matriz transpuesta V, especificar este indicador acelerará el procesamiento.
La función cvSVD descompone la matriz A en un producto de una matriz diagonal y dos matrices ortogonales:
/matemáticas{/it A=UWV^T}
Aquí W es una matriz diagonal de valores singulares, que se puede codificar como un vector unidimensional de valores singulares, así como U y V. Todos los valores singulares son no negativos y se almacenan en orden descendente. (U y V
también se almacenan en consecuencia).El algoritmo SVD ha sido muy estable en el procesamiento numérico y sus aplicaciones típicas incluyen:
Resuelve exactamente problemas de valores propios cuando A es una matriz cuadrada, simétrica y positiva, por ejemplo, cuando A es una matriz de covarianza. En este caso, W será un vector de valores propios, y
U=V es el vector propio de la matriz (por lo tanto, solo es necesario calcular uno de U y V cuando es necesario calcular los vectores propios). Resuelve exactamente sistemas lineales mal acondicionados.
Solución de mínimos cuadrados de sistemas lineales sobredeterminados. Tanto el problema anterior como este problema pueden usar el método cvSolve especificando CV_SVD.
Cálculo preciso de las diferentes características de las matrices, como el rango (número de valores singulares distintos de cero), el número de condición (relación entre los valores singulares más grandes y los más pequeños), el valor determinante (el valor absoluto del determinante es igual al producto de los valores singulares)
. valores no requieren el cálculo de las matrices U y V.
Algoritmo de sustitución hacia atrás de valor singular SVBkSb (sustitución hacia atrás)
void cvSVBkSb( const CvArr* W, const CvArr* U, const CvArr* V,
const CvArr* B, CvArr* X, int flags );
W
Matriz de valor singular o vector
U
Matriz ortogonal izquierda (posiblemente transpuesta)
V
Matriz ortogonal derecha (posiblemente transpuesta)
B
La matriz multiplicativa de la pseudo-inversa de la matriz original A. Este es un parámetro opcional. Si se omite, se supone que es una matriz identidad de tamaño adecuado (así, x será la reconstrucción de la pseudo-inversa de A).
Matriz de destino X : la bandera de operación de banderas
del resultado del algoritmo de sustitución inversa de valor singular , que es la misma que la bandera del cvSVD que acabamos de analizar. La función cvSVBkSb calcula la sustitución hacia atrás para la matriz A y la matriz B descompuestas (ver descripción de cvSVD):
X=V W-1 UT*B
aquí
W-1(i,i)=1/W(i,i) si W(i,i) > epsilon•sumiW(i,i), de lo contrario: 0. epsilon es un número
pequeño
. Esta función y la función cvSVD se usan para ejecutar cvInvert y cvSolve. La razón para usar estas funciones (svd y bksb) es que la función principal (de bajo nivel) puede evitar la matriz temporal asignada internamente en el cálculo de la función avanzada (inv y resolver).
EigenVV calcula los valores propios y los vectores propios de una matriz simétrica
void cvEigenVV( CvArr* mat, CvArr* evects, CvArr* evals, double eps=0 );
mat
entrada matriz cuadrada simétrica. cambiará durante el procesamiento.
Efectúa
la matriz de salida del vector propio, almacena la matriz de salida del valor propio
evals en orden descendente continuamente (por supuesto, la clasificación de los valores propios y los vectores propios está sincronizada). Precisión de la diagonalización de eps (típicamente, DBL_EPSILON=≈10-15 es suficiente). La función cvEigenVV calcula los autovalores y autovectores de la matriz A:
mat*evects(i,:)' = evals(i)*evects(i,:)' (notación en MATLAB) Los
datos de la matriz A serán modificados por esta función.
Actualmente esta función es más lenta y menos precisa que la función cvSVD.Si se sabe que A es definida positiva (por ejemplo, es una matriz de covarianza), generalmente se entrega a la función cvSVD para calcular sus valores propios y vectores propios. , especialmente sin la necesidad de calcular los vectores propios
CalcCovarMatrix Calcula la matriz de covarianza de una colección de vectores
void cvCalcCovarMatrix( const CvArr** vects, int count, CvArr* cov_mat, CvArr* avg, int flags );
vects
vector de entrada. Deben tener el mismo tipo y tamaño de datos. Los vectores no tienen que ser unidimensionales, también pueden ser bidimensionales (por ejemplo, imágenes) y así sucesivamente.
cuente
el número de vectores de entrada
cov_mat
genera la matriz de covarianza, que es una matriz cuadrada de tipo punto flotante.
matriz de entrada o salida promedio
(dependiendo de las banderas ") - Vector promedio de vectores de entrada.
banderas banderas
de operación, una combinación de los siguientes valores:
CV_COVAR_SCRAMBLED - la matriz de covarianza de salida se calcula de la siguiente manera:
scale * [vects[0] − avg,vects[1] − avg,…]T * [vects[0] − avg,vects[ 1] − avg,…], es decir, la matriz de covarianza es count×count. Una matriz tan inusual se usa en métodos PCA rápidos para un conjunto de vectores grandes (por ejemplo, EigenFaces técnica de reconocimiento facial). Los valores propios de esta matriz codificada ("codificados") coincidirán con los valores propios de la matriz de covarianza verdadera, y los vectores propios verdaderos se pueden calcular fácilmente a partir de los vectores propios de la matriz de covarianza codificada ("codificados").
CV_COVAR_NORMAL: la matriz de covarianza de salida se calcula como:
scale * [vects[0] − avg,vects[1] − avg,…] * [vects[0] − avg,vects[1] − avg,…]T, es decir, cov_mat será uno y cada uno. matriz de covarianza con el mismo tamaño lineal en el número de elementos de los vectores de entrada. CV_COVAR_SCRAMBLED y CV_COVAR_NORMAL solo pueden especificar uno de ellos al mismo tiempo.
CV_COVAR_USE_AVG: si se especifica este indicador, la función no calculará el promedio a partir del vector de entrada, sino que utilizará el vector promedio anterior, lo cual es útil si el promedio se calculó de alguna manera. O si la matriz de covarianza se calcula parcialmente, en este caso, avg no es el promedio de un subconjunto de los vectores de entrada, sino el vector promedio de todo el conjunto.
CV_COVAR_SCALE: si se especifica este indicador, se escala la matriz de covarianza. la matriz de covariación está escalada, en modo "normal" el escalado es 1./cuenta, en modo "codificado" el escalado es el recíproco de la suma de los elementos de cada vector de entrada. De forma predeterminada (si no se especifica ninguna bandera), la matriz de covarianza no está escalada (escala = 1).
La función cvCalcCovarMatrix calcula la matriz de covarianza y el vector medio de los vectores de entrada. Esta función se puede utilizar en el análisis de componentes principales (PCA) y el vector de comparación de la distancia de Mahalanobis (distancia de Mahalanobis), etc.
Mahalanobis calcula la distancia de Mahalanobis entre dos vectores (distancia de Mahalanobis)
double cvMahalanobis( const CvArr* vec1, const CvArr* vec2, CvArr* mat );
vec1
el primer vector de entrada unidimensional
vec2
el segundo vector de entrada unidimensional
mat
La función de matriz inversa de la matriz de covarianza
cvMahalanobis calcula la diferencia entre dos vectores Distancia ponderada, el resultado devuelto es:
d(vec1,vec2)=/sqrt{ /sum_{i,j} /{mat(i,j) (vec1(i)-vec2(i)) (vec1(j)-vec2(j))/} }
La matriz de covarianza se puede calcular con la función cvCalcCovarMatrix y la matriz inversa se puede calcular con la función cvInvert (el método CV_SVD es una mejor opción, porque la matriz puede ser singular).
CalcPCA realiza la transformación PCA en un conjunto de vectores
void cvCalcPCA( const CvArr* data, CvArr* avg,
CvArr* eigenvalues, CvArr* eigenvectors, int flags);
datos de entrada de datos, cada vector es un vector de
una sola fila (CV_PCA_DATA_AS_ROW) o un vector de una sola columna (CV_PCA_DATA_AS_COL). , en la función Calculada internamente o proporcionada por la persona que llama para proporcionar los valores propios de la salida de la matriz de covarianza por valores propios Los vectores propios (es decir, los componentes principales) de la salida de la matriz de covarianza por vectores propios, cada vector tiene una fila de banderas banderas de operación, que pueden ser una combinación de los siguientes métodos: CV_PCA_DATA_AS_ROW: los vectores se almacenan en filas (es decir, cualquier vector se almacena continuamente) CV_PCA_DATA_AS_COL: los vectores se almacenan en columnas (es decir, el valor de un almacenado continuamente) (los dos signos anteriores se excluyen mutuamente Exclusivo) CV_PCA_USE_AVG: use el valor promedio precalculado . Esta función realiza la transformación PCA en un conjunto de vectores. Primero calcula la matriz de covarianza usando cvCalcCovarMatrix y luego calcula los valores propios y vectores propios de la matriz de covarianza Los valores propios de salida /vectores propios El número es menor o igual que MIN(filas(datos), cols(datos)).
ProjectPCA proyecta un vector en un subespacio
void cvProjectPCA( const CvArr* data, const CvArr* avg,
const CvArr* eigenvectors, CvArr* result )
datos de entrada de datos, cada vector puede ser un vector promedio promedio
de una sola fila o de una sola columna . O bien es un vector de una sola fila lo que significa que los datos de entrada están en filas Los datos se almacenan en forma de un vector de una sola columna, lo que significa que el vector de entrada se almacena en una columna.vectores propios vectores propios (componentes principales ) , cada vector tiene una fila. El resultado matriz de coeficiente de descomposición de salida, el número de filas de la matriz debe ser el mismo que El número de vectores de entrada es igual, y el número de columnas de la matriz debe ser menor que el número de filas del vector propio. Esta función proyecta la entrada vectores a un sistema ortogonal (vectores propios).Antes de calcular el producto escalar, los vectores de entrada se restan del vector medio:
result(i,:)=(data(i,:)-avg)*eigenvectors' // para diseño CV_PCA_DATA_AS_ROW.
[editar]
BackProjectPCA
reconstruye el vector original según los coeficientes de proyección
void cvBackProjectPCA( const CvArr* proj, const CvArr* avg,
const CvArr* eigenvects, CvArr* result ); datos de entrada del
proyecto
, consistentes con el formato del vector promedio cvProjectPCA
avg
. Si es un vector de una sola fila, significa que la salida El vector es De lo contrario, es un vector de una sola columna, luego el vector de salida se almacena en una columna.Vectores
propiosVectores propios
(componentes principales), cada vector tiene una fila.La matriz reconstruida generada por la función
de resultado reconstruye el original de acuerdo con la proyección. vector coeficiente:
result(i,:)=proj(i,:)*eigenvectors + avg // para diseño CV_PCA_DATA_AS_ROW
adjunto
operación matricial
Asignar espacio de matriz libre
Resumen:
OpenCV tiene funciones de lenguaje C para operaciones matriciales. Muchos otros métodos proporcionan interfaces C++ más convenientes con la misma eficiencia que OpenCV. OpenCV maneja vectores
como matrices 1D.
La matriz se almacena en filas, cada fila tiene 4 bytes de corrección.
Asignar espacio de matriz:
CvMat* cvCreateMat(int filas, int cols, int tipo);
type: 矩阵元素类型. 格式为CV_<bit_depth>(S|U|F)C<number_of_channels>.
例如: CV_8UC1 表示8位无符号单通道矩阵, CV_32SC2表示32位有符号双通道矩阵.
例程:
CvMat* M = cvCreateMat(4,4,CV_32FC1);
Liberar espacio de matriz:
CvMat* M = cvCreateMat(4,4,CV_32FC1);
cvReleaseMat(&M);
Copiar matriz:
CvMat* M1 = cvCreateMat(4,4,CV_32FC1),
CvMat* M2,
M2=cvCloneMat(M1);
Inicializar matriz:
doble a[] = { 1, 2, 3, 4, 5, 6
, 7, 8,
9, 10, 11, 12 };
CvMat Ma=cvMat(3, 4, CV_64FC1, a);
Otra forma:
Cv Mat Ma;
cvInitMatHeader(&Ma, 3, 4, CV_64FC1, a);
Inicialice la matriz como una matriz de identidad:
CvMat* M = cvCreateMat(4,4,CV_32FC1);
cvSetIdentity(M); // Parece que hay un problema aquí, sin éxito
Elementos de la matriz de acceso
Suponga que necesita acceder al (i,j)-ésimo elemento de una matriz bidimensional de punto flotante.
Acceso indirecto a los elementos de la matriz:
cvmSet(M,i,j,2.0); // Establecer M(i,j)
t = cvmGet(M,i,j); // Obtener M(i,j)
Acceso directo, asumiendo una alineación de 4 bytes:
CvMat* M = cvCreateMat(4,4,CV_32FC1),
int n = M->cols,
float *data = M->data.fl;
datos[i*n+j] = 3.0;
Acceso directo, byte de corrección arbitrario:
CvMat* M = cvCreateMat(4,4,CV_32FC1);
int step = M->step/sizeof(float);
float *data = M->data.fl;
(datos+i*paso)[j] = 3,0;
Acceso directo a un elemento de matriz inicializado:
double a[16];
CvMat Ma = cvMat(3, 4, CV_64FC1, a);
a[i*4+j] = 2.0; // Ma(i,j)=2.0 ;
Operaciones matriciales/vectoriales
operación matriz-matriz:
CvMat *Ma, *Mb, Mc;
cvAdd(Ma, Mb, Mc); // Ma+Mb -> Mc
cvSub(Ma, Mb, Mc); // Ma-Mb -> Mc
cvMatMul(Ma, Mb, Mc); // Ma Mb -> Mc
按电影的电影的operación matricial:
CvMat *Ma, *Mb, *Mc;
cvMul(Ma, Mb, Mc); // Ma.*Mb -> Mc
cvDiv(Ma, Mb, Mc); // Ma./Mb -> Mc
cvAddS(Ma, cvScalar(-10.0), Mc); // Ma.-10 -> Mc
Producto vectorial:
doble va[] = {1, 2, 3},
doble vb[] = {0, 0, 1},
doble vc[3];
CvMat Va=cvMat(3, 1, CV_64FC1, va);
CvMat Vb=cvMat(3, 1, CV_64FC1, vb);
CvMat Vc=cvMat(3, 1, CV_64FC1, vc);
double res=cvDotProduct(&Va,&Vb); // producto punto: Va . Vb -> res cvCrossProduct
(&Va, &Vb, &Vc); // producto vectorial: Va x Vb -> Vc
end{verbatim}
Nota Va, Vb, Vc debe tener el mismo número de elementos vectoriales en el producto vectorial.
Operación de matriz única:
CvMat *Ma, *Mb;
cvTranspose(Ma, Mb); // transpose(Ma) -> Mb (no se puede transponer a sí mismo)
CvScalar t = cvTrace(Ma); // trace(Ma) - > t. val[0]
doble d = cvDet(Ma); // det(Ma) -> d
cvInvert(Ma, Mb); // inv(Ma) -> Mb
Solución de sistema lineal no homogéneo:
CvMat* A = cvCreateMat(3,3,CV_32FC1);
CvMat* x = cvCreateMat(3,1,CV_32FC1);
CvMat* b = cvCreateMat(3,1,CV_32FC1);
cvSolve(&A, &b, &x); // resuelve (Ax=b) para x
Análisis de valores propios (para matrices simétricas):
CvMat* A = cvCreateMat(3,3,CV_32FC1);
CvMat* E = cvCreateMat(3,3,CV_32FC1);
CvMat* l = cvCreateMat(3,1,CV_32FC1);
cvEigenVV( &A , &E, &l); // l = valores propios de A (en orden descendente)
// E = vectores propios correspondientes (por fila)
Descomposición en valores singulares SVD:
CvMat* A = cvCreateMat(3,3,CV_32FC1);
CvMat* U = cvCreateMat(3,3,CV_32FC1);
CvMat* D = cvCreateMat(3,3,CV_32FC1);
CvMat* V = cvCreateMat( 3,3,CV_32FC1);
cvSVD(A, D, U, V, CV_SVD_U_T|CV_SVD_V_T); // La
etiqueta A = UDV^T hace transponer U y V al regresar (si no hay etiqueta de transposición, no hay problema éxito !!!).
manipulación de secuencias de vídeo
Toma un cuadro de una secuencia de video
OpenCV admite la captura de imágenes de la cámara web o archivos de video (AVI).
Obtenga la inicialización de la cámara:
CvCapture* capture = cvCaptureFromCAM(0); // capture from video device #0
Obtenga la inicialización del archivo de video:
CvCapture* capture = cvCaptureFromAVI(“infile.avi”);
Toma un cuadro:
IplImage* img = 0;
if(!cvGrabFrame(capture)){ // toma un cuadro
printf("No se pudo tomar un cuadro/n/7");
exit(0);
}
img=cvRetrieveFrame(captura ); // Restaurar imágenes de fotogramas capturados
Para adquirir imágenes de varias cámaras al mismo tiempo, primero capture un fotograma de cada cámara. Restaure las imágenes de fotogramas después de completar todas las acciones de captura.
Libere la fuente de captura:
cvReleaseCapture(&capture);
tenga en cuenta que la imagen capturada por el dispositivo se asigna y libera automáticamente mediante la función de captura. No intente liberarla usted mismo.
Obtener/establecer información del marco
Obtenga las propiedades del dispositivo:
cvQueryFrame(capture); // esta llamada es necesaria para obtener
// las propiedades de captura correctas
int frameH = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);
int frameW = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_W IDTH);
int fps = (int) cvGetCaptureProperty(capturar, CV_CAP_PROP_FPS);
int numFrames = (int) cvGetCaptureProperty(capturar, CV_CAP_PROP_FRAME_COUNT);
Todos los números de fotogramas parecen estar relacionados únicamente con archivos de video. ¡Error cuando se usa una cámara, extraño!
Obtenga información del cuadro:
float posMsec = cvGetCaptureProperty(capture, CV_CAP_PROP_POS_MSEC);
int posFrames = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES);
float posRatio = cvGetCaptureProperty(capture, CV_CAP_PROP_POS_AVI_RATIO) ;
Obtenga la posición del cuadro capturado en la secuencia de video, desde El primer cuadro se cuenta en milisegundos. O comience desde el primer cuadro con un número de 0 para obtener el número del cuadro capturado. O tome la posición relativa, el primer cuadro es 0 y el último cuadro es 1, que es solo válido para archivos de vídeo.
Establece la etiqueta del primer cuadro capturado:
// Captura desde la posición relativa 0.9 del archivo de video
cvSetCaptureProperty(capture, CV_CAP_PROP_POS_AVI_RATIO, (double)0.9);
solo es válido para capturar desde archivos de video. ¡Pero parece que no tiene éxito! ! !
almacenar archivos de video
Inicialice la memoria de video:
CvVideoWriter *writer = 0;
int isColor = 1;
int fps = 25; // o 30
int frameW = 640; // 744 para cámaras firewire
int frameH = 480; // 480 para cámaras firewirewriter
=cvCreateVideoWriter( "out.avi", CV_FOURCC('P','I','M','1'),
fps, cvSize(frameW,frameH),isColor);
otras codificaciones válidas:
CV_FOURCC('P','I','M','1') = códec MPEG-1
CV_FOURCC('M','J','P','G') = códec motion-jpeg (no funciona bien)
CV_FOURCC('M', 'P', '4', '2') = códec MPEG-4.2 CV_FOURCC (
'D', 'I', 'V', '3') = códec MPEG-4.3
CV_FOURCC( 'D', 'I', 'V', 'X') = códec MPEG-4 CV_FOURCC
('U', '2', '6', '3') = códec H263 CV_FOURCC
('I', '2 ', '6', '3') = Códec H263I
CV_FOURCC('F', 'L', 'V', '1') = Códec FLV1
Si el códec de video está configurado en -1, se abrirá una ventana de selección de códec (bajo sistema de ventanas).
Almacenar archivos de video:
IplImage* img = 0;
int nFrames = 50;
for(i=0;i<nFrames;i++){ cvGrabFrame(capturar); // capturar marco img=cvRetrieveFrame(capturar); // restaurar imagen cvWriteFrame ( escritor,img); //Agregar fotogramas al archivo de video } Para ver la imagen capturada durante la captura, agregue el siguiente código en el bucle:
cvShowImage(“mainWin”, img);
key=cvWaitKey(20); // espera 20 ms
Si no hay 20 [milisegundos] de retraso, la secuencia de video no se mostrará correctamente.
Liberar memoria de video:
cvReleaseVideoWriter(&writer);
Lista de otras funciones de operaciones matriciales
add
矩阵加法,A+B的更高级形式,支持mask
scaleAdd
矩阵加法,一个带有缩放因子dst(I) = scale * src1(I) + src2(I)
addWeighted
矩阵加法,两个带有缩放因子dst(I) = saturate(src1(I) * alpha + src2(I) * beta + gamma)
subtract
矩阵减法,A-B的更高级形式,支持mask
multiply
矩阵逐元素乘法,同Mat::mul()函数,与A*B区别,支持mask
gemm
一个广义的矩阵乘法操作
divide
矩阵逐元素除法,与A/B区别,支持mask
abs
对每个元素求绝对值
absdiff
两个矩阵的差的绝对值
exp
求每个矩阵元素 src(I) 的自然数 e 的 src(I) 次幂 dst[I] = esrc(I)
pow
求每个矩阵元素 src(I) 的 p 次幂 dst[I] = src(I)p
log
求每个矩阵元素的自然数底 dst[I] = log|src(I)| (if src != 0)
sqrt
求每个矩阵元素的平方根
min, max
求每个元素的最小值或最大值返回这个矩阵 dst(I) = min(src1(I), src2(I)), max同
minMaxLoc
定位矩阵中最小值、最大值的位置
compare
返回逐个元素比较结果的矩阵
bitwise_and, bitwise_not, bitwise_or, bitwise_xor
每个元素进行位运算,分别是和、非、或、异或
cvarrToMat
旧版数据CvMat,IplImage,CvMatND转换到新版数据Mat
extractImageCOI
从旧版数据中提取指定的通道矩阵给新版数据Mat
randu
以Uniform分布产生随机数填充矩阵,同 RNG::fill(mat, RNG::UNIFORM)
randn
以Normal分布产生随机数填充矩阵,同 RNG::fill(mat, RNG::NORMAL)
randShuffle
随机打乱一个一维向量的元素顺序
theRNG()
返回一个默认构造的RNG类的对象
theRNG()::fill(...)
reduce
矩阵缩成向量
repeat
矩阵拷贝的时候指定按x/y方向重复
split
多通道矩阵分解成多个单通道矩阵
merge
多个单通道矩阵合成一个多通道矩阵
mixChannels
矩阵间通道拷贝,如Rgba[]到Rgb[]和Alpha[]
sort, sortIdx
为矩阵的每行或每列元素排序
setIdentity
设置单元矩阵
completeSymm
矩阵上下三角拷贝
inRange
检查元素的取值范围是否在另两个矩阵的元素取值之间,返回验证矩阵
checkRange
检查矩阵的每个元素的取值是否在最小值与最大值之间,返回验证结果bool
sum
求矩阵的元素和
mean
求均值
meanStdDev
均值和标准差
countNonZero
统计非零值个数
cartToPolar, polarToCart
笛卡尔坐标与极坐标之间的转换
flip
矩阵翻转
transpose
矩阵转置,比较 Mat::t() AT
trace
矩阵的迹
determinant
行列式 |A|, det(A)
eigen
矩阵的特征值和特征向量
invert
矩阵的逆或者伪逆,比较 Mat::inv()
magnitude
向量长度计算 dst(I) = sqrt(x(I)2 + y(I)2)
Mahalanobis
Mahalanobis距离计算
phase
相位计算,即两个向量之间的夹角
norm
求范数,1-范数、2-范数、无穷范数
normalize
标准化
mulTransposed
矩阵和它自己的转置相乘 AT * A, dst = scale(src - delta)T(src - delta)
convertScaleAbs
先缩放元素再取绝对值,最后转换格式为8bit型
calcCovarMatrix
计算协方差阵
solve
求解1个或多个线性系统或者求解最小平方问题(least-squares problem)
solveCubic
求解三次方程的根
solvePoly
求解多项式的实根和重根
dct, idct
正、逆离散余弦变换,idct同dct(src, dst, flags | DCT_INVERSE)
dft, idft
正、逆离散傅立叶变换, idft同dft(src, dst, flags | DTF_INVERSE)
LUT
查表变换
getOptimalDFTSize
返回一个优化过的DFT大小
mulSpecturms
两个傅立叶频谱间逐元素的乘法
La tabla anterior se cita de: http://blog.sina.com.cn/s/blog_7908e1290101i97z.html
Indique la fuente de la reimpresión (este artículo actualiza el enlace): http://blog.csdn.net/iracer/article/details/51296631