// 方法1
vector<int > v1(v2);//声明
// 方法2 使用swap进行交换:
vector<int > v1();
v1.swap(v2);
// 方法3 使用函数assign进行赋值 【推荐】
vector<int > v1;//声明v1
v1.assign(v2.begin(), v2.end());//将v2赋值给v1
// 方法4 循环赋值
vector<int >::iterator it;//声明迭代器
for(it = v2.begin();it!=v2.end();++it){//遍历v2,赋值给v1
v1.push_back(it);
}
在Vector中,size是指容器当前拥有元素的个数,而capacity是指容器在必须分配新的存储空间之前可以存放的元素总数。
reserve是容器预留空间,但在空间内不真正创建元素对象,所以在没有添加新的对象之前,不能引用容器内的元素。此时size() != capacity()。 resize是改变容器的大小,且在创建对象,因此,调用这个函数之后,就可以引用容器内的对象了 此时size() == capacity()。
vector<int> myVec, myVec1;
myVec.reserve( 100 ); // 新元素还没有构造, 此时不能用[]访问元素, 但在VS中Release模式下可以
cout << "size = " << myVec.size() << " \t capacity =" << myVec.capacity() << "endl";
for (int i = 0; i < 100; i++ )
{
myVec.push_back( i ); //新元素这时才构造
}
myVec1.resize( 102 ); // 用元素的默认构造函数构造了两个新的元素
myVec1[100] = 1; //直接操作新元素
myVec1[101] = 2;
cout << "size = " << myVec1.size() << " \t capacity =" << myVec1.capacity() << "endl";
vector<int> vi={1,2,3};
vi.resize(10, 9);
for(auto it=vi.begin();it!=vi.end();++it)
cout<<*it<<" ";
// 输出结果为 1 2 3 9 9 9 9 9 9 9
#OpenCV
下面几篇blog可以参考
OpenCV for Matlab Users 2 OpenCV for Matlab Users 3 OpenCV for Matlab Users 4 OpenCV for Matlab Users 5
如果对Mat中的rows cols与height width感到迷惑,可以看看 这篇文章 简单来说 在openCV新接口中(如 Mat, Range)是先rows 后cols 在老版本的接口类型中(如Point ,Rect) 是先宽后高 (x , y, w, h)
总的来说就是: Mat类的rows(行)<==> IplImage结构体的heigh(高)<==> point.y
Mat类的cols(列) <==> IplImage结构体的width(宽)<==> point.x
``` c++ // 初始化 Mat::zeros(thinIm.rows, thinIm.cols, CV_8U); Mat depth(h, w, DataType::type, cv::Scalar::all(0)); Mat zeroMatrix(Size(w, h), CV_8UC1, Scalar(0));
// 数组 float data = new float[rowscols]; Mat mt(rows, cols, CV_32FC1, data);
//是否加载成功 if(img.empty()) return -1;
//判断是否有数据 if(!img.data) return -1;
- **Range()**
Range是为了使opencv的使用更像Matlab而产生的。
比如Range::all()其实就是Matlab里的符号:或者...。
而Range(a, b)其实就是Matlab中的a:b (**包含a 不包括b**)
``` c++
// 第0行至第99行-->h,
// 第50列至199列-->w
// 返回的是视图, 修改roi_img 依旧会改变 src_img
roi_img = src_img(Range(0,100),Range(50,200));
// Range是适用Mat类型的
// Rect是旧接口
Mat B = A(Range::all(), Range(1, 300));
Mat B = A(Rect(0,0,100,100));
setTo(Scalar s, mask)函数是将图像设置为某个值,第二个参数是mask,可以省略
// 将src的值全部设置成0
src.setTo(0)
// 将src中大于或者小于某个值的像素值设置为指定的值
src.setTo(0,src < 10);
### Rect
``` c++
// 定义
typedef Rect_<int> Rect;
Rect_(); // 形参列表为空,即定义一个空窗口(默认值为:x=y=width=height=0)
// 略过不提
Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height);
Rect_(const Rect_& r);
Rect_(const CvRect& r);
//org为左上角起点, sz为 (width, height)
Rect_(const Point_<_Tp>& org, const Size_<_Tp>& sz);
// 由两个点构成的矩形 左上和右下
Rect_(const Point_<_Tp>& pt1, const Point_<_Tp>& pt2);
常用函数
rect.area(); //返回rect的面积 5000
rect.size(); //返回rect的尺寸 [50 × 100]
rect.tl(); //返回rect的左上顶点的坐标 [100, 50]
rect.br(); //返回rect的右下顶点的坐标 [150, 150]
rect.width(); //返回rect的宽度 50
rect.height(); //返回rect的高度 100
rect.contains(Point(x, y)); //返回布尔变量,判断rect是否包含Point(x, y)点
//还可以求两个矩形的交集和并集
rect = rect1 & rect2;
rect = rect1 | rect2;
//还可以对矩形进行平移和缩放
rect = rect + Point(-100, 100); //平移,也就是左上顶点的x坐标-100,y坐标+100
rect = rect + Size(-100, 100); //缩放,左上顶点不变,宽度-100,高度+100
//还可以对矩形进行对比,返回布尔变量
rect1 == rect2;
rect1 != rect2;
cv::cvtColor(srcImage, dstImage, cv::COLOR_GRAY2BGR);
cv::cvtColor(srcImage, dstImage, cv::COLOR_BGR2GRAY);
src.convertTo(dst, type, scale, shift)
dst(i) = (type) scale* src(i) +shift
using namespace cv;
Mat mat, mat1;
mat = Mat::zeros(100,100,CV_32F); // 得到一个浮点型的100*100的矩阵
mat.convertTo(mat1, CV_8U); // 把矩阵mat转为unsing char类型的矩阵
转换为浮点数需要加上scale,否则imshow显示的时候会全白 for example, 255 becomes 255.0. But when you try `imshow’ the resulting image, the command expects all pixel values to be between 0.0 and 1.0.
mat.convertTo(output, CV_32F, 1.0/255.0)
Mat Im, NonZeroLoc;
findNonZero(Im, NonZeroLoc);
for (int i = 0; i < NonZeroLoc.total(); i++) {
x = NonZeroLoc.at<Point>(i).x; // w 即cols
y = NonZeroLoc.at<Point>(i).y; // h 即rows
}
得到的NonZeroLoc的遍历结果,顺序是先高后宽,可以想象成一条竖线由左向右移动,竖线上的点由上而下。
//Matlab: B(A<1)=0
Mat B= A > 1;
// src2= (src1 <220 & src3 > 100); // Error, 条件不能是两个变量,即使大小相同
src2= (src1 <220 & src1 > 100); // 可以通过
void compare(InputArray src1, InputArray src2, OutputArray dst, int cmpop);
src1:原始图像1(必须是单通道)或者一个数值,比如是一个Mat或者一个单纯的数字n; src2:原始图像2(必须是单通道)或者一个数值,比如是一个Mat或者一个单纯的数字n; dst:结果图像,类型是CV_8UC1,即单通道8位图,大小和src1和src2中最大的那个一样,比较结果为真的地方值为 255,否则为0; cmpop:操作类型,有以下几种类型: enum { CMP_EQ=0, //相等
CMP_GT=1, //大于
CMP_GE=2, //大于等于
CMP_LT=3, //小于
CMP_LE=4, //小于等于
CMP_NE=5 //不相等 };
// 从图像中找出像素值为50的像素点
cv::Mat result;
cv::compare(image,50, result, cv::CMP_EQ);
void putTextonIm(Mat& mask, string text, Scalar color=Scalar(255, 0, 0))
{
int font_face = cv::FONT_HERSHEY_COMPLEX;
double font_scale = 2;
int thickness = 2;
int baseline;
//获取文本框的长宽
cv::Size text_size = cv::getTextSize(text, font_face, font_scale, thickness, &baseline);
cv::Point origin;
origin.x = mask.cols / 2 - text_size.width / 2;
origin.y = mask.rows / 2 + text_size.height / 2;
cv::putText(mask, text, origin, font_face, font_scale, color, thickness, 8, 0);
}
实现 begin() 和 end() 可以进行for循环遍历
class MyClass
{
public:
MyClass():a{ 1,2,3,4,5 }
{
}
int* begin()//stl::begin模版调用
{
return a;
}
int* end() //stl::end模版可以调用
{
return a + sizeof(a)/sizeof(int);
}
// 重载[]操作符,作为右值
int& operator [](const int index);
const int& operator [](const int index) const;
private:
int a[5];
};
int main()
{
MyClass myclass;
for(int var : myclass)
cout << var << " ";
for(int i=0 ; i < 5; ++i)
cout << myclass[i] << " ";
}
// 数字转字符串
string str = std::to_string(42);
// 字符串分割函数
std::vector<std::string> split(std::string str,std::string pattern)
{
std::string::size_type pos;
std::vector<std::string> result;
str+=pattern;//扩展字符串以方便操作
int size=str.size();
for(int i=0; i<size; i++)
{
pos=str.find(pattern,i);
if(pos<size)
{
std::string s=str.substr(i,pos-i);
result.push_back(s);
i=pos+pattern.size()-1;
}
}
return result;
}
Windows.h中的 max min会和 std::max std::min冲突 解决方法有下面两个
项目属性 ——> C/C++ ——> 预处理器 ——> 预处理器定义 ——>加入NOMINMAX
加上下面预处理代码
#define NOMINMAX
#undef max
#undef min