美文网首页
11:cmake编译Qt5

11:cmake编译Qt5

作者: 杨强AT南京 | 来源:发表于2019-11-26 20:22 被阅读0次

      想使用cmake来组织代码工程,其中使用opencv与Qt,下面使用的CMakeLists.txt存档于此备忘。


    opencv的使用例子

    cmake_minimum_required(VERSION 3.15)
    project(main)
    set(CMAKE_CXX_STANDARD 11)
    set(CMAKE_CXX_STANDARD_REQUIRED True)
    
    message(STATUS "编译OpenCV...")
    # aux_source_directory(. SOURCES)
    # add_executable(main ${SOURCES})
    
    find_path(INCLUDES opencv2/opencv.hpp /usr/local/include/opencv4/)
    
    message(STATUS ${INCLUDES})
    
    find_library(LIB1  opencv_core)
    find_library(LIB2  opencv_imgcodecs)
    find_library(LIB3  opencv_imgproc)
    find_library(LIB4  opencv_ml)
    
    include_directories(${INCLUDES})
    
    add_executable(main main.cpp)
    target_link_libraries(main ${LIB1} ${LIB2} ${LIB3} ${LIB4})
    
    

    Qt5的使用例子

     cmake_minimum_required(VERSION 3.15)
    project(main)
    set(CMAKE_INCLUDE_CURRENT_DIR ON)  
    set(CMAKE_CXX_STANDARD 11)
    set(CMAKE_CXX_STANDARD_REQUIRED True)
    SET(CMAKE_PREFIX_PATH /Users/yangqiang/Qt512/5.12.1/clang_64/lib/cmake)
    find_package(Qt5Core REQUIRED)
    FIND_PACKAGE(Qt5Widgets REQUIRED)
    FIND_PACKAGE(Qt5Gui REQUIRED)
    FIND_PACKAGE(Qt5Core REQUIRED)
    
    SET(CMAKE_AUTOMOC ON)
    SET(CMAKE_AUTOUIC ON)
    
    
    qt5_wrap_ui(UI_FILES output.ui)
    
    
    message(STATUS "编译Qt...")
    aux_source_directory(. SOURCES)
    add_executable(main ${SOURCES} ${UI_FILES})
    
    
    include_directories(
        /Users/yangqiang/Qt512/5.12.1/Src/qtbase/include
        /Users/yangqiang/Qt512/5.12.1/Src/qtbase/include/QtWidgets
        /Users/yangqiang/Qt512/5.12.1/Src/qtbase/include/QtCore
        /Users/yangqiang/Qt512/5.12.1/Src/qtbase/include/GtGui
        /Users/yangqiang/Qt512/5.12.1/Src/qtbase/include/QtWidgets
        /Users/yangqiang/Qt512/5.12.1/Src/qtbase/include/QThread
    )
    find_library(FRAMEWORK1  QtCore /Users/yangqiang/Qt512/5.12.1/clang_64/lib)
    find_library(FRAMEWORK2  QtGui /Users/yangqiang/Qt512/5.12.1/clang_64/lib)
    find_library(FRAMEWORK3  QtWidgets /Users/yangqiang/Qt512/5.12.1/clang_64/lib)
    target_link_libraries(main ${FRAMEWORK1} ${FRAMEWORK2} ${FRAMEWORK3})
    
    
    • 项目截图


      image.png

    opencv代码

    
    #include <opencv2/opencv.hpp>
    #include <iostream>
    
    void loadIrisFromTxt(cv::String filename, cv::Mat &data, cv::Mat &label){
        int rows = 150;
        int cols = 4;
        data.create(rows, cols, CV_32FC1);
        label.create(rows, 1, CV_32SC1);
        // 打开文件
        std::ifstream ifs(filename, std::ifstream::in);
        char buf[256];
        int row_id = 0;
        while(! ifs.eof()){
            bzero(buf, sizeof(buf));
            ifs.getline(buf, sizeof(buf)-1);
            std::istringstream istr(buf);
            float a, b, c, d;
            char buffer[256] = {0};
            char _;
            istr >> a >> _ >> b >> _ >> c >> _ >> d >> _ >> buffer;
            cv::Mat row_one = (cv::Mat_<float>(1,4) << a, b, c, d);
            row_one.copyTo(data.row(row_id));
    
            if(strcmp(buffer, "Iris-setosa") == 0){
                label.at<int>(row_id, 0) = 0;
            }
            else if (strcmp(buffer, "Iris-versicolor") == 0){
                label.at<int>(row_id, 0) = 1;
            }
            else if (! strcmp(buffer, "Iris-virginica")){
                label.at<int>(row_id, 0) = 2;
            }
            row_id ++;
        }
        // 关闭文件
        ifs.close();
    };
    // 可视化分类器与数据集
    void visual_classifier( cv::Mat data,      // 可视化数据集,必须2两个特征
                            cv::Mat label,     // 可视化标签,必须一个特征
                            cv::Mat &out,       // 输出的可视化图
                            cv::Ptr<cv::ml::SVM> classifer = 0,  // 需要可视化的分类器,可以为0
                            int w=512,          // 默认可视化区域
                            int h=512){         // 默认可视化区域
        // 可视化数据集与分类器,其中数据集需要方大到指定w与h,标签用来区分样本点的颜色
        // out.create(h, w, CV_8UC3);  // 初始化输出的图像
        out = cv::Mat(h, w, CV_8UC3, cv::Scalar(255, 255, 255));
        // 计算缩放比例
        double scale_x, scale_y; 
        // 计算数据集的x,y最大最小值
        double max_x, min_x;
        double max_y, min_y;
        cv::minMaxIdx(data.col(0), &min_x, &max_x);
        cv::minMaxIdx(data.col(1), &min_y, &max_y);
        // 扩边,避免点绘制在边界上
        min_x -= 0.5;
        max_x += 0.5;
        min_y -= 0.5;
        max_y += 0.5;
    
        scale_x = w / (max_x - min_x);
        scale_y = h / (max_y - min_y);
        
        /////////////////绘制分类器的分类边界开始//////////////////
        std::cout << "开始绘制分类区域!"<< std::endl;
        // 定义绘制颜色
        cv::Vec3b cr(0, 0, 128), cg(0, 128, 0), cb(128, 0, 0);
    
        //对区域循环判别作为的类别
        for(int y = 0; y < h; y++){
            for(int x = 0; x < w; x++){
                // 把x,y映射到样本区域;
                // 先缩放
                double a_x = x / scale_x;
                double a_y = y / scale_y;
                // 再平移
                a_x += min_x;
                a_y += min_y;
                // 使用这个点预测
                cv::Mat a_sample = (cv::Mat_<float>(1,2) << a_x, a_y);
                double pre = classifer->predict(a_sample);
                if(pre == 0) {
                    out.at<cv::Vec3b>(y, x) = cr;
                }
                else if(pre == 1 ){
                    out.at<cv::Vec3b>(y, x) = cg;
                }else if(pre == 2 ){
                    out.at<cv::Vec3b>(y, x) = cb;
                }
            }
        }
        /////////////////绘制分类器的分类边界结束///////////////////
        // 绘制支撑向量
        /////////////////绘制支撑向量开始///////////////////
        // 获取支撑向量
        cv::Mat sv = classifer->getSupportVectors();
        std::cout<< "支撑向量维度:" << sv.rows <<"," << sv.cols << std::endl;
        for (int i = 0; i < sv.rows; i++){
            const float* v = sv.ptr<float>(i);
            double v_x = v[0];
            double v_y = v[1];
            // 平移
            v_x -= min_x;
            v_y -= min_y;
            // 方大
            v_x *= scale_x;
            v_y *= scale_y; 
            // 绘制
            circle(out,  cv::Point( (int) v_x, (int) v_y), 3, cv::Scalar(255, 255, 255), 1);
    
        }
        /////////////////绘制支撑向量结束///////////////////
        std::cout << "开始绘制数据集样本点!"<< std::endl;
        // 定义绘制的颜色
        cv::Vec3b r(0, 0, 255), g(0, 255, 0), b(255, 0, 0);
        // 绘制样本点
        for(int i = 0; i < data.rows; i++){
            double d_x = data.at<float>(i, 0);
            double d_y = data.at<float>(i, 1);
            // 先平移到0点再放大
            d_x -= min_x;
            d_y -= min_y;
            d_x *= scale_x;
            d_y *= scale_y; 
            // 取整绘制
            int lab = label.at<int>(i,0);
            if(lab == 0){
                circle(out, cv::Point( (int) d_x,  (int) d_y ), 1, r, -1);
            }
            if(lab == 1){
                circle(out, cv::Point( (int) d_x,  (int) d_y ), 1, g, -1);
            }
            if(lab == 2){
                circle(out, cv::Point( (int) d_x,  (int) d_y ), 1, b, -1);
            }
        }
    }
    
    int main(int argc, const char** argv) {
        cv::Mat data, label;
        loadIrisFromTxt("iris.txt", data, label);
    
        cv::Mat newData;
        cv::hconcat(data.col(0), data.col(2), newData);
    
        // 创建SVM对象
        cv::Ptr<cv::ml::SVM>  svm = cv::ml::SVM::create();
        svm->setType(cv::ml::SVM::C_SVC);           // 带正则化惩罚因子C的SVM
        svm->setC(1000);                            // 设置C的值
        svm->setGamma(0.001);                        // 设置gamma的值
        svm->setKernel(cv::ml::SVM::SIGMOID);        // 设置SVM的核
        svm->setTermCriteria(cv::TermCriteria(cv::TermCriteria::MAX_ITER, (int)1e8, 1e-8));  // 设置训练终止条件
        // 训练终止条件
        svm->setTermCriteria(cv::TermCriteria(cv::TermCriteria(cv::TermCriteria::MAX_ITER, (int)1e8, 1e-8)));
        // 开始训练
        svm->train(newData,cv::ml::ROW_SAMPLE,label);
        // 使用训练集预测
        cv::Mat  predict;
        svm->predict(newData, predict);   // 第三个参数取默认值,预测返回的结果是CV_32F类型
        predict.convertTo(predict, CV_32SC1);   // 需要转换为一致才能比较
    
        // 统计准确率
        cv::Mat result;
        cv::compare(label, predict, result, cv::CMP_EQ); // 比较结果, 相等true,则设置为255,false设置为0
        cv::Scalar mean = cv::mean(result / 255.0);
        std::cout<<"识别准确率:";
        std::cout << std::fixed << std::setprecision(2) << mean[0] * 100.0 <<"%"<< std::endl;
        
        cv::Mat img;
    
        visual_classifier(newData, label, img, svm);
        imwrite("visual.png", img); 
        return 0;
    }
    
    
    • 输出图片


      SVM对鸢尾花的分类可视化

    相关文章

      网友评论

          本文标题:11:cmake编译Qt5

          本文链接:https://www.haomeiwen.com/subject/qciywctx.html