Can we access camera and alarm clock on Android devices through Qt5.1.0 Android build?
-
I am making an experiment on Qt5.1.0 Android build to test whether these functionalities are applicable through Qt, or can we find workaround ( ie. 3rd party library through C++ ) to meet these demand?
-
Qt5.1 do not support camera yet, you have to wait for Qt5.2 for full support. Qt5.1 is a technical preview only.
This blog has the answer you want
"Qt5.1 RC":http://blog.qt.digia.com/blog/2013/06/18/qt-5-1-release-candidate-available/Maybe you could give openCV a try, it should be able to access the camera of android.
-
[quote author="stereomatching" date="1371841980"]Qt5.1 do not support camera yet, you have to wait for Qt5.2 for full support. Qt5.1 is a technical preview only.
This blog has the answer you want
"Qt5.1 RC":http://blog.qt.digia.com/blog/2013/06/18/qt-5-1-release-candidate-available/Maybe you could give openCV a try, it should be able to access the camera of android.
[/quote]
How about alarm clock? I've searched the Internet and find there is a service in controling Android internal alarm clock. How does Qt handle Android service? Thanks.
hey, stereomatching, are you the one who is active at CSDN Qt forum? -
[quote author="jiangcaiyang" date="1371911455"]
How about alarm clock? I've searched the Internet and find there is a service in controling Android internal alarm clock. How does Qt handle Android service? Thanks.
[/quote]
Sorry, I don't know the answer[quote author="jiangcaiyang" date="1371911455"]
hey, stereomatching, are you the one who is active at CSDN Qt forum?
[/quote]
Not sure who you are talking about, but I do have an account on CSDN. -
[quote author="Moster" date="1372151432"]Do you still need to access the camera or was that more like a general quesstion? I could provide an example project that uses opencv to access the camera[/quote]
Please show us your example, I tried it before on desktop, but haven't tried it on android yet.
.hpp
@
#ifndef OPENCVCAMERA_HPP
#define OPENCVCAMERA_HPP#include <QQuickPaintedItem>
#include <QString>#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>class QPainter;
class QTimer;class openCVCamera : public QQuickPaintedItem
{
Q_OBJECT
Q_PROPERTY(int imageHeight READ imageHeight WRITE setImageHeight NOTIFY imageHeightChanged)
Q_PROPERTY(int imageWidth READ imageWidth WRITE setImageWidth NOTIFY imageWidthChanged)
Q_PROPERTY(bool play READ play WRITE setPlay NOTIFY playChanged)
public:
explicit openCVCamera(QQuickItem *parent = 0);
openCVCamera(openCVCamera const&)=delete;
openCVCamera& operator=(openCVCamera const&)=delete;int imageHeight(); int imageWidth(); void paint(QPainter *painter); bool play() const; void setImageHeight(int value); void setImageWidth(int value); void setPlay(bool value);
signals:
void imageHeightChanged();
void imageWidthChanged();void playChanged();
public slots:
void open(size_t index);private slots:
void captureFrame();private:
cv::VideoCapture camera_;
cv::Mat cameraFrame_;cv::Mat displayedFrame_; int imageHeight_; int imageWidth_; QString log_; bool play_; QTimer *timer_;
};
#endif // OPENCVCAMERA_HPP
@
.cpp
@
#include <QDebug>#include <QPainter>
#include <QTimer>#include <opencv2/core/core.hpp>
#include "openCVToQt.hpp"
#include "openCVCamera.hpp"
openCVCamera::openCVCamera(QQuickItem *parent) :
QQuickPaintedItem(parent), imageHeight_(320), imageWidth_(480), play_(false), timer_(new QTimer(this))
{
open(0);
setRenderTarget(QQuickPaintedItem::FramebufferObject);
setPerformanceHint(QQuickPaintedItem::FastFBOResizing);
camera_.set(CV_CAP_PROP_FRAME_WIDTH, 480);
camera_.set(CV_CAP_PROP_FRAME_HEIGHT, 320);
//setRenderTarget(QQuickPaintedItem::Image);connect(timer_, &QTimer::timeout, this, &openCVCamera::captureFrame); timer_->start(33);
}
int openCVCamera::imageHeight()
{
return imageHeight_;
}int openCVCamera::imageWidth()
{
return imageWidth_;
}void openCVCamera::open(size_t index)
{
camera_.open(index);
if(!camera_.isOpened()){
log_ = "could not access the camera or video";
qDebug() << log_;
}
}void openCVCamera::paint(QPainter *painter)
{
if(cameraFrame_.empty()){
log_ = "could not grab the camera frame";
qDebug() << log_;
return;
}
cv::resize(cameraFrame_, cameraFrame_, cv::Size(imageWidth_, imageHeight_));
QImage const img = mat_to_qimage_ref(cameraFrame_);
painter->drawImage(0, 0, img);
}bool openCVCamera::play() const
{
return play_;
}void openCVCamera::setImageHeight(int value)
{
if(value != imageHeight()){
imageHeight_ = value;
qDebug()<<"height changed : "<<value;
emit imageHeightChanged();
}
}void openCVCamera::setImageWidth(int value)
{
if(value != imageWidth()){
imageWidth_ = value;
qDebug()<<"width changed : "<<value;
emit imageWidthChanged();
}
}void openCVCamera::setPlay(bool value)
{
if(value != play_){
play_ = value;emit playChanged(); }
}
/**********************************************************
****************** implementation ************************
**********************************************************/void openCVCamera::captureFrame()
{
if(play_){
camera_ >> cameraFrame_;
if(cameraFrame_.empty()){
log_ = "could not grab the camera frame";
qDebug() << log_;
return;
}
update();
}
}
@Whatever, the speed is slower than QtMultimedia
-
Its just a simple project to test if it works. I basically just extended some opencv example. Im using a tegra3 device. So I got a modified opencv version for the tegra3. You would need to adjust the pro file for your opencv version
I have to say that Im also pretty new to Qt :P
main.cpp
@#include <QApplication>
#include "Window.h"int main(int argc, char** argv){
QApplication app (argc, argv);Window window; window.showMaximized(); return app.exec();
}
@Window.cpp
@#include "Window.h"
Window::Window(QWidget *parent) :
QWidget(parent)
{
scene = new QGraphicsScene(this);view = new QGraphicsView(scene, this); view->setViewport(new QGLWidget); //view->setFixedSize(640,480); view->setScene(scene); view->showMaximized(); QThread* thread = new QThread; Worker* worker = new Worker(); worker->moveToThread(thread); connect(worker, SIGNAL(error(QString)), this, SLOT(errorString(QString))); connect(thread, SIGNAL(started()), worker, SLOT(process())); connect(worker, SIGNAL(finished()), thread, SLOT(quit())); connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater())); connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); connect(worker, SIGNAL(sendPicture(QImage*, Mat*)), this, SLOT(updateScene(QImage*, Mat*))); thread->start();
}
void Window::updateScene(QImage result, Mat help){
scene->clear(); scene->addPixmap(QPixmap::fromImage(*result)); delete(result); delete(help);
}
Worker::Worker() {
capture = new cv::VideoCapture(0); cv::Size camera_resolution; camera_resolution.width=640; camera_resolution.height=480; capture->set(CV_CAP_PROP_FRAME_WIDTH, camera_resolution.width); capture->set(CV_CAP_PROP_FRAME_HEIGHT, camera_resolution.height);
}
Worker::~Worker(){
capture->release();}
void Worker::process(){
float fps = 0; queue<int64> time_queue; while(1){ int64 then; int64 now = cv::getTickCount(); time_queue.push(now); // help = new Mat(); drawing_frame = new Mat(); if (!capture.empty()) { if (capture->grab()) capture->retrieve(*drawing_frame, CV_CAP_ANDROID_GREY_FRAME); char buffer[256]; sprintf(buffer, "Display performance: %dx%d fps: %.3f", drawing_frame->cols, drawing_frame->rows, fps); cv::putText(*drawing_frame, std::string(buffer), cv::Point(0,32), cv::FONT_HERSHEY_PLAIN, 0.75, cv::Scalar(0,255,0,255)); } if (time_queue.size() >= 2) then = time_queue.front(); else then = 0; if (time_queue.size() >= 25) time_queue.pop(); fps = time_queue.size() * (float)cv::getTickFrequency() / (now-then); img = new QImage((uchar*)drawing_frame->data, drawing_frame->cols, drawing_frame->rows, drawing_frame->step,QImage::Format_Indexed8); emit sendPicture(img, drawing_frame); }
}
@ -
Window.h
@#ifndef WINDOW_H
#define WINDOW_H#include "helper.h"
class QGraphicsView;
class QGraphicsScene;
class QGraphicsPixmapItem;class Window : public QWidget
{
Q_OBJECT
public:
explicit Window(QWidget parent = 0);
public slots:
void updateScene(QImage img, Mat* help);
private:
QGraphicsView *view;
QGraphicsScene scene;
QGraphicsPixmapItem item;};
class Worker : public QObject {
Q_OBJECT
cv::Ptrcv::VideoCapture capture;
QImage *img;
Mat *drawing_frame;
public:
Worker();
~Worker();public slots:
void process();signals:
void finished();
void error(QString err);
void sendPicture(QImage* img, Mat* help);
};#endif // WINDOW_H@
helper.h
@#ifndef HELPER_H
#define HELPER_H
#define _USE_MATH_DEFINES#include <math.h>
#include <jni.h>
#include <errno.h>
#include <sys/time.h>
#include <time.h>
#include <queue>
#include <vector>#include <QGraphicsScene>
#include <QGraphicsView>
#include <QImage>
#include <QWidget>
#include <QObject>
#include <QThread>
#include <QPixmap>
#include <QGLWidget>#include <android/log.h>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,VA_ARGS)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,VA_ARGS)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG,VA_ARGS)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,VA_ARGS)using namespace std;
using namespace cv;#endif // HELPER_H@
project file: cam.pro
@TEMPLATE = app
TARGET = camQT = opengl core widgets gui
OTHER_FILES +=
android/version.xml
android/src/org/qtproject/qt5/android/bindings/QtActivity.java
android/src/org/qtproject/qt5/android/bindings/QtApplication.java
android/src/org/kde/necessitas/ministro/IMinistro.aidl
android/src/org/kde/necessitas/ministro/IMinistroCallback.aidl
android/res/values-el/strings.xml
android/res/values-nb/strings.xml
android/res/values-zh-rCN/strings.xml
android/res/values-id/strings.xml
android/res/values-ja/strings.xml
android/res/values-zh-rTW/strings.xml
android/res/values-de/strings.xml
android/res/values-fr/strings.xml
android/res/values-pl/strings.xml
android/res/values-ro/strings.xml
android/res/values-it/strings.xml
android/res/values-es/strings.xml
android/res/values-pt-rBR/strings.xml
android/res/values-fa/strings.xml
android/res/layout/splash.xml
android/res/values-rs/strings.xml
android/res/values-ms/strings.xml
android/res/values-et/strings.xml
android/res/values/strings.xml
android/res/values/libs.xml
android/res/values-nl/strings.xml
android/res/values-ru/strings.xml
android/AndroidManifest.xmlINCLUDEPATH += $$PWD/../../../NVPACK/OpenCV-2.4.5-Tegra-sdk/sdk/native/jni/include/opencv/
INCLUDEPATH += $$PWD/../../../NVPACK/OpenCV-2.4.5-Tegra-sdk/sdk/native/jni/include/opencv2/
INCLUDEPATH += $$PWD/../../../NVPACK/OpenCV-2.4.5-Tegra-sdk/sdk/native/jni/include/
INCLUDEPATH += $$PWD/../../../NVPACK/android-ndk-r8d/sources/android/native_app_glueLIBS += -L$$PWD/../../../NVPACK/android-ndk-r8d/platforms/android-14/arch-arm/usr/lib/ -landroid
INCLUDEPATH += $$PWD/../../../NVPACK/android-ndk-r8d/platforms/android-14/arch-arm/usr/include/android
DEPENDPATH += $$PWD/../../../NVPACK/android-ndk-r8d/platforms/android-14/arch-arm/usr/include/androidLIBS += -L$$PWD/../../../NVPACK/android-ndk-r8d/platforms/android-14/arch-arm/usr/lib/ -lEGL
INCLUDEPATH += $$PWD/../../../NVPACK/android-ndk-r8d/platforms/android-14/arch-arm/usr/include/EGL
DEPENDPATH += $$PWD/../../../NVPACK/android-ndk-r8d/platforms/android-14/arch-arm/usr/include/EGLLIBS += -L$$PWD/../../../NVPACK/android-ndk-r8d/platforms/android-14/arch-arm/usr/lib/ -lGLESv2
INCLUDEPATH += $$PWD/../../../NVPACK/android-ndk-r8d/platforms/android-14/arch-arm/usr/include/GLES2
DEPENDPATH += $$PWD/../../../NVPACK/android-ndk-r8d/platforms/android-14/arch-arm/usr/include/GLES2LIBS += -L$$PWD/../../../NVPACK/OpenCV-2.4.5-Tegra-sdk/sdk/native/libs/tegra3/
-lopencv_contrib
-lopencv_legacy
-lopencv_ml
-lopencv_stitching
-lopencv_objdetect
-lopencv_videostab
-lopencv_calib3d
-lopencv_photo
-lopencv_video
-lopencv_features2d
-lopencv_highgui
-lopencv_androidcamera
-lopencv_flann
-lopencv_imgproc
-lopencv_coreLIBS += -L$$PWD/../../../NVPACK/OpenCV-2.4.5-Tegra-sdk/sdk/native/3rdparty/libs/tegra3/
-ltbb
-llibjpeg
-llibpng
-llibtiff
-llibjasper
-lIlmImfSOURCES +=
main.cpp
Window.cppHEADERS +=
helper.h
Window.h
@ -
Thanks for your codes:). Maybe you could use smart pointer
(unique_ptr) to guard your resources, this could make your codes
become safer and more robust(there are a lot of articles explain how
important smart pointer(RAII) in c++). -
what about alarm clock?