您的位置:首页 > 编程语言 > Qt开发

linux+Qt+Opencv实现采集摄像头采集,截图,边缘检测,霍夫变换

2017-01-14 20:25 1016 查看
最近在做一个机器视觉货物分拣系统,小白一个,从头开始学起。希望写博客可以督促自己加快步伐,完成任务!

系统:ubantu14.04

opencv版本 :3.0.0

Qt版本:5.7

程序功能:实现摄像头视频的采集,截图,边缘检测和霍夫直线检测。

运行效果:



原始截图



生成的灰度图



边缘检测和霍夫变换直线检测后的图像



首先你得先装好软件和库才行。网上教程很多,这个就不多说了。

话不多说,直接上程序:

1,新建一个qt wiget工程;

2,在.pro文件中最后加入opencv库文件

INCLUDEPATH += .
INCLUDEPATH += /usr/local/include
INCLUDEPATH += /usr/local/include/opencv
INCLUDEPATH += /usr/local/include/opencv2
INCLUDEPATH += /usr/local/include/opencv2/core
INCLUDEPATH += /usr/local/include/opencv2/highgui
INCLUDEPATH += /usr/local/include/opencv2/imgproc
INCLUDEPATH += /usr/local/include/opencv2/flann
INCLUDEPATH += /usr/local/include/opencv2/photo
INCLUDEPATH += /usr/local/include/opencv2/video
INCLUDEPATH += /usr/local/include/opencv2/features2d
INCLUDEPATH += /usr/local/include/opencv2/objdetect
INCLUDEPATH += /usr/local/include/opencv2/calib3d
INCLUDEPATH += /usr/local/include/opencv2/ml
INCLUDEPATH += /usr/local/include/opencv2/contrib
LIBS += `pkg-config opencv --cflags --libs`


3,在头文件中写入如下代码:

其中private slots:下的函数是在Ui界面添加按钮的槽函数后自动生成的

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <opencv2/opencv.hpp>
#include <iostream>
#include "highgui.h"
using namespace cv;
using namespace std;

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
Q_OBJECT

public:
explicit Widget(QWidget *parent = 0);
~Widget();

private slots:
void on_Cut_clicked();

void on_Open_clicked();

void on_Quit_clicked();

private:
Ui::Widget *ui;
Mat edges;
Mat mid_edges;
Mat frame;
Mat Gray_Frame;
Mat Canny_Frame;

QImage Img;
QImage Scaled_Img;
QImage Cut_Img;
QImage Gray_Img;
QImage  Scaled_Gray_Img;
QImage Canny_Img;
QImage Scaled_Canny_Img;
vector<Vec2f> lines;//定义一个矢量结构lines用于存放得到的线段矢量集合

};

#endif // WIDGET_H


4,在widget.c文件下面加入以下代码:

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
}

Widget::~Widget()
{
delete ui;
}

void Widget::on_Cut_clicked()
{
Cut_Img =Scaled_Img;
QLabel  *Img_label =new QLabel(this);
Img_label->setGeometry(360,20,300,200);
Img_label->setPixmap(QPixmap::fromImage(Cut_Img));
Img_label->resize( Img_label->pixmap()->size());
Img_label->show();

cvtColor(frame,Gray_Frame,CV_BGR2GRAY);
//anny算子边缘检测
Canny(Gray_Frame,Canny_Frame,75,80,3);
// 霍夫变换直线检测算法---8bit pic,setp,angel,length_limit
HoughLines(Canny_Frame, lines, 3, CV_PI/20, 70, 0, 0 );
//依次在图中绘制出每条线
for( size_t i = 0; i < lines.size(); i++ )

4000
{
float rho = lines[i][0], theta = lines[i][1];
Point pt1, pt2;
double a = cos(theta), b = sin(theta);
double x0 = a*rho, y0 = b*rho;
pt1.x = cvRound(x0 + 10000*(-b));
pt1.y = cvRound(y0 + 10000*(a));
pt2.x = cvRound(x0 - 10000*(-b));
pt2.y = cvRound(y0 - 10000*(a));
line( Canny_Frame, pt1, pt2, Scalar(55,100,195), 1, CV_AA);
}

/*
//灰度图显示
Gray_Img = QImage((const unsigned char*)(Gray_Frame.data), Gray_Frame.cols, Gray_Frame.rows, QImage::Format_Grayscale8);
Scaled_Gray_Img=  Gray_Img.scaled(Gray_Img.width()/2,Gray_Img.height()/2,Qt::KeepAspectRatio) ;
QLabel  *Gray_Img_label =new QLabel(this);
Gray_Img_label->setGeometry(20,260,300,200);
Gray_Img_label->setPixmap(QPixmap::fromImage(Scaled_Gray_Img));
Gray_Img_label->resize( Gray_Img_label->pixmap()->size());
Gray_Img_label->show();
*/

Canny_Img = QImage((const unsigned char*)(Canny_Frame.data), Canny_Frame.cols, Canny_Frame.rows, QImage::Format_Grayscale8);
Scaled_Canny_Img=  Canny_Img.scaled(Canny_Img.width()/2,Canny_Img.height()/2,Qt::KeepAspectRatio) ;
QLabel  *Gray_Img_label =new QLabel(this);
Gray_Img_label->setGeometry(20,280,300,200);
Gray_Img_label->setPixmap(QPixmap::fromImage( Scaled_Canny_Img));
Gray_Img_label->resize( Gray_Img_label->pixmap()->size());
Gray_Img_label->show();

imwrite( "/home/zy/qt_pro/frame.jpg", frame );
imwrite( "/home/zy/qt_pro/Gray_Image.jpg", Gray_Frame );
imwrite( "/home/zy/qt_pro/Canny_Frame.jpg", Canny_Frame );
}

void Widget::on_Open_clicked()
{
VideoCapture cap(-1);
//设置视频格式
cap.set(CV_CAP_PROP_FRAME_WIDTH , 640);
cap.set(CV_CAP_PROP_FRAME_HEIGHT , 480);
if(!cap.isOpened())
{
cerr <<"can not open a camera!"<<endl;
}
while(1)
{
cap>>frame;
//转换格式后在Qt中显示
cvtColor(frame,edges,CV_RGB2RGBA);
Img = QImage((const unsigned char*)(edges.data), edges.cols, edges.rows, QImage::Format_RGB32);
//等比缩放图像以用来显示
Scaled_Img =  Img.scaled(Img.width()/2,Img.height()/2,Qt::KeepAspectRatio) ;
//建立显示图像的TextLabel并且显示
QLabel  *Video_label =new QLabel(this);
Video_label->setGeometry(20,20,300,400);
Video_label->setPixmap(QPixmap::fromImage( Scaled_Img));
Video_label->resize( Video_label->pixmap()->size());
Video_label->show();
cvWaitKey(500);
}
}

void Widget::on_Quit_clicked()
{
VideoCapture release();
this->close();
}


5程序还有一点小问题

(1)每次QUIT后,进程没有杀死,等研究出来了再往上贴.

(2)有时候程序很崩溃。报错 celect timeout查了好多资料至今无法解决

有哪位大神知道至两个问题怎么弄?求指导……不胜感激
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息