C++学习与OPENCV

c++学习笔记

1,C++环境配置
c++在练习时notepad++(txt)中写好,在cmd中运行。不过要配置一些环境变量。但是在cmd中调用cl,只进行编译而不会运行编译后的代码,如下代码

#include<iostream>
int main()
{
    std::cout<<"Enter two numbers:"<<std::endl;
    int v1=0,v2=0;
    std::cin>>v1>>v2;
    std::cout<<"The sum of"<<v1<<"and"<<v2
    <<"is"<<v1+v2<<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<iostream>
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<<num<<endl;
system("pause");
return 0;
}

Mat中的数据类型对应关系为

Mat_<uchar>对应的是CV_8U,Mat_<char>对应的是CV_8S,Mat_<int>对应的是CV_32S,Mat_<float>对应的是CV_32F,Mat_<double>对应的是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 两个傅立叶频谱间逐元素的乘法

猜你喜欢

转载自blog.csdn.net/u012140304/article/details/73350879
今日推荐