【PHYTEC开发板试用体验】phyBOARD-Pollux i.MX 8M Plus 主机开发程序并尝试开发板调试2
之前测试搭建好了软硬件开发环境后,我开始了项目开发尝试,首先是调试了虚拟机Ubuntu的摄像头获取,然后利用QT程序调用摄像头拍照,并尝试在开发板上直接调试摄像头调用程序,
第二个小目标是在主机上安装OpenCV,并利用OpenCV调用摄像头,然后是通过QT程序通过OpenCV实现调用摄像头,并且通过QT直接在开发板上调式这个OpenCV调用摄像头的应用
第三个大目标是将程序移植到开发板并在开发板上测试,这一步由于我之前没有完全解决opt下root目录空间的问题,未能完全实现,
并且在调试中发现,我的主机和开发板用了不同的摄像头出现了我还未能解决的问题。目前还在尝试中。
本次项目测试在开发板上没有完全实现,主要是调试的root空间百分百被使用,把程序直接复制到开发板后由于摄像头问题未能实现,
但是,整个开发过程以及遇到的问题还是能起到一些避坑帮助的。
接下来,我将测试开发过程简单介绍,并把一些问题记录出来,
我在上一篇中,测试好了主机的开发环境,因为开发板提供的系统已经完成了一些配置,只需要稍微测试程序调试即可,但是一定要注意在开发调试的时候,注意使用开发板root空间,不要将大的程序文件拷贝过去,会导致开发板端调试报错的。
vmbox使用摄像头的时候,需要在设置里面USB添加一个摄像头筛选器,笔记本开发时候建议使用外接USB摄像头,不建议使用笔记本自带摄像头开发测试,这会导致在开发板上测试使用摄像头可能无法成功的问题。
另外,vmbox虚拟机需要安装vbox官网的对应版本的usb扩展插件,这个很重要,下载好插件后需要在vbox启动后的上方菜单设备设置中添加设备控制增强插件,并且,在选择USB控制器的时候要选择2.0 和3.0
两个选项轮流尝试,并添加USB摄像头,有的usb摄像头虽然是2。0但USB选择器需要选3.0才能被vbox虚拟机中的Ubuntu系统识别。
QT程序控制摄像头开发程序在网上都有,比较简单,创建新项目的时候注意选择正确项目属性如图,一般Ubuntu系统设别了摄像头,
QT代码问题不大,在主机桌面测试后,可以选择在ARM开发板上测试QT启用摄像头,你需要吧虚拟机识别的USB摄像头插到开发板上进行测试,如果你使用的是笔记本自带的摄像头,这个时候多多少少会有些问题,另外,最好先关虚拟机再插拔摄像头,我的系统奔溃了好几次,耽误了很多时间用于恢复虚拟机系统,很不稳定。
test.pro
QT += core gui
QT += multimedia
QT += multimediawidgets
greaterThan(QT_MAJOR_VERSION,
4): QT += widgets
TARGET
= QCameratest
TEMPLATE
= app
SOURCES
+= main.cpp\
widget.cpp
HEADERS += widget.h
FORMS += widget.ui
.h
#ifndef
WIDGET_H
#define
WIDGET_H
#include
class
QCamera;
class
QCameraViewfinder;
class
QCameraImageCapture;
class
Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = 0);
~Widget();
private
slots:
void exitBtnResponded();
void cameraImageCaptured(int,QImage);
private:
QCamera* m_pCamera;
QCameraViewfinder* m_pViewfinder;
QCameraImageCapture* m_pImageCapture;
};
#endif
// WIDGET_H
main.cpp
#include
"widget.h"
#include
int
main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
Widget.cpp
#include
"widget.h"
#include
#include
#include
#include
#include
#include
#include
Widget::Widget(QWidget
*parent)
: QWidget(parent)
{
setWindowTitle("QCamera");
m_pCamera = new QCamera(this);
m_pViewfinder = new
QCameraViewfinder(this);
m_pImageCapture = new
QCameraImageCapture(m_pCamera);
QPushButton* button1 = new
QPushButton("Capture");
QPushButton* button2 = new
QPushButton("Exit");
QVBoxLayout *mainLayout = new
QVBoxLayout(this);
mainLayout->addWidget(m_pViewfinder)
mainLayout->addWidget(button1)
mainLayout->addWidget(button2)
connect(button1, SIGNAL(clicked()),
m_pImageCapture, SLOT(capture()));
connect(button2, SIGNAL(clicked()), this,
SLOT(exitBtnResponded()));
connect(m_pImageCapture,
SIGNAL(imageCaptured(int,QImage)), this,
SLOT(cameraImageCaptured(int,QImage)));
m_pImageCapture->setCaptureDestination(QCameraImageCapture::CaptureToFile);
m_pCamera->setCaptureMode(QCamera::CaptureStillImage);
m_pCamera->setViewfinder(m_pViewfinder);
m_pCamera->start();
}
Widget::~Widget()
{
delete
m_pCamera;
delete
m_pViewfinder;
delete m_pImageCapture;
}
void
Widget::exitBtnResponded()
{
m_pCamera->stop();
close();
}
void
Widget::cameraImageCaptured(int, QImage image)
{
QString savepath =
QFileDialog::getSaveFileName(this,"Save
Capture","Capture","Image png(.png);;Image
jpg(.jpg);;Image bmp(*.bmp)");
if(!savepath.isEmpty()){
image.save(savepath);
}
第二部分是安装OpenCV在Ubuntu上,并使用opencv调用摄像头,
OpenCV安装过程会不断更新对应的库, 以及更新cmake
相关,需要你给虚拟机再添加一个桥接到无线网卡的虚拟机网卡,如果,你使用的是网线与开发板调试的话。这样就不需要来回切换了。
CSDN
上 有个叫不高兴的
Ubuntu下QT 调用OpenCV使用摄像头帖子中对于OpenCV安装非常详细,可以参考,之后的具体开发就参考思路即可。
其中,OpenCV安装过程中要不断注意报错提示,安装网络上的步骤基本问题不大,少什么就装什么,网络畅通的话也就个把小时。
OpenCV安装之后,有一件重要的事情就是升级QT,直接安装QT5并设置环境变量,官方的Ubuntu 虚拟机中是QT4 ,这个开发的时候需要QT5,我使用的是OpenCV3, 已经很古老了,但都需要QT5支持。
QT调用OpenCV开启摄像头的代码放在文章最后,
我在实现qt调用OpenCV设别人脸的时候,Ubuntu崩溃了,开发板之前的root空间也又成了百分百占用了,我之前已经重新扩展的etx4根空间了,但我发现我需要重新挂载一个新建的root空间,
另外就是,虚拟机以及硬盘所在
空间一定要留够25G以上的空间,因为在安装opencv相关时候,虚拟内存和虚拟空间增长速度很快,盘满了虚拟机Ubuntu系统容易崩溃导致重装环境,删除虚拟机重新连接虚拟硬盘无法继续开发和测试,
目前,我正在解决重装环境,等解决完,下一期我将着重在开发板上测试项目程序,实现最终项目。
这是找到一个比较好用的OpenCV编辑照片和调用摄像头的代码
optest.cpp
#include
<opencv2/highgui.hpp>
#include
<opencv2/opencv.hpp>
using
namespace cv;
using
namespace std;
int
main(int argc, char** argv)
{
CvPoint center;
double scale = -3;
IplImage* image =
cvLoadImage("lena.jpg");
argc == 2? cvLoadImage(argv[1]) : 0;
cvShowImage("Image", image);
if (!image) return -1; center = cvPoint(image->width / 2,
image->height / 2);
for (int i = 0;iheight;i++)
for (int j = 0;j<image->width;j++) {
double dx = (double)(j - center.x) /
center.x;
double dy = (double)(i - center.y) /
center.y;
double weight = exp((dx*dx +
dy*dy)*scale);
uchar* ptr = &CV_IMAGE_ELEM(image,
uchar, i, j * 3);
ptr[0] = cvRound(ptr[0] * weight);
ptr[1] = cvRound(ptr[1] * weight);
ptr[2] = cvRound(ptr[2] * weight);
}
Mat src;Mat dst;
src = cvarrToMat(image);
cv::imwrite("test.png", src);
cvNamedWindow("test",1); imshow("test",
src);
cvWaitKey();
return
0;
}
g++ test.cpp -o test pkg-config --cflags--libs opencv
摄像头使用代码
#include
#include
<opencv2/opencv.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
using
namespace cv;
using
namespace std;
int
main()
{
//打开电脑摄像头
VideoCapture cap(0);
if (!cap.isOpened())
{
cout << "error" <<
endl;
waitKey(0);
return 0;
}
//获得cap的分辨率
int w =
static_cast(cap.get(CV_CAP_PROP_FRAME_WIDTH));
int h =
static_cast(cap.get(CV_CAP_PROP_FRAME_HEIGHT));
Size videoSize(w, h);
VideoWriter
writer("RecordVideo.avi", CV_FOURCC('M', 'J', 'P', 'G'), 25,
videoSize);
Mat frame;
int key;//记录键盘按键
char startOrStop = 1;//0 开始录制视频; 1 结束录制视频
char flag = 0;//正在录制标志 0-不在录制; 1-正在录制
while (1)
{
cap >> frame;
key = waitKey(100);
if (key == 32)//按下空格开始录制、暂停录制 可以来回切换
{
startOrStop = 1 - startOrStop;
if (startOrStop == 0)
{
flag = 1;
}
}
if (key == 27)//按下ESC退出整个程序,保存视频文件到磁盘
{
break;
}
if (startOrStop == 0 && flag==1)
{
writer << frame;
cout << "recording"
<< endl;
}
else if (startOrStop == 1)
{
flag = 0;
cout << "end recording"
<< endl;
}
imshow("picture", frame);
}
cap.release();
writer.release();
destroyAllWindows();
return 0;
}