rm中的一些函数

看的一些代码,看到不少陌生的函数。记录一点之前没怎么用过的c++的用法。
explicit operator bool() const { return state; }
int operator()(const cv::Mat &image);
显式的类型转换运算符(explicit)

为了防止四中的异常情况发生,C++11标准引入了显式的类型转换运算符explicit
显示转换之后,不能直接使用隐式规则对类进行类型转换,需要使用static_cast显式的对类进行转换
格式:通过explicit关键字定义
  class SmallInt {
    
    
private:
    std::size_t val;
public:
    SmallInt(int i = 0) :val(i) {
    
    
        if (i < 0 || i>255)
            throw std::out_of_range("Bad SmallInt value");
    }
    operator int()const {
    
     return val; }
};

SmallInt si;
si = 4; //首先将4隐式转换为SmallInt,然后调用SmallInt::operator=
cout << si + 3 << endl; //打印7。首先将si隐式地转换为int,然后执行整数的加法。如果不定义operator,那么这一步将出错

struct A {
    
    
    A() = default;
    A(const B&); //把一个B转换成A
};
 
struct B {
    
    
    operator A()const; //也是把一个B转换成A
}

fmax()函数是cmath标头的库函数,用于查找给定数字的最大值,它接受两个数字并返回较大的一个。

Syntax of fmax() function:

fmax()函数的语法:

fmax(x, y);

RotatedRect该类表示平面上的旋转矩形,有三个属性:

矩形中心点(质心)
边长(长和宽)
旋转角度
class CV_EXPORTS RotatedRect
{
    
    
public:
    //构造函数
    RotatedRect();
    RotatedRect(const Point2f& center, const Size2f& size, float angle);
    RotatedRect(const CvBox2D& box);
    void points(Point2f pts[]) const;//!返回矩形的4个顶点
    Rect boundingRect() const; //返回包含旋转矩形的最小矩形
    operator CvBox2D() const;    //!转换到旧式的cvbox2d结构
    Point2f center; //矩形的质心
    Size2f size;   //矩形的边长
    float angle;  //旋转角度,当角度为0、90、180、270等时,矩形就成了一个直立的矩形
};
std::vector<cv::Mat> channels;       // 通道拆分

    cv::split(src, channels);               /************************/
    if (enemy_color == ENEMY_BLUE) {
    
             /*                      */
        color_channel = channels[0];        /* 根据目标颜色进行通道提取 */
    } else if (enemy_color == ENEMY_RED) {
    
        /*                      */
        color_channel = channels[2];        /************************/
    }

    int light_threshold;
    if(enemy_color == ENEMY_BLUE){
    
    
        light_threshold = 225;
    }else{
    
    
        light_threshold = 200;
    }

常使用push_back()向容器中加入一个右值元素(临时对象)时,首先会调用构造函数构造这个临时对象,然后需要调用拷贝构造函数将这个临时对象放入容器中。原来的临时变量释放。这样造成的问题就是临时变量申请资源的浪费。
引入了右值引用,转移构造函数后,push_back()右值时就会调用构造函数和转移构造函数,如果可以在插入的时候直接构造,就只需要构造一次即可。这就是c++11 新加的emplace_back
void cv::split(
const cv::Mat& mtx, //输入图像
vector& mv // 输出的多通道序列(n个单通道序列)
);

cv::Mat src = imread("lenna.jpg", cv::IMREAD_COLOR);
	cv::imshow("src", src);
 
	// Split the image into different channels
	std::vector<cv::Mat> rgbChannels(3);
	split(src, rgbChannels);
 
	// Show individual channels
	cv::Mat blank_ch, fin_img;
	blank_ch = cv::Mat::zeros(cv::Size(src.cols, src.rows), CV_8UC1);
 
	// Showing Red Channel
	// G and B channels are kept as zero matrix for visual perception
	std::vector<cv::Mat> channels_r;
	channels_r.push_back(blank_ch);
	channels_r.push_back(blank_ch);
	channels_r.push_back(rgbChannels[2]);
 
	/// Merge the three channels
	cv::merge(channels_r, fin_img);
	cv::imshow("R", fin_img);
	
 
	// Showing Green Channel
	std::vector<cv::Mat> channels_g;
	channels_g.push_back(blank_ch);
	channels_g.push_back(rgbChannels[1]);
	channels_g.push_back(blank_ch);
	cv::merge(channels_g, fin_img);
	cv::imshow("G", fin_img);

opencv imdecode和imencode用法

主要是对内存数据自动编解码

string fname = "D:/image.jpg";
//! 以二进制流方式读取图片到内存
FILE* pFile = fopen(fname.c_str(), "rb");
fseek(pFile, 0, SEEK_END);
long lSize = ftell(pFile);
rewind(pFile);
char* pData = new char[lSize];
fread(pData, sizeof(char), lSize, pFile);
fclose(pFile);

//! 解码内存数据,变成cv::Mat数据
cv::Mat img_decode;
vector<uchar> data;
for (int i = 0; i < lSize; ++i){
    
    
    data.push_back(pData[i]);
}
img_decode = cv::imdecode(data, CV_LOAD_IMAGE_COLOR);

转载一个程序:原文链接:https://blog.csdn.net/tt_ren/article/details/53227900
程序首先读入一个图片。然后encode,之后把encode后的内容写入文件(实际应用可以发送到网络)。
第二步,从文件读取encode的内容。然后解码decode。转换为mat格式,显示出来。

#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <iostream>
#include <sstream>
#include <string>
#include <opencv2/opencv.hpp>
#include <vector>
 
using namespace boost::filesystem;
namespace newfs = boost::filesystem;
using namespace cv;
————————————————

int main(int argc, char ** argv)
{
    
    
    cv::Mat img_encode;
    img_encode = imread("../res/test.png", CV_LOAD_IMAGE_COLOR);
 
    //encode image and save to file
    std::vector<uchar> data_encode;
    imencode(".png", img_encode, data_encode);
    std::string str_encode(data_encode.begin(), data_encode.end());
 
    path p("../res/imgencode_cplus.txt");
    newfs::ofstream ofs(p);
    assert(ofs.is_open());
    ofs << str_encode;
    ofs.flush();
    ofs.close();
 
    //read image encode file and display
    newfs::fstream ifs(p);
    assert(ifs.is_open());
    std::stringstream sstr;
    while(ifs >> sstr.rdbuf());
    ifs.close();
 
    Mat img_decode;
    std::string str_tmp = sstr.str();
    std::vector<uchar> data(str_tmp.begin(), str_tmp.end());
    img_decode = imdecode(data, CV_LOAD_IMAGE_COLOR);
    imshow("pic",img_decode);
    cvWaitKey(10000);
 
    return 0;
————————————————

imencode(".png", img_encode, data_encode); 第一个参数是图片后缀,第二个:Mat类型,第三个:vector类型 应该意为把Mat编码为向量。
注意两个函数的参数数量。imdecode有两个参数,encode有三个
注意这个写法:
std::vector data(str_tmp.begin(), str_tmp.end()); 直接把字符串转化为一组unchar类型的向量。

相机标定部分:

//
//  StereoCalib.h
//  stereo_calibrate_toe
//
//  Created by ding on 17/8/17.
//  Copyright (c) 2017年 ding. All rights reserved.
//

#ifndef __stereo_calibrate_toe__StereoCalib__
#define __stereo_calibrate_toe__StereoCalib__

#include "Header.h"

typedef struct{
    
    
    int height;
    int width;
    float distance_const;
    float f;
    //float yparam_const;
    //float ground;
    //float init_z;
    float lightbase;
}CalibParam;

class StereoCalib{
    
    
public:
    StereoCalib(const string &path){
    
    
        filehead = path;
        this->zpos = 0;
        this->ypos = 0;
        this->xpos = 0;
    };
    void KeyParam(int key);
    void Process(Mat &left,Mat &right);
private:
    void distanceCalib();
    void X_calib();
    void Y_calib();
    void FindTarget();
    void Position_show();
    void center_g(const vector<Point> contour,Point &center);
    void OtherOption();
public:
    Mat thresleft_cp,thresright_cp;
private:
    int rows,cols;
    int key;
    int calib_process = 0;
    int VisionDis = 0;
    vector<vector<Point> > contours_left,contours_right,Triangle_left,Triangle_right;
    vector<Vec4i> hierarchy_L,hierarchy_R;
    vector<Point> approx_left,approx_right;
    Point left_center,right_center;
    vector<Mat> split_left,split_right;
    Mat left_diff[2],right_diff[2];
    Mat init_left,init_right;
    int first_dis,second_dis;
    float xpos,ypos,zpos;
    float x_cal_z,x_cal_x1,x_cal_x2;
    Mat thresleft,thresright;
    int first_y,y_cal_z;
    double tan_theta;
    CalibParam Param;
    string filehead;
};



#endif /* defined(__stereo_calibrate_toe__StereoCalib__) */

cpp:

#include "StereoCalib.h"

void StereoCalib::Process(Mat &left,Mat &right){
    
    
    init_left = left;
    init_right = right;
    Triangle_left.clear();
    Triangle_right.clear();
    split(left,split_left);
    split(right, split_right);
    left_diff[0] = split_left[2] - split_left[1];
    right_diff[0] = split_right[2] - split_right[1];
    left_diff[1] = split_left[0] - split_left[1];
    right_diff[1] = split_right[0] - split_right[1];
    int total = right_diff[0].rows*right_diff[0].cols;
    rows = right_diff[0].rows;
    cols = right_diff[1].cols;
    thresleft = left_diff[0] + left_diff[1];
    thresright = right_diff[0] + right_diff[1];
    threshold(thresleft,thresleft,0,255,THRESH_OTSU);
    threshold(thresright,thresright,0,255,THRESH_OTSU);
    thresleft_cp = thresleft.clone();
    thresright_cp = thresright.clone();
    findContours(thresleft, contours_left,hierarchy_L,CV_RETR_TREE, CV_CHAIN_APPROX_NONE);
    findContours(thresright, contours_right,hierarchy_R,CV_RETR_TREE, CV_CHAIN_APPROX_NONE);
    int tlsize = 0;
    for(int i=0;i<contours_left.size();i++){
    
    
        approxPolyDP(contours_left[i], approx_left, 10, true);
        if(approx_left.size() == 4 && hierarchy_L[i][2] == -1 && hierarchy_L[i][3] != -1){
    
    
            contourArea(contours_left[i]);
            if(contourArea(contours_left[i]) > tlsize){
    
    
                tlsize = contourArea(contours_left[i]);
                Triangle_left.clear();
                center_g(contours_left[i], left_center);
                //circle(left, left_center, 5, Scalar(0,0,0),-1);
                Triangle_left.push_back(contours_left[i]);
            }
        }
    }
    for(int i=0;i<Triangle_left.size();i++){
    
    \
        if(tlsize==contourArea(Triangle_left[i])){
    
    
            center_g(Triangle_left[i], left_center);
        }
    }
    circle(left, left_center, 5, Scalar(0,0,0),-1);
    int trsize = 0;
    for(int i=0;i<contours_right.size();i++){
    
    
        approxPolyDP(contours_right[i], approx_right, 10, true);
        if(approx_right.size() == 4 && hierarchy_R[i][2] == -1 && hierarchy_R[i][3] != -1){
    
    
            contourArea(contours_right[i]);
            if(contourArea(contours_right[i]) > trsize){
    
    
                trsize = contourArea(contours_right[i]);
                Triangle_right.clear();
                center_g(contours_right[i], right_center);
                Triangle_right.push_back(contours_right[i]);
            }
        }
    }
    for(int i=0;i<Triangle_right.size();i++){
    
    \
        if(trsize==contourArea(Triangle_right[i])){
    
    
            center_g(Triangle_right[i], right_center);
        }
    }
    circle(right, right_center, 5, Scalar(0,0,0),-1);
    drawContours(left, Triangle_left, -1, Scalar(255,0,0),3);
    drawContours(right, Triangle_right, -1, Scalar(255,0,0),3);
    if(Triangle_left.size() == 1 && Triangle_right.size() == 1) VisionDis = abs(left_center.x - right_center.x);
    distanceCalib();
    X_calib();
    Y_calib();
    Position_show();
    OtherOption();
}

void StereoCalib::KeyParam(int key){
    
    
    this->key = key;
}

void StereoCalib::Position_show(){
    
    
    if(calib_process > 1 && VisionDis != 0){
    
    
        zpos = Param.distance_const/VisionDis;
    }
    if(calib_process > 3 && zpos > 0 && Param.f != 0){
    
    
        xpos = (left_center.x-cols/2)*zpos/Param.f;
    }
    if(calib_process > 5 && zpos > 0 && Param.f != 0){
    
    
        ypos = (Param.lightbase- left_center.y)*zpos/Param.f;
    }
    ostringstream strx,stry,strz;
    strx<<"x:"<<xpos<<"mm";
    stry<<"y:"<<ypos<<"mm";
    strz<<"z:"<<zpos<<"mm";
    putText(init_left, strx.str(), Point(cols-180,rows-100),FONT_HERSHEY_COMPLEX , 1, Scalar(255,0,255));
    putText(init_left, stry.str(), Point(cols-180,rows-70),FONT_HERSHEY_COMPLEX , 1, Scalar(255,0,255));
    putText(init_left, strz.str(), Point(cols-180,rows-40),FONT_HERSHEY_COMPLEX, 1, Scalar(255,0,255));
}

void StereoCalib::distanceCalib(){
    
    
    if(calib_process == 0){
    
    
        putText(init_left, "Press 'd' for 1st position.", Point(100,50), FONT_HERSHEY_COMPLEX_SMALL, 1, Scalar(255,0,255));
        if(key == 'd'){
    
    
            first_dis = VisionDis;
            Param.height = rows;
            Param.width = cols;
            calib_process = 1;
            std::cout<<"Move away 10.0cm,then press 'x'."<<std::endl;
        }

    }
    if(calib_process == 1){
    
    
        putText(init_left,"Move away 10.0cm,then press 'x'.", Point(100,50), FONT_HERSHEY_COMPLEX_SMALL, 1, Scalar(255,0,255));
        if(key == 'x'){
    
    
            second_dis = VisionDis;
            Param.distance_const = 100.0*((float)(first_dis * second_dis))/((float)(first_dis - second_dis));
            calib_process = 2;
            std::cout<<"Stay and press 'd'."<<std::endl;
        }
    }
}

void StereoCalib::X_calib(){
    
    
    if(calib_process == 2){
    
    
        putText(init_left, "Stay and press 'd'.", Point(100,50), FONT_HERSHEY_COMPLEX_SMALL, 1, Scalar(255,0,255));
        if(key == 'd'){
    
    
            x_cal_z = zpos;
            x_cal_x1 = left_center.x;
            calib_process = 3;
            std::cout<<"Move right 10cm,then press 'x'."<<std::endl;
        }
    }
    if(calib_process == 3){
    
    
        putText(init_left, "Move right 10cm,then press 'x'.", Point(100,50), FONT_HERSHEY_COMPLEX_SMALL, 1, Scalar(255,0,255));
        if(key == 'x'){
    
    
            x_cal_x2 = left_center.x;
            Param.f = (x_cal_x2 -x_cal_x1) * x_cal_z / 100.0;
            calib_process = 4;
            std::cout<<"Move to first z.Stay and press 'd'."<<std::endl;
        }
    }
}

void StereoCalib::Y_calib(){
    
    
    if(calib_process == 4){
    
    
        putText(init_left, "Move to first z.Stay and press 'd'.", Point(100,50), FONT_HERSHEY_COMPLEX_SMALL, 1, Scalar(255,0,255));
        if(key == 'd'){
    
    
            first_y = left_center.y;
            y_cal_z = zpos;
            calib_process = 5;
            std::cout<<"Move to second z.Stay and press 'x'."<<std::endl;
        }
    }
    if(calib_process == 5){
    
    
         putText(init_left, "Move to second z.Stay and press 'x'.", Point(100,50), FONT_HERSHEY_COMPLEX_SMALL, 1, Scalar(255,0,255));
         if(key == 'x'){
    
    
             Param.lightbase = (first_y * y_cal_z - left_center.y * zpos) / (y_cal_z - zpos);
             calib_process = 6;
             std::cout<<"finish"<<std::endl;
         }
    }
}


void StereoCalib::OtherOption(){
    
    
    if(calib_process == 6){
    
    
        filehead.append("stereo_calib.xml");
        FileStorage fs(filehead,FileStorage::WRITE);
        fs<<"height"<<Param.height
        <<"width"<<Param.width
        <<"distance_const"<<Param.distance_const
        <<"f"<<Param.f
        <<"lightbase"<<Param.lightbase;
        fs.release();
        calib_process = 7;
    }
}

void StereoCalib::center_g(const vector<Point> contour,Point &center){
    
    
    Moments mu;                                                 // Get the center of a contour
    mu = moments(contour,false);
    center.x=mu.m10/mu.m00;
    center.y=mu.m01/mu.m00;
}

猜你喜欢

转载自blog.csdn.net/qq_41358574/article/details/114645629