这篇文章整理了常用opencv函数(用途、参数的意义,必要时也会列出该函数所在的头文件)以及一些其它关于opencv库的知识。补充了一些版本之间的头文件、函数等的调整。

一、基础

1

  • 查看版本
pkg-config --modversion opencv

如果要看cv 头文件里面具体的cpp实现,必须要去源码里面看。安装opencv的时候那些具体实现都被编译成二进制的库了。只能跳转到头文件。

3. 版本改动

OpenCV2到OpenCV3之间的改动比较小,而且现在的这些版本已经比较老了。所以此处给出的改动主要是2和3改到OpenCV4。可以参考此处,给出了很多有用的信息。

1. 头文件变动
/* old version ---> compatible with ros-noetic*/
#include <opencv/cv.h> //---> <opencv2/opencv.hpp>
#include <opencv/cxcore.h> //---> <opencv2/core/core_c.h>
#include <opencv/highgui.h> //---> <opencv2/highgui.hpp>
#include <opencv/imgproc.hpp> //---> <opencv2/imgproc.hpp>
2. was not declared in this scope

如果使用的opencv为3.2.0

// CV_WINDOW_AUTOSIZE’ was not declared in this scope
#include <opencv2/highgui/highgui_c.h>

// cvGetWindowHandle’ was not declared in this scope
#include <opencv2/highgui/highgui_c.h>

// CV_LOAD_IMAGE_UNCHANGED’ was not declared in this scope
#include <opencv2/imgcodecs/imgcodecs_c.h>
3. 判断所用的opencv的版本
#include <iostream>
#include <opencv2/core/version.hpp>
#include <opencv2/core/core.hpp>
 
using namespace cv;
 
#if CV_VERSION_EPOCH == 2
#define OPENCV2
#elif CV_VERSION_MAJOR == 3
#define  OPENCV3
#else
#error Not support this OpenCV version

5

cvMat停用,只能用cv::Mat. cvCreateMat是老版本产生cvMat的函数,应改用新的数据结构和构造函数。

6

cv::Mat的赋值=,默认是浅拷贝。

数组 <-> mat

数组转为mat

unsigned char cbuf[height][width];
cv::Mat img(height, width, CV_8UC1, (unsigned char*)cbuf);

mat转为数组

unsigned char *array=new unsigned char[mat.rows*mat.cols];
 
if (mat.isContinuous())
    array = mat.data;
vector <-> mat
cv::Mat a,b;
std::vector<double> vec;

a.convertTo(b,CV_64F);
vec = std::vector<double>(b.reshape(1,b.rows*b.cols)); // 把b转换为一个行矩阵,再转换为向量

a = cv::Mat(vec,true);
mat元素数据类型转换
cv::Mat mat_23f(2, 3, CV_32F);
mat_23f = (cv::Mat_<float>(2, 3) << 
 1, 2, 3, 
 4, 5, 6);
cv::Mat mat_23d(2, 3, CV_64F);
mat_23f.convertTo(mat_23d, CV_64F);

二、

CvImagePtr转换IplImage
IplImage image2;
cv_bridge::CvImagePtr cv_ptr;
// initialize cv_ptr
image2.imageData = (char *) cv_ptr->image.data;

详细参考此处

1. data()

2

三、matrix

1. create and set matrix

#####

XX

  • “cvmSet” and “cvmGet” 访问CV_32FC1CV_64FC1型数组的最简便的方式,其访问速度和直接访问几乎相同.
Scalar value;
// (out, in, in, in)
cvmSet( mat,row, col, value);
// (in,in,in)
value = cvmGet( mat, row, col);

//CV_[The number of bits per item][Signed or Unsigned][Type Prefix]C[The channel number]
//CV_8UC3:8位的 unsigned char 型,每个像素由三个元素组成三通道
  • cvSVD calculate singular values and singular vectors. flag is below. pic1
// (输入矩阵,结果奇异值矩阵,可选的左部正交矩阵,可选右部正交矩阵,flag): 奇异值都是非负的并按降序存储
void cvSVD( CvArr* A, CvArr* W, CvArr* U = NULL, CvArr* V = NULL, int flags = 0);
  • cvSetZero for dense, set all element as 0; for sparse, remove all elements.
void cvSetZero( CvArr* arr ) ;
init
//元素类型为float;Scalar::all(0):所有元素赋值为0
cv::Mat matA(3, 3, CV_32F, cv::Scalar::all(0)); 

3. solve

// src mat: square size and be symmetrical
// the eigenvalues are stored in the descending order. the eigenvectors are stored as subsequent matrix rows, in the same order as the corresponding eigenvalues.
// https://docs.opencv.org/3.4/d2/de8/group__core__array.html#ga9fa0d58657f60eaa6c71f6fbb40456e3
bool cv::eigen (InputArray src, OutputArray eigenvalues, OutputArray eigenvectors = noArray() );

// ( left-hand input matrix, right-hand input matrix, output solution, matrix decomposition types)
bool solve(const Mat & src1, const Mat & src2, Mat & dst, int flags = DECOMP_LU); 

//matVA is eigenvalues in the descending order 降序保存的特征值; matVE is eigenvector 特征向量
cv::eigen(matAC, matVA, matVE); 
// (in,out,*,*,new camera matrix)
cv::undistortPoints(ptc1, ptc2, cameraMatrix, distCoeffs, cameraMatrix);

camera

undistortion

new camera intrinsic matrix for fisheye camera

  • K: Original intrinsic matrix
  • D: Distortion coefficients from cv::fisheye::calibrate
  • imageSize: Image size
  • balance: 0 or 1, tradeoff between “keeping field of view” vs. “removing black borders”
  • K_new: Output “optimal” matrix for undistortion
#include <opencv2/calib3d.hpp>

cv::Mat K_new;
cv::fisheye::estimateNewCameraMatrixForUndistortRectify(
    K, D, imageSize, cv::Matx33d::eye(), K_new, balance, imageSize, 1.0);
cv::Mat K, D; // original intrinsics and distortion (fisheye)
cv::fisheye::estimateNewCameraMatrixForUndistortRectify(K, D, image_size, cv::Matx33d::eye(), K_new);
cv::Mat map1, map2;

cv::fisheye::initUndistortRectifyMap(K, D, cv::Matx33d::eye(), K_new, image_size, CV_16SC2, map1, map2);

Then:

  • K_new is the intrinsic matrix of the undistorted image
  • Distortion coefficients are [0, 0, 0, 0] (the undistorted image is rectified and has no distortion)

new camera intrinsic matrix for pinhole camera

cv::Mat new_K = cv::getOptimalNewCameraMatrix(K, distort_coeffs, image_size, alpha, new_image_size);
cv::Mat map1, map2;
cv::initUndistortRectifyMap(K, distort_coeffs, cv::Mat(), new_K, new_image_size, CV_16SC2, map1, map2);

After this:

  • Intrinsic: new_K
  • Distortion: [0, 0, 0, 0, 0]

pnp

cv::solvePnP assumes the pinhole camera model with radial/tangential distortion, not a fisheye projection. The result of cv::solvePnP gives the camera pose with respect to the world frame expressed in the camera frame. The returned translation vector describing the transformation from the world coordinate system to the camera coordinate system.