Browse Source

creating video using openCV

Animal 3 years ago
parent
commit
8d3a4c4a73
12 changed files with 397 additions and 55 deletions
  1. 100 0
      MyLoader.qml
  2. 22 6
      graber.pro
  3. 19 2
      imagemanager.cpp
  4. 8 3
      imagemanager.h
  5. BIN
      images/pause.png
  6. BIN
      images/start.png
  7. BIN
      images/stop.png
  8. 3 1
      main.cpp
  9. 155 43
      main.qml
  10. 4 0
      qml.qrc
  11. 51 0
      videomanger.cpp
  12. 35 0
      videomanger.h

+ 100 - 0
MyLoader.qml

@@ -0,0 +1,100 @@
+import QtQuick 2.7
+
+Item {
+
+    // ----- Public Properties ----- //
+
+    property alias barCount: repeater.model
+    property color color: "white"
+    property int spacing: 5
+
+    property bool running: true
+
+    id: root
+    onRunningChanged: {
+        if (barCount !== repeater.count || timer._barIndex <= barCount - 1) {
+            return;
+        }
+
+        for (var barIndex = 0; barIndex < barCount; barIndex++) {
+            if (running) {
+                if (repeater.itemAt(barIndex)) {
+                    repeater.itemAt(barIndex).playAnimation();
+                }
+            }
+            else {
+                if (repeater.itemAt(barIndex)) {
+                    repeater.itemAt(barIndex).pauseAnimation();
+                }
+            }
+        }
+    }
+
+    Repeater {
+        id: repeater
+        delegate: Component {
+            Rectangle {
+                width: (root.width / root.barCount) - root.spacing
+                height: root.height
+                x: index * width + root.spacing * index
+                transform: Scale {
+                    id: rectScale
+                    origin {
+                        x: width / 2
+                        y: height / 2
+                    }
+                }
+                transformOrigin: Item.Center
+                color: root.color
+
+                SequentialAnimation {
+                    id: anim
+                    loops: Animation.Infinite
+
+                    NumberAnimation { target: rectScale; property: "yScale"; from: 1; to: 1.5; duration: 300 }
+                    NumberAnimation { target: rectScale; property: "yScale"; from: 1.5; to: 1; duration: 300 }
+                    PauseAnimation { duration: root.barCount * 150 }
+                }
+
+                function playAnimation() {
+                    if (anim.running == false) {
+                        anim.running = true;
+                    }
+
+                    if (anim.paused) {
+                        anim.paused = false;
+                    }
+                }
+
+                function pauseAnimation() {
+                    if (anim.running) {
+                        anim.paused = true;
+                    }
+                }
+            }
+        }
+    }
+
+    Timer {
+        // ----- Private Properties ----- //
+        property int _barIndex: 0
+
+        id: timer
+        interval: 80
+        repeat: true
+        onTriggered: {
+            if (_barIndex === root.barCount) {
+                stop();
+            }
+            else {
+                repeater.itemAt(_barIndex).playAnimation();
+                if (root.running === false) {
+                    repeater.itemAt(_barIndex).pauseAnimation();
+                }
+
+                _barIndex++;
+            }
+        }
+        Component.onCompleted: start()
+    }
+}

+ 22 - 6
graber.pro

@@ -13,17 +13,32 @@ DEFINES += QT_DEPRECATED_WARNINGS
 # You can also select to disable deprecated APIs only up to a certain version of Qt.
 #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
 
+
+INCLUDEPATH += C:\OpenCV\opencv\build\include
+
+LIBS += C:\OpenCV\OpenCV_bin\bin\libopencv_core430.dll
+LIBS += C:\OpenCV\OpenCV_bin\bin\libopencv_highgui430.dll
+LIBS += C:\OpenCV\OpenCV_bin\bin\libopencv_imgcodecs430.dll
+LIBS += C:\OpenCV\OpenCV_bin\bin\libopencv_imgproc430.dll
+LIBS += C:\OpenCV\OpenCV_bin\bin\libopencv_features2d430.dll
+LIBS += C:\OpenCV\OpenCV_bin\bin\libopencv_calib3d430.dll
+LIBS += C:\OpenCV\OpenCV_bin\bin\libopencv_video430.dll
+LIBS += C:\OpenCV\OpenCV_bin\bin\libopencv_videoio430.dll
+LIBS += C:\OpenCV\OpenCV_bin\bin\libopencv_stitching430.dll
+LIBS += C:\OpenCV\OpenCV_bin\bin\libopencv_photo430.dll
+
+
+
 SOURCES += \
         imagemanager.cpp \
-        main.cpp
+        main.cpp \
+        videomanger.cpp
 
 RESOURCES += qml.qrc
 
-# Additional import path used to resolve QML modules in Qt Creator's code model
-QML_IMPORT_PATH =
 
-# Additional import path used to resolve QML modules just for Qt Quick Designer
-QML_DESIGNER_IMPORT_PATH =
+
+
 
 # Default rules for deployment.
 qnx: target.path = /tmp/$${TARGET}/bin
@@ -31,4 +46,5 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin
 !isEmpty(target.path): INSTALLS += target
 
 HEADERS += \
-    imagemanager.h
+    imagemanager.h \
+    videomanger.h

+ 19 - 2
imagemanager.cpp

@@ -1,16 +1,19 @@
 #include "imagemanager.h"
 
 #include <QDebug>
+#include <QFile>
+
 
 ImageManager::ImageManager(QObject *parent) : QObject(parent),
     screens(new QList<QImage>),
+    vManager(new VideoManger),
     imagesCount(0),
     imagesFolder("C://Documents/")
 {
-
+        connect(vManager.get(), SIGNAL(videoSaved()), this, SLOT(onVideoSaved()));
 }
 
-void ImageManager::get(QVariant image)
+void ImageManager::append(QVariant image)
 {
 //    Q_UNUSED(image)
     QImage tmpImg = qvariant_cast<QImage>(image);
@@ -24,3 +27,17 @@ void ImageManager::saveAll() const
         screens.get()->at(i).save(imagesFolder + QString("%1.png").arg(counter++));
     }
 }
+
+void ImageManager::createVideo() const
+{
+//    vManager.get()->makeVideo(screens.get(), imagesFolder);
+}
+
+void ImageManager::onVideoSaved()
+{
+//    for(int i = 0; i < screens.get()->count(); ++i){
+//        QFile file(imagesFolder + QString::number(i) + ".png");
+//    }
+    screens.get()->clear();
+
+}

+ 8 - 3
imagemanager.h

@@ -8,6 +8,8 @@
 
 #include <memory>
 
+#include <videomanger.h>
+
 class QVariant;
 class QImage;
 
@@ -19,21 +21,24 @@ class ImageManager : public QObject
 public:
     explicit ImageManager(QObject *parent = nullptr);
 
-    Q_INVOKABLE void get(QVariant image);
+    Q_INVOKABLE void append(QVariant image);
     Q_INVOKABLE void saveAll() const;
+    Q_INVOKABLE void createVideo() const;
 
 private:
 
     std::unique_ptr<QList<QImage>> screens;
-
+    std::unique_ptr<VideoManger> vManager;
     int imagesCount;
-
     QString imagesFolder;
 
 
 signals:
     void imagesSaved();
 
+private slots:
+    void onVideoSaved();
+
 };
 
 #endif // IMAGEMANAGER_H

BIN
images/pause.png


BIN
images/start.png


BIN
images/stop.png


+ 3 - 1
main.cpp

@@ -6,7 +6,7 @@
 #include <memory>
 
 #include "imagemanager.h"
-
+#include "videomanger.h"
 
 int main(int argc, char *argv[])
 {
@@ -16,7 +16,9 @@ int main(int argc, char *argv[])
 
     QQmlApplicationEngine engine;
     std::unique_ptr<ImageManager> imageManager(new ImageManager);
+    std::unique_ptr<VideoManger> videoManager(new VideoManger);
     engine.rootContext()->setContextProperty("imageManager", imageManager.get());
+        engine.rootContext()->setContextProperty("videoManager", videoManager.get());
     const QUrl url(QStringLiteral("qrc:/main.qml"));
     QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                      &app, [url](QObject *obj, const QUrl &objUrl) {

+ 155 - 43
main.qml

@@ -1,68 +1,180 @@
-import QtQuick 2.11
-import QtQuick.Window 2.11
+//import QtQuick 2.11
+//import QtQuick.Window 2.11
+//import QtGraphicalEffects 1.0
+
+//Window {
+//    id: window
+//    visible: true
+//    width: 640
+//    height: 480
+//    title: qsTr("App")
+
+//    QtObject{
+//        id: d
+
+//        property var images: []
+//    }
+
+
+//    Rectangle{
+//        id: rect
+//        width: parent.width
+//        height: 240
+//        x: 0
+//        y: 0
+//        color: "lightblue"
+
+//        Text{
+//            id: txt
+
+//            property int counter: 0
+
+//            anchors.centerIn: parent
+//            font.pointSize: 30
+//            color: "black"
+//            text: counter
+
+
+//        }
+
+//        MouseArea{
+//            property int counter: 0
+//            anchors.fill: parent
+//            onClicked: {
+//                rect.grabToImage(function(result) {
+////                    img.source = result.url
+//                    ++txt.counter
+////                    imageManager.get(result.image)
+//                    result.saveToFile("C://Documents/%1.png".arg(counter))
+//                })
+//                ++counter
+//            }
+//        }
+//    }
+
+//   Image{
+//       id: img
+//       width: parent.width
+//       height: parent.height - rect.height
+//       x: 0
+//       y: 240
+//       asynchronous: true
+//       mipmap: true
+
+//       MouseArea{
+//           anchors.fill: parent
+//           onClicked: imageManager.saveAll()
+//       }
+//   }
+
+
+//}
+
+
+
+import QtQuick 2.0
+import QtQuick.Window 2.0
+import QtQuick.Controls 2.0
 import QtGraphicalEffects 1.0
 
-Window {
+ApplicationWindow {
     id: window
     visible: true
     width: 640
     height: 480
     title: qsTr("App")
 
-    QtObject{
-        id: d
 
-        property var images: []
-    }
 
+    footer: TabBar{
+        width: parent.width
+        TabButton {
+            icon.source: "qrc:/images/stop.png"
+            icon.width: 48
+            icon.height: 48
+            width: window.width / 3 - 2
+            onClicked: {
+//                imageManager.saveAll()
+//                imageManager.createVideo()
+                videoManager.makeVideo("C://Documents/", timer.counter)
+            }
+        }
+        TabButton {
+            icon.source: "qrc:/images/start.png"
+            icon.width: 48
+            icon.height: 48
+            width: window.width / 3 - 2
+            onClicked: {
+                anim.start()
+                timer.start()
+            }
+        }
+        TabButton {
+            icon.source: "qrc:/images/pause.png"
+            icon.width: 48
+            icon.height: 48
+            width: window.width / 3 - 2
+            onClicked: {
+                anim.stop()
+                timer.stop()
+            }
+        }
+    }
 
     Rectangle{
-        id: rect
+        id: area
         width: parent.width
-        height: 240
-        x: 0
-        y: 0
-        color: "lightblue"
-
-        Text{
-            id: txt
+        height: parent.height
+        color: "black"
 
-            property int counter: 0
+        Rectangle{
+            id: rect
+            width: 30
+            height: 30
+            radius: 5
 
-            anchors.centerIn: parent
-            font.pointSize: 30
-            color: "black"
-            text: counter
+            x: 10
+            y: 10
+            color: "lightblue"
+        }
 
 
+        MyLoader{
+            id: loaderIndicator
+            barCount: 3
+            anchors.centerIn: parent
+            width: parent.width * 0.5
+            height: parent.height / 4
         }
+    }
 
-        MouseArea{
-            anchors.fill: parent
-            onClicked: {
-                rect.grabToImage(function(result) {
-                    img.source = result.url
-                    ++txt.counter
-                    imageManager.get(result.image)
-                })
-            }
-        }
+
+    SequentialAnimation{
+        id: anim
+        loops: Animation.Infinite
+        PropertyAnimation{target: rect; properties: "x"; to: area.width - rect.width - 10; duration: 1000}
+        PropertyAnimation{target: rect; properties: "y"; to: area.height - rect.height - 10; duration: 1000}
+        PropertyAnimation{target: rect; properties: "x"; to: 10; duration: 1000}
+        PropertyAnimation{target: rect; properties: "y"; to: 10; duration: 1000}
     }
 
-   Image{
-       id: img
-       width: parent.width
-       height: parent.height - rect.height
-       x: 0
-       y: 240
-       asynchronous: true
-       mipmap: true
 
-       MouseArea{
-           anchors.fill: parent
-           onClicked: imageManager.saveAll()
-       }
-   }
+    Timer{
 
+        property int counter: 0
+
+        id: timer
+        interval: 40
+        repeat: true
+        running: false
+        onTriggered: {
+            area.grabToImage(function(result) {
+                result.saveToFile("C://Documents/%1.png".arg(counter++))
+//                imageManager.append(result.image)
+            })
+            ++counter
+        }
+    }
 
 }
+

+ 4 - 0
qml.qrc

@@ -1,5 +1,9 @@
 <RCC>
     <qresource prefix="/">
         <file>main.qml</file>
+        <file>MyLoader.qml</file>
+        <file>images/pause.png</file>
+        <file>images/start.png</file>
+        <file>images/stop.png</file>
     </qresource>
 </RCC>

+ 51 - 0
videomanger.cpp

@@ -0,0 +1,51 @@
+#include "videomanger.h"
+
+#include <QImage>
+#include <QList>
+#include <QString>
+
+
+#include <random>
+
+VideoManger::VideoManger(QObject *parent/* = nullptr*/) : QObject(parent),
+    framesPerSecound(25)
+{
+
+}
+
+bool VideoManger::makeVideo(/*QList<QImage> *frames, */QString outputName, int count)
+{
+//    if(frames->isEmpty())
+//        return false;
+    if(outputName.isEmpty()){
+        srand(time(nullptr));
+        outputName = QString(QString::number(rand() % 200 + 10));
+    }
+
+    // counts the size of one frame
+    frameSize = cv::imread(outputName.toStdString() + std::to_string(1) + ".png").size();
+
+    // init videoWriter
+    videoWriter = cv::VideoWriter(outputName.toStdString() + "1.avi", cv::VideoWriter::fourcc('M', 'J', 'P', 'G'),
+                framesPerSecound, frameSize, true);
+
+    // record frames in a video file
+
+    for(int i = 0; i < count; ++i){
+//        frame = QImageToCvMat(frames->at(i), CV_8UC3);
+//        cv::imshow("qwe", frame);
+        frame = cv::imread(outputName.toStdString() + std::to_string(i + 1) + ".png");
+        videoWriter.write(frame);
+    }
+
+    emit videoSaved();
+    return true;
+}
+
+// convert QImage to cv;;mat
+cv::Mat VideoManger::QImageToCvMat(QImage frame, int format)
+{
+    return cv::Mat(frame.height(), frame.width(), format,
+                   const_cast<uchar*>(frame.bits()),
+                   frame.bytesPerLine()).clone();
+}

+ 35 - 0
videomanger.h

@@ -0,0 +1,35 @@
+#ifndef VIDEOMANGER_H
+#define VIDEOMANGER_H
+
+#include <QObject>
+
+#include <sstream>
+#include "opencv2/opencv.hpp"
+
+class VideoManger : public QObject
+{
+    Q_OBJECT
+
+public:
+    explicit VideoManger(QObject *parent = nullptr);
+
+    Q_INVOKABLE bool makeVideo(/*QList<QImage> *frames, */QString outputName, int count);
+
+private:
+
+    cv::Mat QImageToCvMat(QImage frame, int format);
+
+    cv::Mat frame;
+    cv::Size frameSize;
+
+    cv::VideoWriter videoWriter;
+
+    int framesPerSecound;
+
+
+signals:
+    void videoSaved();
+
+};
+
+#endif // VIDEOMANGER_H