1,C++环境配置
c++在练习时notepad++(txt)中写好,在cmd中运行。不过要配置一些环境变量。但是在cmd中调用cl,只进行编译而不会运行编译后的代码,如下代码
#include
int main()
{
std::cout<<"Enter two numbers:"<::endl;
int v1=0,v2=0;
std::cin>>v1>>v2;
std::cout<<"The sum of"<"and" <
<<"is"<std: :endl;
return 0;
}
cmd中编译后,运行编译产生的exe文件可看到输入提示,代码运行。而在VS控制台项目中运行时会让输入v1 和v2,因为VS中编译和运行同时进行。
2,返回值return
return的返回值可以决定此函数完成后是否执行下一步,return 0执行,return -1(或者所有其他非0值),不执行。
3,opencv & C++
opencv配置问题
在配置opencv经常会出现debug能通过release通不过或者release能通过debug通不过的问题。
实际这和我们配置时的选择有关,连接器中输入的附加依赖项的问题不说(末尾d为debug,无d的为release),还有一项如图左上角
选择不同自然效果不同。
实际VC++也有管理插件的工具详见:
https://www.zhihu.com/question/24400428
1,imread读图读不到很可能是因为路径不对,最好是用绝对路径
2,关于opencv卷积有两个:filter2D(C++)和cvFilter2D(C)。第一个用于imread获得的Mat数据,第二个用于cvLoadImage获得的数据进行滤波。
既然图的原格式不同,那么核的格式不同,前者核的格式为Mat类型,后者为cvMat结构体
cvFilter的调用形式如下:
double k2_R[2] = { 1.0 / 2, 1.0 / 2 }; CvMat ker2_R = cvMat(1, 2, CV_32FC1, k2_R); CvMat ker2_U = cvMat(2, 1, CV_32FC1, k2_R);
double k2_RU[2][2] = {0}
Mat调用个行和列img.row和img.col。因为row和col为Mat类中一个public变量。
opencv中的filter2D可以进行滤波,根本原理也是图像的卷积,但是需要注意卷积和滤波的区别。两者都是卷积核对应像素相乘,但是卷积是将核旋转180度后对应相乘,而滤波是直接对应相乘。
imread默认以RGB图像进行读入imread(“img”,0);
vector和mat的互转(http://www.cnblogs.com/venus024/p/5897317.html)
mat转为vector
vector<double> getVector(const Mat &_t1f)
{
Mat t1f;
_t1f.convertTo(t1f, CV_64F);
return (vector<double>)(t1f.reshape(1, 1));
}
vector转mat
cv::Mat descriptor_Mat = Mat(rows,cols,type,(float*)descriptor_vector.data());
vector中迭代器的数据类型要和被迭代的vector保持一致如:代码中imgvector是double型it也要是double型
vector<double>::iterator it;
for (it = imgvector.begin(); it <= imgvector.end(); it++)
{
}
}
for循环中++i和i++效果相同,但是++i的运算速度相对较快
3,opencv不只用来对图像进行操作,opencv中的Mat类型和MATLAB中的矩阵很相似,MATLAB矩阵中的元素可以是正的负的,double行或者无符号行(如:uint8),Mat类型同样可以做到,如以下代码:
#include "opencv2/opencv.hpp"
#include "highgui.h"
#include
using namespace std;
int main()
{
cv::Mat a=(cv::Mat_<double>(5,5)<<-11,2,3,4,5,6,-77.0,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25);
double num=a.at<double>(1,1);
cout<"pause");
return 0;
}
Mat中的数据类型对应关系为
Mat_对应的是CV_8U,Mat_对应的是CV_8S,Mat_对应的是CV_32S,Mat_对应的是CV_32F,Mat_对应的是CV_64F,对应的数据深度如下:
CV_8U - 8-bit unsigned integers ( 0..255 )
• CV_8S - 8-bit signed integers ( -128..127 )
• CV_16U - 16-bit unsigned integers ( 0..65535 )
• CV_16S - 16-bit signed integers ( -32768..32767 )
• CV_32S - 32-bit signed integers ( -2147483648..2147483647 )
• CV_32F - 32-bit floating-point numbers ( -FLT_MAX..FLT_MAX, INF, NAN )
• CV_64F - 64-bit floating-point numbers ( -DBL_MAX..DBL_MAX, INF, NAN )
opencv中Mat元素获取 矩阵中元素的获取方法有多种但是运行速速却相差很大,如以下代码(对矩阵中的元素进行四舍五入保留一位小数)D是一个Mat矩阵。
方法一:
for (int i = 0; i < D.rows; ++i)
{
for (int j = 0; j < D.cols; ++j)
{
if (D.at<double>(i,j) >= 0.0)
{
D.at<double>(i,j) = floor(D.at<double>(i,j) * 10 + 0.5) / 10;
}
else
{
D.at<double>(i,j) = ceil(D.at<double>(i,j) * 10 - 0.5) / 10;
}
}
}
方法二
for (int i = 0; i < D.rows; ++i)
{
double *p2 = D.ptr<double>(i);
for (int j = 0; j < D.cols; ++j)
{
if (p2[j] >= 0.0)
{
p2[j] = floor(p2[j] * 10 + 0.5) / 10;
}
else
{
p2[j] = ceil(p2[j] * 10 - 0.5) / 10;
}
}
}
方法一相比方法二慢很多很多,当然还有一种迭代器方式,貌似也是特变慢。
opencv中有很多现成的Mat处理函数,能用则用,尽量减少for循环的使用,可以大大加强计算速度。
下表引自http://blog.sina.com.cn/s/blog_7908e1290101i97z.html
Function (函数名) | Use (函数用处) | |
---|---|---|
add | 矩阵加法,A+B的更高级形式,支持mask | |
scaleAdd | 矩阵加法,一个带有缩放因子dst(I) = scale * src1(I) + src2(I) | |
addWeighted | 矩阵加法,两个带有缩放因子dst(I) = saturate(src1(I) * alpha + src2(I) * beta + gamma) | |
subtract | 矩阵减法,A-B的更高级形式,支持mask | |
multiply | 矩阵逐元素乘法,同Mat::mul()函数,与A*B区别,支持mask | |
gemm | 一个广义的矩阵乘法操作 | |
divide | 矩阵逐元素除法,与A/B区别,支持mask | |
abs | 对每个元素求绝对值 | |
absdiff | 两个矩阵的差的绝对值 | |
exp | 求每个矩阵元素 src(I) 的自然数 e 的 src(I) 次幂 dst[I] = esrc(I) | |
pow | 求每个矩阵元素 src(I) 的 p 次幂 dst[I] = src(I)p | |
log | 求每个矩阵元素的自然数底 dst[I] = log|src(I)| (if src != 0) | |
sqrt | 求每个矩阵元素的平方根 | |
min, max | 求每个元素的最小值或最大值返回这个矩阵 dst(I) = min(src1(I), src2(I)), max同 | |
minMaxLoc | 定位矩阵中最小值、最大值的位置 | |
compare | 返回逐个元素比较结果的矩阵 | |
bitwise_and, bitwise_not, bitwise_or, bitwise_xor | 每个元素进行位运算,分别是和、非、或、异或 | |
cvarrToMat | 旧版数据CvMat,IplImage,CvMatND转换到新版数据Mat | |
extractImageCOI | 从旧版数据中提取指定的通道矩阵给新版数据Mat | |
randu | 以Uniform分布产生随机数填充矩阵,同 RNG::fill(mat, RNG::UNIFORM) | |
randn | 以Normal分布产生随机数填充矩阵,同 RNG::fill(mat, RNG::NORMAL) | |
randShuffle | 随机打乱一个一维向量的元素顺序 | |
theRNG() | 返回一个默认构造的RNG类的对象 theRNG()::fill(…) | |
reduce | 矩阵缩成向量 | |
repeat | 矩阵拷贝的时候指定按x/y方向重复 | |
split | 多通道矩阵分解成多个单通道矩阵 | |
merge | 多个单通道矩阵合成一个多通道矩阵 | |
mixChannels | 矩阵间通道拷贝,如Rgba[]到Rgb[]和Alpha[] | |
sort, sortIdx | 为矩阵的每行或每列元素排序 | |
setIdentity | 设置单元矩阵 | |
completeSymm | 矩阵上下三角拷贝 | |
inRange | 检查元素的取值范围是否在另两个矩阵的元素取值之间,返回验证矩阵 | |
checkRange | 检查矩阵的每个元素的取值是否在最小值与最大值之间,返回验证结果bool | |
sum | 求矩阵的元素和 | |
mean | 求均值 | |
meanStdDev | 均值和标准差 | |
countNonZero | 统计非零值个数 | |
cartToPolar, polarToCart | 笛卡尔坐标与极坐标之间的转换 | |
flip | 矩阵翻转 | |
transpose | 矩阵转置,比较 Mat::t() AT | |
trace | 矩阵的迹 | |
determinant | 行列式 |A|, det(A) | |
eigen | 矩阵的特征值和特征向量 | |
invert | 矩阵的逆或者伪逆,比较 Mat::inv() | |
magnitude | 向量长度计算 dst(I) = sqrt(x(I)2 + y(I)2) | |
Mahalanobis | Mahalanobis距离计算 | |
phase | 相位计算,即两个向量之间的夹角 | |
norm | 求范数,1-范数、2-范数、无穷范数 | |
normalize | 标准化 | |
mulTransposed | 矩阵和它自己的转置相乘 AT * A, dst = scale(src - delta)T(src - delta) | |
convertScaleAbs | 先缩放元素再取绝对值,最后转换格式为8bit型 | |
calcCovarMatrix | 计算协方差阵 | |
solve | 求解1个或多个线性系统或者求解最小平方问题(least-squares problem) | |
solveCubic | 求解三次方程的根 | |
solvePoly | 求解多项式的实根和重根 | |
dct, idct | 正、逆离散余弦变换,idct同dct(src, dst, flags | DCT_INVERSE) | |
dft, idft | 正、逆离散傅立叶变换, idft同dft(src, dst, flags | DTF_INVERSE) | |
LUT | 查表变换 | |
getOptimalDFTSize | 返回一个优化过的DFT大小 | |
mulSpecturms | 两个傅立叶频谱间逐元素的乘法 |