Vector
vector 複製
// 方法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內存釋放需要使用下面語句
單獨的clear會導致內存泄漏
vector<T>().swap(x);
x.clear();
reserve 和resize
在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";
- resize
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
如果對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
// 初始化
Mat::zeros(thinIm.rows, thinIm.cols, CV_8U);
Mat depth(h, w, DataType<ushort>::type, cv::Scalar::all(0));
Mat zeroMatrix(Size(w, h), CV_8UC1, Scalar(0));
// 數組
float *data = new float[rows*cols];
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)
// 第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));
- Mat::setTo()
setTo(Scalar s, mask)函數是將圖像設置爲某個值,第二個參數是mask,可以省略
// 將src的值全部設置成0
src.setTo(0)
// 將src中大於或者小於某個值的像素值設置爲指定的值
src.setTo(0,src < 10);
- Mat 是否相等
來源於這個博客,點擊查看原文
bool matIsEqual(const cv::Mat mat1, const cv::Mat mat2) {
if (mat1.empty() && mat2.empty()) {
return true;
}
if (mat1.cols != mat2.cols || mat1.rows != mat2.rows || mat1.dims != mat2.dims||
mat1.channels()!=mat2.channels()) {
return false;
}
if (mat1.size() != mat2.size() || mat1.channels() != mat2.channels() || mat1.type() != mat2.type()) {
return false;
}
int nrOfElements1 = mat1.total()*mat1.elemSize();
if (nrOfElements1 != mat2.total()*mat2.elemSize()) return false;
bool lvRet = memcmp(mat1.data, mat2.data, nrOfElements1) == 0;
return lvRet;
}
Rect
// 定義
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;
cvtColor 顏色空間轉換
cv::cvtColor(srcImage, dstImage, cv::COLOR_GRAY2BGR);
cv::cvtColor(srcImage, dstImage, cv::COLOR_BGR2GRAY);
convertTo 類型轉換
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)
findNonZero
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 find
//Matlab: B(A<1)=0
Mat B= A > 1;
// src2= (src1 <220 & src3 > 100); // Error, 條件不能是兩個變量,即使大小相同
src2= (src1 <220 & src1 > 100); // 可以通過
- compare函數
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);
將多 channels轉成1 channels
static Mat formatImageForPCA(const Mat &data, int rows)
{
Mat dst(rows, 2, CV_32F);
for (unsigned int i = 0; i < rows; i++)
{
Mat image_row = data.row(i).clone().reshape(1, 1);
Mat row_i = dst.row(i);
image_row.convertTo(row_i, CV_32F);
}
return dst;
}
Mat::type
Mat::type() 表示了矩陣中元素的類型以及矩陣的通道個數
Mat a(n, n, src.type(), ptr, astep);
Class && 符號重載
實現 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;
}
std::next_permutation
C++的全排列函數
min/max宏衝突
Windows.h中的 max min會和 std::max std::min衝突
解決方法有下面兩個
項目屬性 ——> C/C++ ——> 預處理器 ——> 預處理器定義 ——>加入NOMINMAX
加上下面預處理代碼
#define NOMINMAX #undef max #undef min