Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. QtonPi
  4. RaspberryPI3 too slow thread with opencv algorithm

RaspberryPI3 too slow thread with opencv algorithm

Scheduled Pinned Locked Moved Solved QtonPi
6 Posts 3 Posters 2.9k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    davidino
    wrote on last edited by davidino
    #1

    Goodmorning to all,
    I'm trying to use ORB algorithm to detect an object in a room using a camera.
    I'm already using a different thread with the purpose of detaching the GUI thread from the the one where I do calculation, as I reported in one of my previous topic "Custom Qlabel show videocamera on different thread".
    Unfortunately, with this algorithm the CPU usage is more than 100%.

    How do I know if the thread used for calculation is actually using a different processor, or it use the same as GUI thread? Is it possible to chooses which processor to use for one thread?
    Since I saw that the most demanding part is when I detect and compute the keypoints and descriptors (code reported below), do you suggest to create another thread only for it?

    vector<KeyPoint> sceneKeypoints, objectKeyPoints;
    Mat sceneDescriptors, objectDescriptors;
    Mat objectImg = imread("/home/root/objectToDetect.png", IMREAD_GRAYSCALE);
    
    orb = ORB::create();
                    
    // EXTRACT KEYPOINTS AND DESCRIPTORS
    orb->detect(objectImg, objectKeypoints);
    orb->compute(objectImg, objectKeypoints, objectDescriptors);   
    orb->detect(sceneImg, sceneKeypoints);
    orb->compute(sceneImg, sceneKeypoints, sceneDescriptors);
    

    Thank you very much.
    Davidino

    1 Reply Last reply
    0
    • mrdebugM Offline
      mrdebugM Offline
      mrdebug
      wrote on last edited by
      #2

      Hi. I have a situation similar to yours.

      In order to know how much cpu each thread are using you can use top tool and press H. In this mode you will have the processes sorted by thread with the right thread name.

      If you are using opencv maybe you are grabbing images from a local camera. This could be cpu expensive.

      I'm working with an rtsp camera using ffmpeg to grap it. This is not cpu expensive. The grabbing is done by a dedicated non gui thread.
      I have a second thread that (by using opencv) evaluate the frame.
      The first thread uses the second thread only if the second thread is availabe to evaluate it.
      In this way I have a good real time live video but the thread that are using opencv often drops frames.

      Need programmers to hire?
      www.labcsp.com
      www.denisgottardello.it
      GMT+1
      Skype: mrdebug

      1 Reply Last reply
      3
      • Pablo J. RoginaP Offline
        Pablo J. RoginaP Offline
        Pablo J. Rogina
        wrote on last edited by
        #3

        @davidino in addition to the good reply from @mrdebug, and although you're working with C++ (from your code snippet) you may want to take a look at this post, related to optimizing OpenCV and Python on the Raspberry Pi. Hopefully some hints may help you improve the performance of your environment.

        Upvote the answer(s) that helped you solve the issue
        Use "Topic Tools" button to mark your post as Solved
        Add screenshots via postimage.org
        Don't ask support requests via chat/PM. Please use the forum so others can benefit from the solution in the future

        1 Reply Last reply
        3
        • D Offline
          D Offline
          davidino
          wrote on last edited by
          #4

          Thank you both for your answer.
          I worked something more and the performance has been improved a little bit. Before the frame rate was about 0.15 FPS!, now it's 1-1.8 FPS. Without the ORB algorithm, but simply grabbing the image from camera I can reach up to 40-45 FPS.
          One of the thing that I changed was moving the detectAndCompute of the target image on the thread initialization (after all it's has to be done only one time, not continuously).

          Hello mkdebug,
          Regarding the top+H, the situation is shown below.

          0_1516529591974_5ac905b6-8ebc-49ba-b8e4-dbcabfc7e578-immagine.png

          Yes, I'm using a usb camera, in fact I don't expect to reach the same frame rate as the pi camera, but I'd like to know as much as I can push to obtain the maximum.
          Your solution is interesting, I'm trying to do the same as you. Thank you.

          Hello, Oablo J. Rogina,
          I saw the site that you suggest me, and it's very interesting, especially the deep learning part, unfortunately my OS image is made with yocto, and, at least for the moment, I cannot install programs as freely as with a standard image with apt-get command. But I'll keep it in mind, thank you.

          1 Reply Last reply
          0
          • mrdebugM Offline
            mrdebugM Offline
            mrdebug
            wrote on last edited by
            #5

            Hi. In order to not make your cpu eaten by opencv you should insert a sleep step after every image. You should calculate the frame rate, for example 5 fpc could be enough.

            Need programmers to hire?
            www.labcsp.com
            www.denisgottardello.it
            GMT+1
            Skype: mrdebug

            1 Reply Last reply
            1
            • D Offline
              D Offline
              davidino
              wrote on last edited by davidino
              #6

              Hello mrdebug,
              thank you very much for your suggestion. I've done a second Qthread for calculation. so the cycle is the following.

              • Read cam_image with one thread every QTimer event (200ms). I've inserted a QThread::msleep(100) in the first thread, for letting the second thread to work, as you suggested.
              • Pass the the Mat data to the second thread for calculating ORB algorithm
              • Pass back the Mat, where the algorithm has been applied, to the first thread.
              • Convert Mat file to image and pass the QIMage to GUI thread.

              The frame rate got an increasement up to 9 FPS (which is much more than before!).
              For passing Mat object among threads, I had to register Mat type as follow:

              ....
              Q_DECLARE_METATYPE(Mat)
              
              int main(int argc, char *argv[])
              {
                  qmlRegisterType<VideoCamera>("VideocameraLib", 1, 0, "Videocamera");
                  qRegisterMetaType<Mat>("Mat");
              ....
              

              Concerning the CPU usage, the situation didn't change a lot, although the second thread and msleep.

              0_1517061582408_934efba6-3c9c-4ca7-95d9-a883ccfdb9f8-immagine.png

              If anyone could take a look at my other problem, I would really appreciate it:
              https://forum.qt.io/topic/87039/pass-oncurrentindexchanged-event-to-an-object-in-page1/2

              Thank you again.
              Davidino

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved