从零开始的嵌入式图像图像处理(PI+QT+OpenCV)实战演练
1综述
2环境架设
3两个例子
4程序框架
5编译使用最新opencv
6综合实验
7拾遗
为了方便后期图像处理相关操作运用,将前面的程序封装成框架以复用
一、打开PI自带的摄像头
sudo raspi -config
移动到“5”选项,按下回车键,选择camera。
选择“Enable”然后回车。
再选择“Yes”,回车后树莓派会重新启动。
通过raspi-config工具更新了操作并使能摄像头之后,它会告诉树莓派摄像头已经连接成功,并增加了两个命令行工具以供用户使用摄像头。
raspistill
raspivid
如果是usb摄像c,现在已经可以直接使用。但是如果想集成度搞一些,直接使用csi的摄像头,需要这样做:
cd
/etc
/modules
-load.d
/
sudo vim modules.conf
添加
bcm2835 -v4l2
需要重启。
二、编写程序,获取并显示实时视频
主要程序代码:
#
ifndef CLICKEDLABEL_H
#
define CLICKEDLABEL_H
#
include
<QWidget
>
#
include
<QLabel
>
class ClickedLabel
:
public QLabel
{
Q_OBJECT
public
:
ClickedLabel(QWidget
*parent
=
0)
: QLabel(parent){}
~ClickedLabel() {}
signals
:
void clicked(ClickedLabel
* click);
// ????
protected
:
void mouseReleaseEvent(QMouseEvent
*);
// ?????????
};
#
endif
// CLICKEDLABEL_H
#
ifndef MAINWINDOW_H
#
define MAINWINDOW_H
#
include
<QMainWindow
>
//新添加
#
include
<opencv2
/core
/core.hpp
>
#
include
<opencv2
/highgui
/highgui.hpp
>
#
include
<opencv2
/imgproc
/imgproc.hpp
>
#
include
<QFileDialog
>
#
include
<QImage
>
#
include
<QTimer
>
// 时间触发
#
include
"clickedlabel.h"
using
namespace cv;
//helper函数
QPixmap Mat2QImage(Mat src);
namespace Ui {
class MainWindow;
}
class MainWindow
:
public QMainWindow
{
Q_OBJECT
public
:
explicit MainWindow(QWidget
*parent
=
0);
~MainWindow();
private slots
:
void on_MainWindow_iconSizeChanged(
const QSize
&iconSize);
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void on_pushButton_3_clicked();
void on_pushButton_4_clicked();
void readFarme();
// 核心函数
private
:
Ui
:
:MainWindow
*ui;
QTimer
*timer;
QImage
*imag;
VideoCapture
*videocapture;
Mat matFrame;
bool bMethod;
//是否采用图像处理算法
ClickedLabel
* clickLabel;
ClickedLabel
* clickLabel2;
};
#
endif
// MAINWINDOW_H
#
include
"clickedlabel.h"
void ClickedLabel
:
:mouseReleaseEvent(QMouseEvent
*)
{
emit clicked(
this);
}
#
include
"mainwindow.h"
#
include
<QApplication
>
int main(
int argc,
char
*argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
#
include
"mainwindow.h"
#
include
"ui_mainwindow.h"
using
namespace cv;
Mat src;
Mat gray;
Mat tmp;
Mat dst;
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();
clickLabel
=
new ClickedLabel(
this);
clickLabel
-
>setGeometry(
0,
0,
400,
400);
connect(clickLabel,SIGNAL(clicked(ClickedLabel
*)),
this,SLOT(on_pushButton_3_clicked()));
clickLabel2
=
new ClickedLabel(
this);
clickLabel2
-
>setGeometry(
400,
0,
400,
400);
connect(clickLabel2,SIGNAL(clicked(ClickedLabel
*)),
this,SLOT(on_pushButton_2_clicked()));
}
MainWindow
:
:
~MainWindow()
{
delete ui;
}
void MainWindow
:
:on_MainWindow_iconSizeChanged(
const QSize
&iconSize)
{
}
//Open camera
void MainWindow
:
:on_pushButton_clicked()
{
videocapture
=
new VideoCapture(
0);
timer
-
>start(
33);
}
void MainWindow
:
:readFarme()
{
videocapture
-
>read(matFrame);
if(bMethod)
{
cvtColor(matFrame,tmp,COLOR_BGR2GRAY);
Canny(tmp,dst,
30,
255);
}
else
{
dst
= matFrame.clone();
}
QPixmap qpixmap
= Mat2QImage(dst);
clickLabel
-
>setPixmap(qpixmap);
}
//capture
void MainWindow
:
:on_pushButton_2_clicked()
{
QPixmap qpixmap
= Mat2QImage(dst);
//ui->label_2->setPixmap(qpixmap);
clickLabel2
-
>setPixmap(qpixmap);
}
//action
void MainWindow
:
:on_pushButton_3_clicked()
{
bMethod
=
!bMethod;
}
//exit
void MainWindow
:
:on_pushButton_4_clicked()
{
timer
-
>stop();
// ???????
videocapture
-
>release();
}
//helper??//
QPixmap Mat2QImage(Mat src)
{
QImage img;
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;
}
三、程序要点和结果展示
1、直接调用OpenCV的摄像头模块,实践证明在Linux上面很有效;
2、为了能够让label可以被点击,进行了一个类的重构工作;
至此,程序框架搭建完成,可以方便复用,完整代码在链接为: