这篇文章整理了常用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
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.