OpenCV上手有一些基本操作要练习下,其实是想把OpenCV玩的像MATLAB一样熟

照着MATLAB的手册从前到后找了下自己经常用到的东西,要完成的操作有:

// zeros ones eyes
// rand sort sortrows sum transpose 用键盘输入的方式初始化矩阵
// 乘法 det行列式 读取和更改任意位置 元素 一行几行 或几列 部分截取和修改填充
// reshape min max
// 拼接 删除 归一化 A(:) triu tril
// 读取矩阵尺寸 flipud fliplr diag
// 1:5:100步进 linspace repmat length meshgrid
// logical .* ./ strcat num2str rank trace
// 打印矩阵 解方程组 sqrt .^2
// sin cos tan arctan log exp 生成复数矩阵
// abs real angle
// fix floor round mod sign pi NaN的处理 conv2
// input interp interp2
// mean std diff
// fft fft2 ifft ifft2 fftshift ifftshift
// fminunc minFunc quad dblquad 可能没有
// 符号计算sym 可能没有
// 文件读写 目录操作 将一个mat的内容写入到文件中,再在另一个程序中读入
// rgb2gray im2bw imresize imrotate imcrop subplot
// ginput conhull imhist edge
// 作图部分还有一大堆,figure mesh surf 之类的,可能要第三方包
// 子矩阵赋值 矩阵拼接 特定列数、行数的抽取,删除
// find 二维矩阵拼接成三维矩阵
// svd

zeros,ones,eye:

 Mat A = Mat::zeros(,, CV_32F); // zeros

 Mat B = Mat::ones(,, CV_8U);   // ones

 Mat C = Mat::eye(,, CV_32F);   // eye

打印矩阵的几种方式:

 // 第一种,逐行逐列打印
for(int i=; i<A.rows; i++)
{
for(int j=; j<A.cols; j++)
cout << A.at<float>(i,j) << "\t"; // 打印矩阵 A
cout << endl;
} // 第二种
cout << "\n" << "A = " << "\n" << A << "\n" << endl;

矩阵初始化的几种方式:

 // 第一种,初始化,然后逐行逐列输入,再打印
Mat I = Mat(,, CV_64F);
cout << "请输入一个" << I.rows << "x" << I.cols << "大小的矩阵" << "\n";
for(int i=; i<I.rows; i++)
{
cout << "请输入第" << i << "行的" << I.cols << "个元素" << endl;
for(int j=; j<I.cols; j++)
{
cin >> I.at<double>(i,j); // 类型问题真他妈烦
//I.at<double>(i,j) = i+j;
}
}
cout << "\n" << "I = " << "\n" << I << "\n" << endl; // 第二种
Mat L = (Mat_<int>(,) << , -, , -, , -, , -, ); // 第三种
double b[] = {, , , };
Mat N = Mat(, , CV_64FC1, b); // 第四种
Mat K(Matx33d(
2759.48, , 1520.69,
, 2764.16, 1006.81,
, , ));

生成一个随机数或者随机矩阵:

 // 随机数
RNG rng; // Random number generator
double x = rng.uniform( (double), (double)); // 生成一个随机数 double类型,[0,1)之间
cout << "x = " << x << "\n" << endl; // 随机矩阵
Mat D = Mat(, , CV_32F);
randu(D, Scalar::all(), Scalar::all()); // 生成一个随机数矩阵,范围在[0,1)间,float类型
cout << "\n" << "D = " << "\n" << D << "\n" << endl; Mat E = Mat(, , CV_8UC1);
randu(E, Scalar::all(), Scalar::all()); // 生成一个随机数矩阵,范围在[0,255)间,8U类型
cout << "\n" << "E = " << "\n" << E << "\n" << endl;

排序,MATLAB中是sort和sortrows,但是没找到OpenCV中实现MATLAB中sortrows这种扩展排序的函数,先跳过:

 Mat F = Mat(, , CV_8UC1);
cv::sort( E, F, CV_SORT_EVERY_COLUMN); // 对每一列排序,注意要添加cv::,不然会认为是std中的sort,E是上面生成的随机矩阵
cout << "\n" << "F = " << "\n" << F << "\n" << endl; Mat G = Mat(, , CV_8UC1);
cv::sortIdx(E,G,CV_SORT_EVERY_COLUMN); // 看不懂,不知道类似MATLAB中的sortrows有没有,先跳过
cout << "\n" << "G = " << "\n" << G << "\n" << endl;

对行或列求和:

 Mat H = Mat(,, CV_8UC1);
reduce(E, H, , CV_REDUCE_SUM, CV_32S); // 0 是对列求和,1是对行求和,dtype参数要注意
cout << "\n" << "H = " << "\n" << H << "\n" << endl;
// 项目--属性--配置属性--C/C++--常规--多处理器编译--选择 是(/MP) 会让程序更快

矩阵转置,乘法,点乘:

 A.t()

 Mat J = I*I;   // 乘法

 Mat K = J.mul(J);  // 点乘

类型转换:

 Mat L1;
L.convertTo(L1,CV_32FC1); // L 转换为 L1 的 CV_32FC1 类型

求矩阵的行列式的值:

double a[] = {, , , };
Mat Ma = Mat(, , CV_64FC1, a); // 这也是一种矩阵初始化方式
double dst = determinant(Ma); // 小矩阵求行列式的值
cout << "\n" << "Ma = " << "\n" << Ma << "\n" << endl;
cout << "det of Ma is :" << dst << endl; //小型方阵直接计算,大型方阵(大于 3 x 3 的)用高斯消去法计算
//如果矩阵正定对称,用奇异值分解的方法解决 SVD; 以后解决

修改矩阵中某些元素或者某行某列的值:

 // 用 A.at<type>(i,j)修改
Mat L = (Mat_<int>(,) << , -, , -, , -, , -, );
cout << "\n" << "L = " << "\n" << L << "\n" << endl;
L.at<int>(,) = ;
cout << "\n" << "修改后L = " << "\n" << L << "\n" << endl; // 修改某些行或者列
L(Range(,), Range::all()) = ;
// 行号都是从0开始数起,但是都是左闭右开 [0,2) 代表第0和1行, rowRange、colRange类似
cout << "\n" << "修改某些行后的L = " << "\n" << L << "\n" << endl; // 下面这种方法自己也没搞透,貌似只能scalar,stackoverflow上看到的
Mat bigmat = Mat::zeros(,, CV_64FC1);; //Full matrix
Rect r(,,,); // Part of the matrix we are interested in
Mat roi(bigmat, r); // This submatrix will be a REFERENCE to PART of full matrix, NOT a copy
roi = Scalar();
cout << "\n" << "bigmat = " << "\n" << bigmat << "\n" << endl;

对矩阵的子矩阵赋值是一个经常使用到的重要操作,就算OpenCV中没有诸如MATLAB中[A;B]或者[A B]这种矩阵拼接方式,也可以通过新建一个矩阵

然后再把要拼接的矩阵赋值到子矩阵完成。

还有矩阵中特定行数或者列数的抽取、删除也很重要,以及诸如find函数,二维矩阵拼接成三维矩阵都相当重要。

先练习了下子矩阵赋值,也是stackoverflow上看到的:

 #include <opencv2/opencv.hpp>
#include <iostream> using namespace cv;
using namespace std; int main()
{
Mat X = Mat::zeros(,,CV_32FC1);
//Mat mat43= Mat::eye(2,2,CV_32FC1);
float b[] = {, , , };
Mat mat43 = Mat(, , CV_32FC1, b); cout << "\n" << "X = " << "\n" << X << "\n" << endl;
cout << "\n" << "mat43 = " << "\n" << mat43 << "\n" << endl; Mat aux = X.colRange(,).rowRange(,); // you are pointing to submatrix 4x3 at X(0,0)
cout << "\n" << "aux = " << "\n" << aux << "\n" << endl;
mat43.copyTo(aux);
cout << "\n" << "X = " << "\n" << X << "\n" << endl; system("PAUSE"); return ;
}

OpenCV中矩阵拼接:

 #include <opencv2/opencv.hpp>
#include <iostream> using namespace cv;
using namespace std; Mat cat1(Mat A, Mat B)
{
if(A.type()==B.type())
{
// [A;B] 竖直方向拼接
if(A.cols==B.cols)
{
Mat C = Mat( A.rows + B.rows, A.cols, A.type()); Mat Apart = C.rowRange(, A.rows).colRange(, A.cols);
Mat Bpart = C.rowRange(A.rows, A.rows+B.rows).colRange(, A.cols); A.copyTo(Apart);
B.copyTo(Bpart); cout << "\n" << "C = " << "\n" << C << "\n" << endl;
return C;
}
else
cout << "\n[A;B] 类型的拼接要求 A 和 B 的列数一致!\n" << endl;
}
else
cout << "\n A和B的类型不一致,无法拼接!\n" << endl;
} Mat cat2(Mat A, Mat B)
{
if(A.type()==B.type())
{
// [A B] 水平方向拼接
if(A.rows==B.rows)
{
Mat C = Mat( A.rows , A.cols+B.cols, A.type()); Mat Apart = C.rowRange(, A.rows).colRange(, A.cols);
Mat Bpart = C.rowRange(, A.rows).colRange(A.cols, A.cols+B.cols); A.copyTo(Apart);
B.copyTo(Bpart); cout << "\n" << "C = " << "\n" << C << "\n" << endl;
return C;
}
else
cout << "\n[A B] 类型的拼接要求 A 和 B 的行数一致!\n" << endl;
}
else
cout << "\n A和B的类型不一致,无法拼接!\n" << endl;
} int main()
{
//Mat A = Mat::zeros(3,4, CV_64F);
//Mat B = Mat::eye(3,4, CV_64F); Mat A = (Mat_<double>(,) <<
, -, ,
-, , -,
, -, );
Mat B = (Mat_<double>(,) <<
, , ,
, , ,
, , ); cout << "\n" << "A = " << "\n" << A << "\n" << endl;
cout << "\n" << "B = " << "\n" << B << "\n" << endl; cout << A.type() << endl;
cout << B.type() << endl; Mat C = cat2(B,A); system("pause");
return ;
}

==========================================================================

Mat矩阵保存到xml中,以及从xml中读取数据到Mat中,文件后缀也可以是txt:

 #include <iostream>
#include <fstream>
#include <iterator>
#include <vector>
#include <opencv2/opencv.hpp> using namespace std;
using namespace cv; int main()
{
Mat mat = Mat::eye(,,CV_32FC1);
FileStorage fs(".\\vocabulary.xml", FileStorage::WRITE);
fs<<"vocabulary"<<mat;
fs.release(); FileStorage fs(".\\vocabulary.xml", FileStorage::READ);
Mat mat_vocabulary;
fs["vocabulary"] >> mat_vocabulary; return ;
}

==========================================================================

SVD:

在MATLAB中做了下测试

A = ...
[1 0 1;
 -1 -2 0;
 0 1 -1]

svd后得到
U =
 -0.1200 -0.8097 0.5744
  0.9018  0.1531  0.4042
 -0.4153  0.5665  0.7118
S =
 2.4605 0          0
 0         1.6996  0
 0         0          0.2391
V =
 -0.4153 -0.5665  0.7118
 -0.9018  0.1531 -0.4042
  0.1200 -0.8097 -0.5744

其中:
AA = U*S*V'= A

OpenCV中svd如下:

 #include <opencv2/opencv.hpp>
#include <iostream> using namespace std;
using namespace cv; int main()
{
Mat A = (Mat_<float>(,) << , , , -, -, , , , -); Mat U(,,CV_64F), S(,,CV_64F), VT(,,CV_64F);
SVD thissvd(A,SVD::FULL_UV); U = thissvd.u;
S = thissvd.w;
VT = thissvd.vt;// 已经转置了 cout << "\n" << "U = " << "\n" << U << "\n" << endl;
cout << "\n" << "S = " << "\n" << S << "\n" << endl; // 3 x 1 的矩阵,和MATLAB中 3 x 3 的不同
cout << "\n" << "VT = " << "\n" << VT << "\n" << endl; system("PAUSE"); return ;
}

OpenCV中解线性方程组:

 #include <opencv2/opencv.hpp>
#include <iostream> using namespace std;
using namespace cv; int main()
{
Mat A(Matx33d(
, , ,
, , ,
, , )); // 由 MATLAB 中的 magic(3) 产生的矩阵 Mat B(Matx31d(
,
,
)); Mat X = Mat(,, CV_64F); solve(A, B, X, DECOMP_LU); // AX = B cout << "\n" << "X = " << "\n" << X << "\n" << endl; system("pause");
return ;
} //A =
// 8 1 6
// 3 5 7
// 4 9 2
//
//B =
// 1
// 2
// 3
//
//X =
// 0.0500
// 0.3000
// 0.0500

寻找最大最小值并返回索引值:

 #include <opencv2/opencv.hpp>
#include <iostream> using namespace cv;
using namespace std; int main()
{
double RawData[][] =
{{ 4.5, 1.1, 1.0 },
{ 8.1, 27.2, 19.9 }};
Mat RawDataMat(,,CV_64F,RawData); cout << "\n" << "RawDataMat = " << "\n" << RawDataMat << "\n" << endl; double minv = 0.0, maxv = 0.0;
double* minp = &minv;
double* maxp = &maxv; int minidx[] = {, }, maxidx[] = {, };
double minval = , maxval = ;
minMaxIdx(RawDataMat, &minval, &maxval, minidx, maxidx); cout << "minval = " << minval << endl;
cout << "maxval = " << maxval << endl;
cout << "min value at row: " << minidx[] << "\t" << "col: " << minidx[] << endl;
cout << "max value at row: " << maxidx[] << "\t" << "col: " << maxidx[] << endl; system("pause");
return ;
}

编辑时间:

2016年8月5日00:15:00

2016年8月8日00:06:35

2016年8月12日13:21:57

2016年8月16日18:50:14

2016年8月16日23:47:02

2016年8月17日17:09:43

在OpenCV中要练习的一些基本操作的更多相关文章

  1. OpenCV中cv2的用法

    一.读入图像 使用函数cv2.imread(filepath,flags)读入一副图片 filepath:要读入图片的完整路径 flags:读入图片的标志  cv2.IMREAD_COLOR:默认参数 ...

  2. 对OpenCV中3种乘法操作的理解掌握

    参考了<Opencv中Mat矩阵相乘——点乘.dot.mul运算详解 >“http://blog.csdn.net/dcrmg/article/details/52404580”的相关内容 ...

  3. opencv中Mat与IplImage,CVMat类型之间转换

    opencv中对图像的处理是最基本的操作,一般的图像类型为IplImage类型,但是当我们对图像进行处理的时候,多数都是对像素矩阵进行处理,所以这三个类型之间的转换会对我们的工作带来便利. Mat类型 ...

  4. 解析opencv中Box Filter的实现并提出进一步加速的方案(源码共享)。

    说明:本文所有算法的涉及到的优化均指在PC上进行的,对于其他构架是否合适未知,请自行试验. Box Filter,最经典的一种领域操作,在无数的场合中都有着广泛的应用,作为一个很基础的函数,其性能的好 ...

  5. OpenCV中IplImage图像格式与BYTE图像数据的转换

    最近在将Karlsruhe Institute of Technology的Andreas Geiger发表在ACCV2010上的Efficent Large-Scale Stereo Matchin ...

  6. opencv中的SIFT,SURF,ORB,FAST 特征描叙算子比较

    opencv中的SIFT,SURF,ORB,FAST 特征描叙算子比较 参考: http://wenku.baidu.com/link?url=1aDYAJBCrrK-uk2w3sSNai7h52x_ ...

  7. 混合高斯模型:opencv中MOG2的代码结构梳理

    /* 头文件:OurGaussmix2.h */ #include "opencv2/core/core.hpp" #include <list> #include&q ...

  8. opencv中的.at方法

    opencv中的.at方法是用来获取图像像素值得函数: interpolation:差值 histogram:直方图

  9. 【OpenCV】OpenCV中GPU模块使用

    CUDA基本使用方法 在介绍OpenCV中GPU模块使用之前,先回顾下CUDA的一般使用方法,其基本步骤如下: 1.主机代码执行:2.传输数据到GPU:3.确定grid,block大小: 4.调用内核 ...

随机推荐

  1. Maven命令安装jar包到本地仓库

    https://blog.csdn.net/moxiong3212/article/details/78767480 当需要的jar包在中央仓库找不到或者是想把自己生成的jar包放到的Maven仓库中 ...

  2. python argv传递参数

    test.pyimport sysprint(sys.argv) python test.py arg1 arg2 arg3 打印["test.py","arg1&quo ...

  3. 反射,内省,BeanUtil的区别

    PS:为了操作反射方便,sun创建了 内省, Apache闲麻烦自己创建了BeanUtils 1.开发框架时,经常需要使用java对象的属性来封装程序的数据,每次都使用反射技术完成此类操作过于麻烦,所 ...

  4. 配置文件schema约束

    解释:https://blog.csdn.net/zh15732621679/article/details/79074380 操作:https://blog.csdn.net/lhg_55/arti ...

  5. MACOS-Can't-connect-to-local-MySQL-server-through-socket-'/tmp/mysql.sock'

    mac os start mysql fail by "brew services start mysql"you can try : mysql.server  start

  6. showdoc 开源在线api&&技术文档管理工具

    showdoc 是一个很不错的api 以及技术文档管理工具 环境准备 doker-copose 文件 version: "3" services: doc: image: regi ...

  7. Singer 学习九 运行&&开发taps、targets (四 开发target)

    singer 的target 需要从stdin 的行数据,同时处理schema.record.state 消息 指南 schema 需要进行关联stream records 数据的校验 一旦Targe ...

  8. ipfs cluster 模式部署使用(docker-compose 环境运行)

    ipfs 点对点的分布式文件系统,官方提供了集群模式运行的docker 镜像,以及docker-compose 文件 所以测试下 环境准备 docker-compose   version: '3.4 ...

  9. GBDT(Gradient Boosting Decision Tree) 没有实现仅仅有原理

                阿弥陀佛.好久没写文章,实在是受不了了.特来填坑,近期实习了(ting)解(shuo)到(le)非常多工业界经常使用的算法.诸如GBDT,CRF,topic model的一些算 ...

  10. 【网络协议】TCP分段与IP分片

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/mmc_maodun/article/details/30109789     我们在学习TCP/IP ...