开发者社区> 禾路> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

(6综合实验)从零开始的嵌入式图像图像处理(PI+QT+OpenCV)实战演练

简介: 从零开始的嵌入式图像图像处理(PI+QT+OpenCV)实战演练 1综述http://www.cnblogs.com/jsxyhelu/p/7907241.html2环境架设http://www.cnblogs.
+关注继续查看
最后,我们必须完成一个综合实验,来验证前面所做的一切工作。为了达到这个目的,将实验设定为:使用实时根据图像的特征(包括ORB/SHIFT/SURF/BRISK),进行特征比对。这样,就验证了opencv类库的编译(因为使用了contrib库,所以必须自己编译)、基本程序框架的运行(涉及摄像头操作)。并且我们是使用虚拟机(PC版本的PI系统)编译测试,而后移植到PI上面去的。
配置文件:
#
# Project created by QtCreator 2017-11-29T07:39:32
#
#-------------------------------------------------

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = GOQTTemplate2
TEMPLATE = app


INCLUDEPATH += /usr/local/include/opencv \
                /usr/local/include/opencv2

LIBS += /usr/local/lib/libopencv_world.so

SOURCES += main.cpp\
        mainwindow.cpp \
    clickedlabel.cpp

HEADERS  += mainwindow.h \
    clickedlabel.h

FORMS    += mainwindow.ui
主程序文件,简单说明流程:程序一开始就打开默认的摄像头,而后截获显示摄像头获取的数据。当有点击图片的操作的时候,保存当前图片作为模板,而后开始特征点匹配,并且显示匹配结果。有一个按钮能够切换不同的特征点算法:
//by jsxyhelu 2017/12/6
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMouseEvent>
//全局变量
Mat src;
Mat gray;
Mat tmp;
Mat dst;
Mat matMatch;//template
double m_lastTime;//time
Mat grayLeft;
Mat grayRight;
Mat descriptorsLeft;
std::vector<KeyPoint> keypointsLeft;
Mat descriptorsRight;
std::vector<KeyPoint> keypointsRight;
std::vector< DMatch > matches;
std::vector< DMatch > good_matches;
Mat img_matches;
int imethod;//0-ORB 1-SIFT 2-SURF 3-BRISK
using namespace cv;
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    timer   = new QTimer(this);
    imag    = new QImage();         // 初始化
    connect(timer, SIGNAL(timeout()), this, SLOT(readFarme()));  // 时间到,读取当前摄像头信息
    bMethod = false;//是否使用算法
    on_pushButton_clicked();//main process
    //take a picture
    clickLabel = new ClickedLabel(this);
    clickLabel->setGeometry(0,0,800,400);
    connect(clickLabel,SIGNAL(clicked(ClickedLabel*)),this,SLOT(on_pushButton_3_clicked()));
    imethod = 0;//ORB
    setWindowState(Qt::WindowMaximized);//max
}
MainWindow::~MainWindow()
{
    delete ui;
}
////////////////////////////////////事件驱动///////////////////////////////////////////////////////
//打开摄像头
void MainWindow::on_pushButton_clicked()
{
    //打开摄像头,从摄像头中获取视频
    videocapture  = new VideoCapture(0);
    // 开始计时,超时则发出timeout()信号
    timer->start(33);
}
//main process 读取下一Frame图像 when timeout()
void MainWindow::readFarme()
{
    // 从摄像头中抓取并返回每一帧
    videocapture->read(matFrame);
    src = matFrame.clone();
    m_lastTime = (double)getTickCount();
    tmp = matFrame.clone();
    //final
    cv::resize(tmp,tmp,Size(200,200));
    dst = Mat(Size(tmp.cols*2,tmp.rows),tmp.type(),Scalar(255));
    tmp.copyTo(dst(cv::Rect(0,0,200,200)));
    //生成特征点算法及其匹配方法
    Ptr<Feature2D>  extractor;
    BFMatcher matcher;
    switch (imethod)
           {
                    case 1: //"SIFT"
                        extractor= SIFT::create();
                        matcher = BFMatcher(NORM_L2);
                        break;
                    case 2: //"SURF"
                        extractor= SURF::create();
                        matcher = BFMatcher(NORM_L2);
                        break;
                    case 3: //"BRISK"
                        extractor = BRISK::create();
                        matcher = BFMatcher(NORM_HAMMING);
                        break;
                    case 0: //"ORB"
                        extractor= ORB::create();
                        matcher = BFMatcher(NORM_HAMMING);
                        break;
             }

    if(matMatch.rows > 0)
    {
        //利用现有数据结构,对比对结构进行筛选
        double max_dist = 0; double min_dist = 100;
         //action
        cv::resize(matMatch,matMatch,Size(200,200));
        //gray
        cvtColor(tmp,grayLeft,COLOR_BGR2GRAY);
        cvtColor(matMatch,grayRight,COLOR_BGR2GRAY);
        //寻找到特征点
        extractor->detectAndCompute(grayLeft,Mat(),keypointsLeft,descriptorsLeft);
        extractor->detectAndCompute(grayRight,Mat(),keypointsRight,descriptorsRight);
        matcher.match( descriptorsLeft, descriptorsRight, matches );
        //对现有距离进行排序
        for( int i = 0; i < descriptorsLeft.rows; i++ )
        {
            double dist = matches[i].distance;
            if( dist < min_dist ) min_dist = dist;
            if( dist > max_dist ) max_dist = dist;
        }
        for( int i = 0; i < descriptorsLeft.rows; i++ )
        {
            if( matches[i].distance <= max(2*min_dist, 0.02) )
            {
                good_matches.push_back( matches[i]);
            }
        }
         drawMatches( tmp, keypointsLeft, matMatch, keypointsRight, good_matches, dst );
         //clear
         good_matches.clear();
    }
    cv::resize(dst,dst,Size(800,400));
    switch (imethod)
    {
    case 0:
    putText(dst,"METHOD:ORB",Point(10,350),CV_FONT_HERSHEY_DUPLEX,1.0f,Scalar(0,0,255));
    break;
    case 1:
     putText(dst,"METHOD:SIFT",Point(10,350),CV_FONT_HERSHEY_DUPLEX,1.0f,Scalar(0,0,255));
    break;
    case 2:
     putText(dst,"METHOD:SURF",Point(10,350),CV_FONT_HERSHEY_DUPLEX,1.0f,Scalar(0,0,255));
    break;
    case 3:
     putText(dst,"METHOD:BRISK",Point(10,350),CV_FONT_HERSHEY_DUPLEX,1.0f,Scalar(0,0,255));
    break;
    }
    // 格式转换
    QPixmap qpixmap = Mat2QImage(dst);
    // 将图片显示到label上
    clickLabel->setPixmap(qpixmap);
    m_lastTime = (double)getTickCount();
}
//method
void MainWindow::on_pushButton_2_clicked()
{   
    if(imethod == 4)
    {
        imethod = 1;
    }else
    {
        imethod += 1;
    }
}
//action
void MainWindow::on_pushButton_3_clicked()
{
      matMatch = src.clone();
}

//exit
void MainWindow::on_pushButton_4_clicked()
{
    timer->stop();         // 停止读取数据。
    videocapture->release();
    //exit
    QApplication* app;
    app->exit(0);
}
//////////////////////////helper函数//////////////////////////////////////////////////
//格式转换
QPixmap Mat2QImage(Mat src)
{
    QImage img;
    //根据QT的显示方法进行转换
    if(src.channels() == 3)
    {
        cvtColor( src, tmp, CV_BGR2RGB );
        img = QImage( (const unsigned char*)(tmp.data), tmp.cols, tmp.rows, QImage::Format_RGB888 );
    }
    else
    {
        img = QImage( (const unsigned char*)(src.data), src.cols, src.rows, QImage::Format_Indexed8 );
    }
    QPixmap qimg = QPixmap::fromImage(img) ;
    return qimg;
}
 
 





附件列表

 

目前方向:图像拼接融合、图像识别 联系方式:jsxyhelu@foxmail.com

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
OpenCV 图像处理:常用绘图函数
OpenCV 图像处理:常用绘图函数
0 0
Opencv 图像处理:图像通道、直方图与色彩空间
Opencv 图像处理:图像通道、直方图与色彩空间
0 0
Opencv 图像处理:图像基础操作与灰度转化
Opencv 图像处理:图像基础操作与灰度转化
0 0
Opencv 图像处理:数字图像的必会知识
Opencv 图像处理:数字图像的必会知识
0 0
OpenCV的自我修养(三)——图像处理(上)
本文主要讲述了如何使用OpenCV-Python来对图像进行一些简单的处理
0 0
项目实战:Qt+OpenCV图像处理与识别算法平台(持续更新,当前v1.7.0)
项目实战:Qt+OpenCV图像处理与识别算法平台(持续更新,当前v1.7.0)
0 0
Python opencv图像处理基础总结(七) 基于分水岭算法的图像分割
任何一副灰度图像都可以被看成拓扑平面,灰度值高的区域可以被看成是山峰,灰度值低的区域可以被看成是山谷。我们向每一个山谷中灌不同颜色的水。随着水的位的升高,不同山谷的水就会相遇汇合,为了防止不同山谷的水汇合,我们需要在水汇合的地方构建起堤坝。不停地灌水,不停地构建堤坝知道所有的山峰都被水淹没。我们构建好的堤坝就是对图像的分割
0 0
Python opencv图像处理基础总结(六) 直线检测 圆检测 轮廓发现
我还有改变的可能性 一想起这一点 我就心潮澎湃
0 0
+关注
禾路
图像处理工程师,专注图像处理多年,长期奋斗在图像增强、识别一线。实战经验丰富,研究开发的连铸体拼接算法、人脸美化算法、红外线血管增强识别系统、中药识别系统、石材大板识别系统等均已投入使用。对opencv有着深入理解和解析,以jsxyhelu账号参与OpenCV项目。
文章
问答
文章排行榜
最热
最新
相关电子书
更多
《视觉计算开发者系列手册》
立即下载
魔搭・平台工程框架介绍
立即下载
从零到一:IOS平台TensorFlow入门及应用详解
立即下载