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. Blender 3D 打印插件Print Toolbox

    Blender 3D Print Toolbox Statistics 统计,可以提算出模型的体积,可供打印备料参考. Error Checking 错误检查 Solid 检查模型是否完整正确,是否有 ...

  2. 【单位矩阵】【杭电OJ1575】

    Tr A Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  3. random(随机模块)

    程序中有很多地方需要用到随机字符,比如登录网站的随机验证码,通过random模块可以很容易生成随机字符串 >>> random.randrange(1,10) #返回1-10之间的一 ...

  4. Queue接口的实现类竟然有一个是LinkedList,一个是优先队列(同一个接口,只改了不同的实现类,附源码)

    输出是: Queue接口底层换一个实现类,照样的是调用Queue接口中的方法 import java.util.HashMap; import java.util.LinkedList; import ...

  5. python基础(七)——网络编程

    服务端 我们使用 socket 模块的 socket 函数来创建一个 socket 对象.socket 对象可以通过调用其他函数来设置一个 socket 服务. 现在我们可以通过调用 bind(hos ...

  6. skipper lua 添加luarocks 包管理

    skipper 支持基于lua 的script 扩展,同时设计比较方便的filter模型,让我们可以方便 进行request.response的扩展,结合lua 社区的包我们可以快速的进行新功能的开发 ...

  7. android设备兼容性

    原文地址:http://developer.android.com/guide/practices/compatibility.html android被设计成能够在多种不同的设备上执行的系统,为了达 ...

  8. node nightmare 网页自动化测试 sample

    安装nightmare 编写1.js 运行 node 1.js var Nightmare = require('nightmare');var nightmare = Nightmare({ sho ...

  9. mysql之 误用SECONDS_BEHIND_MASTER衡量MYSQL主备的延迟时间

    链接:http://www.woqutech.com/?p=1116 MySQL 本身通过 show slave status 提供了 Seconds_Behind_Master ,用于衡量主备之间的 ...

  10. vue-cli 创建的项目,在 nginx 上配置启用浏览器缓存

    nginx 配置,关键参数: server { listen 80; server_name xxx.xxx.xxx.xxx; charset utf-8; root /home/xxx/dist/; ...