amin这个例子,使用了比较复杂高阶的qml技巧,但是也有局限性。下面分3个部分,分别是界面部分,算法部分和扩展部分,简单地对这个问题进行理解。
由衷感谢:http://amin-ahmadi.com/quick-camera-cv/ 给本程序很多借鉴
Text
{
id : helpText
wrapMode : Text.Wrap
anchors.left : parent.left
anchors.right : parent.right
text : "由衷感谢:<a href=\"http://amin-ahmadi.com/quick-camera-cv/\">http://amin-ahmadi.com/quick-camera-cv</a>" +
"给本程序很多借鉴" +
"<br>" +
"<br>" +
"作者博客:" +
"<br>" +
"<a href=\"jsxyhelu.cnblogs.com\">jsxyhelu.cnblogs.com</a>" +
"<br>" +
"<a href=\"jsxyhelu.cnblogs.com\"><img src=\"http://images2015.cnblogs.com/blog/508489/201607/508489-20160731065441684-483128601.png\" alt=\"欢迎访问!\"></a>" +
"<br>" +
"<b>版权</b>" +
"本程序使用 <a href=\"http://qt.io/\">Qt Framework</a> 作为GUI" +
"<br>" +
"同时使用 <a href=\"http://opencv.org/\">OpenCV</a> 做图像处理算法." +
"<br>" +
"程序采用ICO来自<a href=\"http://flaticon.com/\">Flat Icon</a>."
onLinkActivated :
{
Qt.openUrlExternally(link);
}
}
//调用qcamera进行图像采集
void QCvImageProcessor : :setCamera(QVariant v)
{
QObject *o = qvariant_cast <QObject * >(v);
camera = qvariant_cast <QCamera * >(o - >property( "mediaObject"));
camera - >setCaptureMode(QCamera : :CaptureStillImage);
imageCapture = new QCameraImageCapture(camera);
camera - >focus() - >setFocusMode(QCameraFocus : :ContinuousFocus);
camera - >focus() - >setFocusPointMode(QCameraFocus : :FocusPointAuto);
//直接在这里设置动作级联
connect(imageCapture, &QCameraImageCapture : :imageSaved, [ this]( int id, const QString &fileName)
{
Q_UNUSED(id);
processSavedImage(fileName);
});
}
void QCvImageProcessor : :capture()
{
if(imageCapture - >isReadyForCapture())
{
//注意这里获得一个可用的图片地址的方法
imageCapture - >capture(QStandardPaths : :writableLocation(QStandardPaths : :PicturesLocation));
}
else
{
emit errorOccured( "Camera is not ready to capture.");
}
}
代码下载地址:https://files.cnblogs.com/files/jsxyhelu/GO_GTD2%E5%AE%8C%E6%88%90.zip
视频地址 :https://files.cnblogs.com/files/jsxyhelu/amin%E4%BE%8B%E5%AD%90%E8%A7%86%E9%A2%91.zip
视频地址 :https://files.cnblogs.com/files/jsxyhelu/amin%E4%BE%8B%E5%AD%90%E8%A7%86%E9%A2%91.zip
一、qml界面部分:
1、专门生成了用于提示的dialog
/*
只有一个OK的弹出界面,目前这个弹出界面只给捕获的时候使用
*/
Dialog
{
property alias text : msgDlgLabel.text
id : messageDialog
modal : true
x : (parent.width - width) / 2
y : (parent.height - height) / 2
standardButtons : Dialog.Ok
//上面只有一个label
Label
{
id : msgDlgLabel
font.bold : true
wrapMode : Text.Wrap
width : parent.width
//点击事件
onLinkActivated :
{
if(link == "图像处理")
{
tabBar.currentIndex = 1
}
messageDialog.close()
}
}
}
只有一个OK的弹出界面,目前这个弹出界面只给捕获的时候使用
*/
Dialog
{
property alias text : msgDlgLabel.text
id : messageDialog
modal : true
x : (parent.width - width) / 2
y : (parent.height - height) / 2
standardButtons : Dialog.Ok
//上面只有一个label
Label
{
id : msgDlgLabel
font.bold : true
wrapMode : Text.Wrap
width : parent.width
//点击事件
onLinkActivated :
{
if(link == "图像处理")
{
tabBar.currentIndex = 1
}
messageDialog.close()
}
}
}
2、整体界面采用swipe和page以及footer的形式,达到了简洁高效
/*
主要的swipview界面
*/
SwipeView
{
id : swipeView
currentIndex : 0
anchors.rightMargin : 0
anchors.bottomMargin : 0
anchors.leftMargin : 0
anchors.topMargin : 0
anchors.fill : parent
//TabBar和swipview要对应起来
onCurrentIndexChanged :
{
tabBar.setCurrentIndex(swipeView.currentIndex)
}
//视频预览
Page
{……
主要的swipview界面
*/
SwipeView
{
id : swipeView
currentIndex : 0
anchors.rightMargin : 0
anchors.bottomMargin : 0
anchors.leftMargin : 0
anchors.topMargin : 0
anchors.fill : parent
//TabBar和swipview要对应起来
onCurrentIndexChanged :
{
tabBar.setCurrentIndex(swipeView.currentIndex)
}
//视频预览
Page
{……
以及
/*
主要的footer操作
*/
footer : TabBar {
id : tabBar
currentIndex : 0
padding : 10
主要的footer操作
*/
footer : TabBar {
id : tabBar
currentIndex : 0
padding : 10
3、使用了HTML增加文本显示效果,并且是可以切换的
Text
{
id : helpText
wrapMode : Text.Wrap
anchors.left : parent.left
anchors.right : parent.right
text : "由衷感谢:<a href=\"http://amin-ahmadi.com/quick-camera-cv/\">http://amin-ahmadi.com/quick-camera-cv</a>" +
"给本程序很多借鉴" +
"<br>" +
"<br>" +
"作者博客:" +
"<br>" +
"<a href=\"jsxyhelu.cnblogs.com\">jsxyhelu.cnblogs.com</a>" +
"<br>" +
"<a href=\"jsxyhelu.cnblogs.com\"><img src=\"http://images2015.cnblogs.com/blog/508489/201607/508489-20160731065441684-483128601.png\" alt=\"欢迎访问!\"></a>" +
"<br>" +
"<b>版权</b>" +
"本程序使用 <a href=\"http://qt.io/\">Qt Framework</a> 作为GUI" +
"<br>" +
"同时使用 <a href=\"http://opencv.org/\">OpenCV</a> 做图像处理算法." +
"<br>" +
"程序采用ICO来自<a href=\"http://flaticon.com/\">Flat Icon</a>."
onLinkActivated :
{
Qt.openUrlExternally(link);
}
}
应该这样讲,有这段代码作为例子,那么这种样式的程序在界面上基本不成问题。
二、算法实现部分:
qml是弱语法,比较类似lambda,所以这种语言的使用对于习惯c语言的我来说有难度,想要精通需要时间;另一个方面,因为需要和OpenCV进行交互,所以更复杂一点。本例中综合使用了qml使用c++封装出来的对象,以及“信号、槽”机制等;在
摄像头获取和图片采集实现中,
硬件层综合使用了qml和qcamera,捕获使用了
QCameraImageCapture
,具体这样用
在qml中,使用
//摄像头选择对话框
ComboBox
{
id : cameraCombo
Layout.fillWidth : true
Layout.fillHeight : true
model : QtMultimedia.availableCameras
textRole : "displayName"
delegate : ItemDelegate
{
text : modelData.displayName
}
onCurrentIndexChanged :
{
camera.stop()
camera.deviceId = model[currentIndex].deviceId
camera.start()
}
}
{
id : cameraCombo
Layout.fillWidth : true
Layout.fillHeight : true
model : QtMultimedia.availableCameras
textRole : "displayName"
delegate : ItemDelegate
{
text : modelData.displayName
}
onCurrentIndexChanged :
{
camera.stop()
camera.deviceId = model[currentIndex].deviceId
camera.start()
}
}
这样可以获得所有可用摄像头的句柄,然后直接传递到c++中
//调用qcamera进行图像采集
void QCvImageProcessor : :setCamera(QVariant v)
{
QObject *o = qvariant_cast <QObject * >(v);
camera = qvariant_cast <QCamera * >(o - >property( "mediaObject"));
camera - >setCaptureMode(QCamera : :CaptureStillImage);
imageCapture = new QCameraImageCapture(camera);
camera - >focus() - >setFocusMode(QCameraFocus : :ContinuousFocus);
camera - >focus() - >setFocusPointMode(QCameraFocus : :FocusPointAuto);
//直接在这里设置动作级联
connect(imageCapture, &QCameraImageCapture : :imageSaved, [ this]( int id, const QString &fileName)
{
Q_UNUSED(id);
processSavedImage(fileName);
});
}
void QCvImageProcessor : :capture()
{
if(imageCapture - >isReadyForCapture())
{
//注意这里获得一个可用的图片地址的方法
imageCapture - >capture(QStandardPaths : :writableLocation(QStandardPaths : :PicturesLocation));
}
else
{
emit errorOccured( "Camera is not ready to capture.");
}
}
还是使用
QCameraImageCapture,QCamera来完成捕获。
由于在andoird中,videocapture不能给使用,那么qcamera作为qt专属,来实现摄像头采集功能是非常合适的,这里给出了具体系统方法。
三、进一步扩展部分:
QCameraImageCapture只能捕获静态图片,但是作为一个完整的图像处理程序,一定要能够处理并显示实时的视频数据,如何解决?继续探索!
感谢阅读至此,希望有所帮助。
附件列表
目前方向:图像拼接融合、图像识别 联系方式:jsxyhelu@foxmail.com