opencv的基础用法及其在QT中的应用

文章目录

      • 一.基础用法
        • 1.图片色彩空间转换
        • 2.保存图片
        • 3.图片浏览器
        • 4.播放视频文件
        • 5.调整图片大小
        • 6.截图 抠图 矩形(Point(x,y) Size(w,h))
        • 7.图片中画矩形框
      • 二、opencv在QT中的用法
        • 1.QT中导入opencv
        • 2.cv图片转qt图片
        • 3.图片与控件的大小适应
        • 4.定时器事件
        • 5.矩形外像素点变暗
        • 6.Qt滑动条控制像素点
        • 7.sqlite数据库
        • 8.级联分类器
        • 9.人脸识别器
        • 10.自定义定时器

创作不易,先赞后看

一.基础用法

1.图片色彩空间转换

int fun1()
{
    //Mat opencv中表示图片的类型
    Mat src;
    //imread 加载图片
    src = imread("D:/opencv/1.jpg");
    if (src.empty()) {
        cout<<"could not load image...\n"<<endl;
        return -1;
    }

    //转换图片色彩空间1、BGR->RGB
    //参数1:原图    参数2:目标图    参数3:空间参数
    Mat dst;
    cvtColor(src , dst ,CV_BGR2RGB);

    //2、灰度
    Mat gray;
    cvtColor(src , gray , CV_BGR2GRAY);

    imshow("src" , src);
    imshow("dst" , dst);
    imshow("gray" , gray);

    //创建窗口           标题名字
    //namedWindow("input image", CV_WINDOW_AUTOSIZE);

    //显示图片(1.自动创建窗口  2.显示图片)
    //imshow("input image", src);

    //等待键盘输入  参数0:永久等待
    waitKey(0);
}

2.保存图片

int fun2()
{
    Mat src;
    src = imread("D:/opencv/1.jpg");
    if (src.empty()) {
        cout<<"could not load image...\n"<<endl;
        return -1;
    }
    //转换为灰度图
    Mat gray;
    cvtColor(src,gray,CV_BGR2GRAY);

    //保存图片
    imwrite("D:/opencv/gray.jpg",gray);
}

3.图片浏览器

int fun3()
{
    vector<string> paths;
    for(int i=1;i<=32;i++)
    {
        char buf[50];
        sprintf(buf,"D:/QT/heads/head%d.jpg",i);
        cout<<buf<<endl;
        paths.push_back(buf);
    }
    Mat src = imread(paths[0]);
    imshow("src",src);
    int i = 0;
    while(true)
    {
        int key = waitKey(0);
        if(key == 'a')
        {
            cout<<"pre"<<endl;
            i = i==0?31:i-1;
            imshow("src",imread(paths[i]));
        }
        else if(key == 'd')
        {
            cout<<"next"<<endl;
            i = i==31?0:i+1;
            imshow("src",imread(paths[i]));
        }
        if(key == 'b')
        {
            break;
        }
    }
}

4.播放视频文件

int fun4()
{
    //1.视频对象
    VideoCapture vc;
    //2. 打开视频文件    打开摄像头,参数0
    //if(vc.open("D:/QT/img/mv2.mp4"))
    if(vc.open(0))
    {
        while(true)
        {
            Mat src;
            //3.提取一帧图像 >>自动往后取下一帧图像
            vc>>src;
            //4.如果提取成功,播放图像
            if(!src.empty())
            {
                Mat gray;
                cvtColor(src , gray , CV_BGR2GRAY);

                //反转图像 0:x轴 1:y轴 -1:xy轴
                flip(gray,gray,1);
                int x = gray.cols/2;
                int y = gray.rows/2;
                //矩形
                Rect r(Point(x-100,y-100),Size(200,200));

                //画框 原图 矩形 颜色BGR
                rectangle(gray,r,Scalar(255,255,255),3);
                imshow("gray",gray);
                //0:永久等待 其他:单位毫秒
                waitKey(20);
            }
            else
            {
                break;
            }
        }
    }
    else
    {
        cout<<"open fail"<<endl;
    }
}

5.调整图片大小

int fun5()
{
    Mat src;
    src = imread("D:/QT/img/tim.jpg");
    if (src.empty()) {
        cout<<"could not load image...\n"<<endl;
        return -1;
    }
    //获取图片的宽、高
    cout<<"w: "<<src.cols<<" h:"<<src.rows<<endl;

    //调整图片大小为250 330
    Mat dst;
    cv::resize(src,dst,Size(250,300));
    imshow("src",src);
    imshow("dst",dst);
    waitKey(0);
}

6.截图 抠图 矩形(Point(x,y) Size(w,h))

int fun6()
{
    Mat src;
    src = imread("D:/QT/img/tim.jpg");
    if (src.empty()) {
        cout<<"could not load image...\n"<<endl;
        return -1;
    }
    cout<<"w: "<<src.cols<<" h:"<<src.rows<<endl;

    //矩形
    Rect r(Point(0,0),Size(320,410));
    //截图 Mat对象对()重载了   小图 = 大图(r)
    Mat dst = src(r);
    imshow("src",src);
    imshow("dst",dst);

    waitKey(0);
}

7.图片中画矩形框


int fun7()
{
    Mat src;
    src = imread("D:/QT/img/Chris.jpg");
    if (src.empty()) {
        cout<<"could not load image...\n"<<endl;
        return -1;
    }
    cout<<"w: "<<src.cols<<" h:"<<src.rows<<endl;
    int x = src.cols/2;
    int y = src.rows/2;
    //矩形
    Rect r(Point(x-100,y-100),Size(200,200));
    //截图 Mat对象对()重载了   小图 = 大图(r)

    //画框 原图 矩形 框的颜色BGR 线宽
    rectangle(src,r,Scalar(255,0,0),3);
    imshow("src",src);
    waitKey(0);
}

二、opencv在QT中的用法

1.QT中导入opencv

INCLUDEPATH += D:/opencv/opencv3.4-install/install/include
INCLUDEPATH += D:/opencv/opencv3.4-install/install/include/opencv
INCLUDEPATH += D:/opencv/opencv3.4-install/install/include/opencv2
LIBS += D:/opencv/opencv3.4-install/install/x86/mingw/lib/libopencv_*.a

#include 
using namespace cv;

2.cv图片转qt图片

QPixmap convertCv2Qt(Mat src);
QPixmap MainWindow::convertCv2Qt(Mat src)
{
    //转换色彩空间
    cvtColor(src,src,CV_BGR2RGB);
    //Mat --> QImage     rgb图像的数据,宽,高,一行的通道数,QImage的格式
    QImage img(src.data,src.cols,src.rows,src.cols*src.channels(),QImage::Format_RGB888);
    //QImage --> QT:QPixmap
    QPixmap pic = QPixmap::fromImage(img);
    return pic;
}

3.图片与控件的大小适应

Mat src = imread("D:/QT/img/1.jpg");
cv::resize(src,src,Size(ui->label->width(),ui->label->height()));//图片大小适应控件大小

QPixmap p = QPixmap::fromImage(img);
ui->label->resize(QSize(p.size()));                              //控件大小适应图片大小

4.定时器事件

#include 
void timerEvent(QTimerEvent *ev);
//周期性执行
void MainWindow::timerEvent(QTimerEvent *ev)
{
    if(ev->timerId() == timeId1)
    {
        ui->label->setNum(++count);
    }
    else if(ev->timerId() == timeId2)
    {
        ui->label_2->setNum(++count2);
    }
}
void MainWindow::on_pushButton_start_clicked()
{
    timeId1 = startTimer(1000);//毫秒为单位,每间隔多长时间执行一次
    timeId2 = startTimer(2000);//又开启一个
}

void MainWindow::on_pushButton_stop_clicked()
{
    killTimer(timeId1);
}

5.矩形外像素点变暗

void MainWindow::timerEvent(QTimerEvent *ev)
{
    Mat src;
    vc>>src;

    if(!src.empty())
    {
        cv::resize(src,src,Size(ui->label_vidio->width(),ui->label_vidio->height()));//图片大小适应控件大小
        Rect r(Point(src.cols/2-100,src.rows/2-100),Size(200,200));
        //画框:  原图 矩形 框的颜色BGR   线宽
        rectangle(src,r,Scalar(255,255,255),2);

        //Mat dst = Mat(src.size(),src.type());//Mat构造函数
        for(int i=0;i<src.cols;i++)
        {
            for(int j=0;j<src.rows;j++)
            {
                //if(i>=src.cols/2-100&&i<=src.cols/2+100&&j>=src.rows/2-100&&j<=src.rows/2+100)
                if(!r.contains(Point(i,j)))  //判断点在矩形内
                {

                    Vec3b v = src.at<Vec3b>(Point(i,j));
                    for(int m=0;m<3;m++)
                    {
                        v[m]=saturate_cast<uchar>(v[m]-50);  //限制
                    }
                    src.at<Vec3b>(Point(i,j)) = v;
                }
            }
        }


        ui->label_vidio->setPixmap(convertCv2Qt(src));
    }
    else
    {
        killTimer(timerId1);
        ui->label_vidio->setText("播放完毕");
    }
}

6.Qt滑动条控制像素点

void MainWindow::on_horizontalSlider_sliderMoved(int position)
{
    if (src.empty())
    {
        qDebug()<<"could not load image...\n";
        return;
    }
    Mat dst = Mat(src.size(),src.type());
    for(int i=0;i<src.cols;i++)
    {
        for(int j=0;j<src.rows;j++)
        {
            Vec3b v = src.at<Vec3b>(Point(i,j));
            for(int m=0;m<3;m++)
            {
                v[m]=saturate_cast<uchar>(v[m]+position);  //限制
            }
            dst.at<Vec3b>(Point(i,j)) = v;
        }
    }
    ui->label->setPixmap(convertCv2Qt(dst));
}

7.sqlite数据库

pro文件:
QT       +=  sql

头文件:
//数据库对象
#include 
//执行sql语句的对象
#include 
//数据库错误
#include 
QSqlDatabase db;
构造:
//1.配置数据库驱动(当前工程使用sqlite)
    db = QSqlDatabase::addDatabase("QSQLITE");

    //2.设置数据库文件名字 student.db文件
    db.setDatabaseName("student.db");

    //3.开启数据库
    //db.open();

    //4.创建表
    createTable();

//创建表
void MainWindow::createTable()
{
    //1.打开数据库
    if(db.open())
    {
        //2.执行sql语句的对象
        QSqlQuery query;
        //准备sql语句
        //字段:1)整形 主键自增id 2)字符串 姓名 3)整形年龄 4)整形的分数
        //主键:表中的一条记录的唯一标识  不可以重复
        //if not exists:避免表的重复创建
        //autoincrement:自增,从1开始 每次加1
        QString sql = "create table if not exists info_student "  //折行自动生成的双引号不要删
                      "(id integer primary key autoincrement,"
                      "name varchar(20),"
                      "age integer,"
                      "score integer);";
        //去数据库执行sql语句
        if(query.exec(sql))
            qDebug()<<"学生信息表创建成功";
        else
            qDebug()<<"学生信息表创建失败";
    }
    else
    {
        qDebug()<<"数据库打开失败";
    }
    db.close();//关闭数据库
}

//插入数据
void MainWindow::insertData()
{
    //获取输入框中的姓名 年龄 分数
    QString name = ui->lineEdit_name->text();
    int age = ui->lineEdit_age->text().toInt();
    int score = ui->lineEdit_score->text().toInt();
    //打开数据库,准备sql 执行sql
    if(db.open())
    {
        //先放入占位符
        QString sql = "INSERT into info_student (name,age,score) values(?,?,?);";

        QSqlQuery query;
        //1.准备sql语句(语句还不完整,没有绑入确切的值)
        query.prepare(sql);
        //2.绑入值
        query.bindValue(0,name);
        query.bindValue(1,age);
        query.bindValue(2,score);
        //3.执行语句
        if(query.exec())
        {
            qDebug()<<"插入成功";
            ui->lineEdit_age->clear();
            ui->lineEdit_name->clear();
            ui->lineEdit_score->clear();
        }
        else
            qDebug()<<"插入失败";
    }
    else
        qDebug()<<"数据库打开失败";
    db.close();
}

//查询提取数据
void MainWindow::selectData()
{
    ui->textBrowser->clear();
    //打开数据库,准备sql 执行sql
    if(db.open())
    {
        QString sql = "SELECT * FROM info_student where score between 70 and 90;";
        QSqlQuery query;
        query.exec(sql);
        //提取和显示查询后的结果
        //query.next()是否还有可显示的数据
        while(query.next())
        {
            //一行数据,按照字段提取数据值 id name age score
            int id = query.value(0).toInt();
            QString name = query.value(1).toString();
            int age = query.value(2).toInt();
            int score = query.value(3).toInt();

            //显示,拼接字符串
            QString str = QString("id:%1  name:%2  age:%3  score:%4").arg(id).arg(name).arg(age).arg(score);
            ui->textBrowser->append(str);
        }
    }
    else
        qDebug()<<"数据库打开失败";
    db.close();
}

8.级联分类器

头文件:
CascadeClassifier classifier;
vector<Rect> findFaces;//存储找到的人脸矩形

构造:
classifier = CascadeClassifier("D:/QT/opencv3.4-install/install/etc/haarcascades/haarcascade_frontalface_alt2.xml");//数据模型的路径

定时器事件:
cv::resize(src,src,Size(ui->label_vidio->width(),ui->label_vidio->height()));//图片大小适应控件大小
flip(src,src,1);//y轴翻转
Mat gray;
cvtColor(src,gray,CV_BGR2GRAY);//转灰度
classifier.detectMultiScale(gray,findFaces);//把gray灰度图中找到的人脸矩形保存在findFaces容器中
for(int i=0;i<findFaces.size();i++)
{
      rectangle(src,findFaces[i],Scalar(0,0,255),2);
}
ui->label_vidio->setPixmap(convertCv2Qt(src));

9.人脸识别器

#include 
using namespace cv::face;
头文件:
vector<Mat> studyFaces;  //要学习的人脸容器
vector<int> studyLables; //标签
//人脸识别器对象
Ptr<FaceRecognizer> recognizer;

构造:
    //人脸识别器初始化
    QFile file("face.xml");//build文件夹下
    //判断这个模型文件是否存在
    if(file.exists())//开机的时候从芯片里读出之前的数据
    {
        //加载旧数据(之前录入过的)
        recognizer = FaceRecognizer::load<LBPHFaceRecognizer>("face.xml");
    }else
    {
        //创建新的人脸识别器对象
        recognizer = LBPHFaceRecognizer::create();
    }

机器学习:
//录入 机器学习过程:1.存图片的容器  2.存储对应相同数量的标签的容器
void MainWindow::on_pushButton_study_clicked()
{
    //1.准备想录入的人员的图片
    for(int i=0;i<9;i++)
    {
        QString path = QString("D:/QT/img/study/s%1.jpg").arg(i);
        Mat face = imread(path.toStdString());
        //统一操作:1.转灰度 2.统一大小100*100
        cvtColor(face,face,CV_BGR2GRAY);
        cv::resize(face,face,Size(100,100));
        studyFaces.push_back(face);
    }
    //2.每张图片 配一个整形的标签
    for(int i=0;i<9;i++)
    {
        studyLables.push_back(i);
    }
    //3.更新数据模型
    recognizer->update(studyFaces,studyLables);
    //4.保存数据模型
    recognizer->save("face.xml");
}

识别人脸:
void MainWindow::on_pushButton__clicked()
{
    //1.通过级联分类器 找到人
    Mat src = imread("D:/QT/img/head2.jpg");
    CascadeClassifier classifier = CascadeClassifier("D:/QT/opencv3.4-install/install/etc/haarcascades/haarcascade_frontalface_alt2.xml");
    vector<Rect> findFaces;
    Mat gray;
    cvtColor(src,gray,CV_BGR2GRAY);
    classifier.detectMultiScale(gray,findFaces);
    qDebug()<<"找到:"<<findFaces.size();

    //2.找到的人去和模型文件中的人去对比
    double confidence = 0;
    int lable = 0;
    for(int i=0;i<findFaces.size();i++)
    {
        //把矩形的范围抠图下来
        Mat face = src(findFaces[i]);
        //imshow("face",face);
        cvtColor(face,face,CV_BGR2GRAY);
        cv::resize(face,face,Size(100,100));

        //3.预测完成后,返回 1.可信度(越小越准) 2.标签
        recognizer->predict(face,lable,confidence);
        qDebug()<<"confi:"<<confidence<<"lable:"<<lable;
    }

}

10.自定义定时器

头文件:
#include 
void slot_studyTimer();
QTimer studyTimer;
构造:
connect(&studyTimer,SIGNAL(timeout()),this,SLOT(slot_studyTimer()));
实现:
studyTimer.start(1000);
void MainWindow::slot_studyTimer()
{
    ui->label_2->setNum(++count_study);
}

你可能感兴趣的