在OpenCV中要练习的一些基本操作
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中要练习的一些基本操作的更多相关文章
- OpenCV中cv2的用法
一.读入图像 使用函数cv2.imread(filepath,flags)读入一副图片 filepath:要读入图片的完整路径 flags:读入图片的标志 cv2.IMREAD_COLOR:默认参数 ...
- 对OpenCV中3种乘法操作的理解掌握
参考了<Opencv中Mat矩阵相乘——点乘.dot.mul运算详解 >“http://blog.csdn.net/dcrmg/article/details/52404580”的相关内容 ...
- opencv中Mat与IplImage,CVMat类型之间转换
opencv中对图像的处理是最基本的操作,一般的图像类型为IplImage类型,但是当我们对图像进行处理的时候,多数都是对像素矩阵进行处理,所以这三个类型之间的转换会对我们的工作带来便利. Mat类型 ...
- 解析opencv中Box Filter的实现并提出进一步加速的方案(源码共享)。
说明:本文所有算法的涉及到的优化均指在PC上进行的,对于其他构架是否合适未知,请自行试验. Box Filter,最经典的一种领域操作,在无数的场合中都有着广泛的应用,作为一个很基础的函数,其性能的好 ...
- OpenCV中IplImage图像格式与BYTE图像数据的转换
最近在将Karlsruhe Institute of Technology的Andreas Geiger发表在ACCV2010上的Efficent Large-Scale Stereo Matchin ...
- opencv中的SIFT,SURF,ORB,FAST 特征描叙算子比较
opencv中的SIFT,SURF,ORB,FAST 特征描叙算子比较 参考: http://wenku.baidu.com/link?url=1aDYAJBCrrK-uk2w3sSNai7h52x_ ...
- 混合高斯模型:opencv中MOG2的代码结构梳理
/* 头文件:OurGaussmix2.h */ #include "opencv2/core/core.hpp" #include <list> #include&q ...
- opencv中的.at方法
opencv中的.at方法是用来获取图像像素值得函数: interpolation:差值 histogram:直方图
- 【OpenCV】OpenCV中GPU模块使用
CUDA基本使用方法 在介绍OpenCV中GPU模块使用之前,先回顾下CUDA的一般使用方法,其基本步骤如下: 1.主机代码执行:2.传输数据到GPU:3.确定grid,block大小: 4.调用内核 ...
随机推荐
- Maven命令安装jar包到本地仓库
https://blog.csdn.net/moxiong3212/article/details/78767480 当需要的jar包在中央仓库找不到或者是想把自己生成的jar包放到的Maven仓库中 ...
- python argv传递参数
test.pyimport sysprint(sys.argv) python test.py arg1 arg2 arg3 打印["test.py","arg1&quo ...
- 反射,内省,BeanUtil的区别
PS:为了操作反射方便,sun创建了 内省, Apache闲麻烦自己创建了BeanUtils 1.开发框架时,经常需要使用java对象的属性来封装程序的数据,每次都使用反射技术完成此类操作过于麻烦,所 ...
- 配置文件schema约束
解释:https://blog.csdn.net/zh15732621679/article/details/79074380 操作:https://blog.csdn.net/lhg_55/arti ...
- 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
- showdoc 开源在线api&&技术文档管理工具
showdoc 是一个很不错的api 以及技术文档管理工具 环境准备 doker-copose 文件 version: "3" services: doc: image: regi ...
- Singer 学习九 运行&&开发taps、targets (四 开发target)
singer 的target 需要从stdin 的行数据,同时处理schema.record.state 消息 指南 schema 需要进行关联stream records 数据的校验 一旦Targe ...
- ipfs cluster 模式部署使用(docker-compose 环境运行)
ipfs 点对点的分布式文件系统,官方提供了集群模式运行的docker 镜像,以及docker-compose 文件 所以测试下 环境准备 docker-compose version: '3.4 ...
- GBDT(Gradient Boosting Decision Tree) 没有实现仅仅有原理
阿弥陀佛.好久没写文章,实在是受不了了.特来填坑,近期实习了(ting)解(shuo)到(le)非常多工业界经常使用的算法.诸如GBDT,CRF,topic model的一些算 ...
- 【网络协议】TCP分段与IP分片
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/mmc_maodun/article/details/30109789 我们在学习TCP/IP ...