Seite 6 von 7

Re: Quick Guide für Raspberry Pi: C/C++ mit Geany für Dummies

Verfasst: 5. Aug 2016 11:27
von HaWe
Platzhalter

Re: Quick Guide für Raspberry Pi: C/C++ mit Geany für Dummies

Verfasst: 5. Aug 2016 11:27
von HaWe
Platzhalter

Re: Quick Guide für Raspberry Pi: C/C++ mit Geany für Dummies

Verfasst: 5. Aug 2016 11:28
von HaWe
sinnvolle C/C++ Zusatzfunktionen und Tipps (optional)
(aus verschiedenen Foren zusammengetragen)

Verwendung der C11 Datentypen int8_t, int16_t usw...:
notwendig ist dafür das #include

Code: Alles auswählen

#include <stdint.h>
Datentypen-Liste s. hier: http://www.raspberry-projects.com/pi/programming-in-c/memory/variables

###########################################################

wmctrl - Terminal-Window mit veränderlicher Position und Größe:
wmctrl installieren:

Code: Alles auswählen

sudo apt-get wmctrl


Nun kann man im C-Programm die Fensterposition und -Größe per system call aufrufen:

Code: Alles auswählen

// LXTerminal window at pos 200,200, size 800x640
system("wmctrl -r LXTerminal -e 0,200,200,800,640"); // no blanks between numbers!


###########################################################

rpiconio.h: Ersatz für kbhit() und getch():

Code: Alles auswählen

#ifndef _RPICONIO_H
#define   _RPICONIO_H

// courtesy of AndyD, raspberrypi.org forums, and peterfido, roboternetz.de forum
// version 003

#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <termio.h>
#include <unistd.h>

#include <linux/input.h>
#include <termios.h>
#include <signal.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/select.h>


// Terminal: move cursor
#define cursup    "\033[A"
#define curshome  "\033[0;0H"
#define cls_lxt   "\033[2J"

// keyboard dev
int    fkbd;
char * kbdin = "/dev/input/event0";
struct input_event ev[64];

int shiftl=0;
int shiftr=0;
int _keyshift_=0; // mod keypress state
int ctrll=0;
int ctrlr=0;
int _keyctrl_=0; // mod keypress state
int capsl=0;
int altl=0;
int altgr=0;
int _keyalt_=0;  // mod keypress state
int windows=0;
int kontext=0;
int _keypress_=0;  // keypress state
int modscode=0;
volatile int _kbscode_ ;

#define _ESC_   1
#define _F1_   59
#define _F2_   60
#define _F3_   61
#define _F4_   62
#define _F5_   63
#define _F6_   64
#define _F7_   65
#define _F8_   66
#define _F9_   67
#define _F10_  68
#define _F11_  69
#define _F12_  70



//*************************************************************
// conio.h - mimics
//*************************************************************

bool kbhit(void)
{
    struct termios original;
    tcgetattr(STDIN_FILENO, &original);

    struct termios term;
    memcpy(&term, &original, sizeof(term));

    term.c_lflag &= ~ICANON;
    tcsetattr(STDIN_FILENO, TCSANOW, &term);

    int characters_buffered = 0;
    ioctl(STDIN_FILENO, FIONREAD, &characters_buffered);

    tcsetattr(STDIN_FILENO, TCSANOW, &original);

    bool pressed = (characters_buffered != 0);

    return pressed;
}

void echoOff(void)
{
    struct termios term;
    tcgetattr(STDIN_FILENO, &term);

    term.c_lflag &= ~ECHO;
    tcsetattr(STDIN_FILENO, TCSANOW, &term);
}

void echoOn(void)
{
    struct termios term;
    tcgetattr(STDIN_FILENO, &term);

    term.c_lflag |= ECHO;
    tcsetattr(STDIN_FILENO, TCSANOW, &term);
}




//*************************************************************
// keyboard scancode
//*************************************************************

int getkbscancode() {
   int  rd,  size = sizeof (struct input_event);
   int keybscan=0;  // scan code "normal key"
   
   
   if ((rd = read (fkbd, ev, size * 64)) < size)
          printf ("Fehler mit Tastatur");
       
        if (ev[1].type != EV_KEY) return 0;
       
        if (ev[1].value==0){         //Taste losgelassen
                switch (ev[1].code) {
                    case 42: shiftl=0;   break;
                    case 54: shiftr=0;   break;
                    case 29: ctrll=0;    break;
                    case 97: ctrlr=0;    break;
                    case 56: altl=0;     break;
                    case 125: windows=0; break;
                    case 100: altgr=0;   break;
                    case 127: kontext=0; break;
                }
        }
        else
        {
            if (ev[1].value==1){           
             //==1 fuer nur einen Druck ohne Wiederholung. >=1 fuer Erkennung von gedrueckt gehaltener Taste
                 modscode = 0;
                 switch (ev[1].code) {
                    case 42: shiftl=1;   break;
                    case 54: shiftr=1;   break;
                    case 29: ctrll=1;    break;
                    case 97: ctrlr=1;    break;
                    case 56: altl=1;     break;
                    case 125: windows=1; break;
                    case 100: altgr=1;   break;
                    case 127: kontext=1; break;                   
                   
                    // Ab hier 'normale Tasten'                   
                    default: keybscan=ev[1].code;// Scancode ablegen
                   
                    _keypress_ = keybscan;  // standard keypress state
                    _keyshift_ = 0;         // reset modifier key pressed
                    _keyalt_   = 0;
                    _keyctrl_  = 0;
                                       
                    if(shiftl || shiftr ) { modscode+=1024; _keyshift_=1; }
                    if(ctrll  || ctrlr  ) { modscode+=2048; _keyctrl_=1; }
                    if(altl)              { modscode+=4096; _keyalt_=1; }
                    if(altgr)             { modscode+=(2048+4096);  _keyalt_=1; _keyctrl_=1; }
                    if(windows)           modscode+=8192;   
                    if(kontext)           modscode+=16384;
                                   
                    if(keybscan>0) {
                       _kbscode_= keybscan + modscode;
                       return keybscan;
                    }
                    else  return 0 ;
                //break;
                }
            }
        }
        return 0 ;
}
 

int setupKbdin() {
  if ((fkbd = open (kbdin, O_RDONLY)) == -1){
        printf ("Keyboard error");
        return -1;
  }
  else return 0;
}

#endif


Testcode:

Code: Alles auswählen

//=========================================================================================
// Testcode:
//=========================================================================================

#include <stdio.h>
#include <unistd.h>

#include "rpiconio.h"

int main(void)
{
    long i=0;
    int c = '\0';
   
    while (c != 'q')   {   // press 'q' to quit
        if (kbhit())
        {
            echoOff();
            c = getchar();
            echoOn(); 
            printf("(hier ggf. auskommentieren: got key \'%c\'\n", c);
            if(c==27) { printf("\nuser break\n"); return 1;  }
        }
        delay(100);
    }
    echoOn(); 
    return 0;
}


###########################################################

Zenity : Datei-Auswahl im Fenster-Menü ähnlich OpenFileDialog/SaveFileDialog:

zenity --file-selection über pipe einlesen:

Code: Alles auswählen

popen("zenity --file-selection", "r"))


Beispielcode (Danke an peterfido und Sisor, Roboternetz-Forum):

Code: Alles auswählen

FILE *f;

    if(!(f = popen("zenity --file-selection", "r"))){
      strcpy(Dateiname,"Falsch");       
      exit(1);
    }
    char Text[1024]="";
    fgets(Text, sizeof(Text), f);
    fclose(f);
    if(strlen(Text)<2){ //Kein Dateiname übergeben / Abbrechen geklickt, etc
        strcpy(Dateiname,"Falsch");
    }else{ //Dateiname sollte in Text stehen.
      strcpy(Dateiname,Text);
    }

Code: Alles auswählen

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main() {
  FILE *f;
  char Dateiname[1024] = "";
  int c;


  /* Zenity für File-Dialog benutzen */
  freopen("/dev/null", "w", stderr); // Warnungen von zenity ignorieren
  if(!(f = popen("zenity --file-selection", "r"))){
    strcpy(Dateiname, "Falsch");       
    exit(1);
  }
  freopen("/dev/tty", "w", stderr);
  fgets(Dateiname, sizeof(Dateiname), f);
  fclose(f);
  if(strlen(Dateiname) < 2){ //Kein Dateiname übergeben / Abbrechen geklickt, etc
    strcpy(Dateiname, "Falsch");
  }


  /* Inhalt der Datei ausgeben */
  printf("Dateiname: %s", Dateiname);
  Dateiname[strlen(Dateiname)-1] = '\0'; // '\n'-Stringende entfernen
  f = fopen(Dateiname, "r");
  if (f) {
     while ((c = fgetc(f)) != EOF)     putchar(c);
     fclose(f);
  }
}

http://www.roboternetz.de/community/thr ... post628328


###########################################################

Re: Quick Guide für Raspberry Pi: C/C++ mit Geany für Dummies

Verfasst: 5. Aug 2016 11:29
von HaWe
Platzhalter

Re: Quick Guide für Raspberry Pi: C/C++ mit Geany für Dummies

Verfasst: 20. Nov 2016 21:05
von HaWe
Arduino-IDE auf Raspberry Pi installieren
(Arduino IDE zum Programmieren von Arduiinos wie vom PC aus)

https://www.raspberrypi.org/forums/viewtopic.php?f=91&t=166183&p=1070661#p1070661 hat geschrieben:1. Go to https://www.arduino.cc and download the Arduino IDE 1.6.12 for the ARM processor.
2. Open a terminal window.
3. Type cd ~/Downloads
4. Type tar -xvf arduino -1.6.12-*.tar.xz
5. Type sudo mv arduino-1.6.12 /opt
6. Type cd /opt/arduino-1.6.12/
7. Type chmod +x install.sh
8. Type ./install.sh

Re: Quick Guide für Raspberry Pi: C/C++ mit Geany für Dummies

Verfasst: 23. Nov 2016 19:22
von HaWe
Arduino Framework für den Raspberry Pi
(Arduino Sketch-kompatible API um den Raspi zu programmieren)

https://github.com/me-no-dev/RasPiArduino

Re: Quick Guide für Raspberry Pi: C/C++ mit Geany für Dummies

Verfasst: 23. Nov 2016 19:26
von HaWe

Re: Quick Guide für Raspberry Pi: C/C++ mit Geany für Newbies

Verfasst: 23. Nov 2016 19:33
von HaWe

Re: Quick Guide für Raspberry Pi: C/C++ mit Geany für Newbies

Verfasst: 23. Nov 2016 19:38
von HaWe
b) openCV: Installation, Libraries, Compile/Link Flags

Installation:

Code: Alles auswählen

sudo apt-get update
sudo apt-get upgrade
# opencv
sudo apt-get install libopencv-dev

#Auswahl von Cam Tools:
apt sarch webcam

# cam tool guvcview
sudo apt install guvcview
# alternativ z.B.:
# cam tool camorama
sudo apt install camorama



test program:

Code: Alles auswählen

#include "opencv2/opencv.hpp"
using namespace cv;
int main(int argc, char** argv)
{
    VideoCapture cap;
    // open the default camera, use something different from 0 otherwise;
    // Check VideoCapture documentation.
    if(!cap.open(0))
        return 0;
    for(;;)
    {
          Mat frame;
          cap >> frame;
          if( frame.empty() ) break; // end of video stream
          imshow("this is you, smile! :)", frame);
          if( (waitKey(10)%256) == 27 ) break; // waitKeypatch: check for 10ms: then stop capturing by pressing ESC=27
    }
    // the camera will be closed automatically upon exit
    // cap.close();
    return 0;
}


compile parameters/flags:
gcc -o test test.cpp -lopencv_highgui -lopencv_core -lstdc++
g++ -o test test.cpp -lopencv_highgui -lopencv_core

komplette Übersicht über alle vorhandenen flags für alle verfügbaren Module:
pkg-config --libs-only-l opencv

Code: Alles auswählen

-lopencv_calib3d -lopencv_contrib -lopencv_core -lopencv_features2d -lopencv_flann -lopencv_gpu -lopencv_highgui -lopencv_imgproc -lopencv_legacy -lopencv_ml -lopencv_objdetect -lopencv_ocl -lopencv_photo -lopencv_stitching -lopencv_superres -lopencv_ts -lopencv_video -lopencv_videostab


es scheint möglich zusein, dass man alle evtl. nötigen openCV libs auf einen Schlag mitcompiliert/linkt stattdessen durch den Flag

Code: Alles auswählen

$(pkg-config --cflags --libs opencv)

Re: Quick Guide für Raspberry Pi: C/C++ mit Geany für Newbies

Verfasst: 3. Dez 2016 13:41
von HaWe
c) openCV Anwendungen:

1.) Color Blob separieren, Anzeige auf s/w Threshold Image


http://opencv-srf.blogspot.de/2010/09/object-detection-using-color-seperation.html

Code: Alles auswählen

#include <iostream>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

/*
 * build flags:
 -lopencv_calib3d -lopencv_contrib -lopencv_core -lopencv_features2d -lopencv_flann -lopencv_gpu -lopencv_highgui -lopencv_imgproc -lopencv_legacy -lopencv_ml -lopencv_objdetect -lopencv_ocl -lopencv_photo -lopencv_stitching -lopencv_superres -lopencv_ts -lopencv_video -lopencv_videostab
*/

/*  exp. thesholds:
 *       blue  red
 *
 * LowH  125     0
 * HighH 150   179
 * LowS  100   127
 * HighS 250   255
 * LowV   50   255
 * HighV 255   255
 * */

using namespace cv;
using namespace std;

 int main( int argc, char** argv )
 {
    VideoCapture cap(0); //capture the video from web cam

    if ( !cap.isOpened() )  // if not success, exit program
    {
         cout << "Cannot open the web cam" << endl;
         return -1;
    }

    namedWindow("Control", CV_WINDOW_AUTOSIZE); //create a window called "Control"

 int iLowH = 0;
 int iHighH = 179;

 int iLowS = 0;
 int iHighS = 255;

 int iLowV = 0;
 int iHighV = 255;

 //Create trackbars in "Control" window
 cvCreateTrackbar("LowH", "Control", &iLowH, 179); //Hue (0 - 179)
 cvCreateTrackbar("HighH", "Control", &iHighH, 179);

 cvCreateTrackbar("LowS", "Control", &iLowS, 255); //Saturation (0 - 255)
 cvCreateTrackbar("HighS", "Control", &iHighS, 255);

 cvCreateTrackbar("LowV", "Control", &iLowV, 255); //Value (0 - 255)
 cvCreateTrackbar("HighV", "Control", &iHighV, 255);

    while (true)
    {
        Mat imgOriginal;

        bool bSuccess = cap.read(imgOriginal); // read a new frame from video

         if (!bSuccess) //if not success, break loop
        {
             cout << "Cannot read a frame from video stream" << endl;
             break;
        }

  Mat imgHSV;

  cvtColor(imgOriginal, imgHSV, COLOR_BGR2HSV); //Convert the captured frame from BGR to HSV
 
  Mat imgThresholded;

  inRange(imgHSV, Scalar(iLowH, iLowS, iLowV), Scalar(iHighH, iHighS, iHighV), imgThresholded); //Threshold the image
     
  //morphological opening (remove small objects from the foreground)
  erode(imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)) );
  dilate( imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)) );

  //morphological closing (fill small holes in the foreground)
  dilate( imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)) );
  erode(imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)) );

  imshow("Thresholded Image", imgThresholded); //show the thresholded image
  imshow("Original", imgOriginal); //show the original image

        if (waitKey(30) == 27) //wait for 'esc' key press for 30ms. If 'esc' key is pressed, break loop
       {
            cout << "esc key is pressed by user" << endl;
            break;
       }
    }
 
   return 0;

}


Hinweis:

Code: Alles auswählen

Hue values of basic colors
        Orange  0-22
        Yellow  22- 38
        Green   38-75
        Blue    75-130
        Violet  130-160
        Red     160-179



2.) Tracking von farbigen Objekten:

tracking colored objects:
http://opencv-srf.blogspot.de/2010/09/o ... ation.html

Code: Alles auswählen

#include <iostream>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

using namespace cv;
using namespace std;

 int main( int argc, char** argv )
 {
    VideoCapture cap(0); //capture the video from webcam

    if ( !cap.isOpened() )  // if not success, exit program
    {
         cout << "Cannot open the web cam" << endl;
         return -1;
    }

    namedWindow("Control", CV_WINDOW_AUTOSIZE); //create a window called "Control"

 int iLowH = 170;
 int iHighH = 179;

 int iLowS = 150;
 int iHighS = 255;

 int iLowV = 60;
 int iHighV = 255;

 //Create trackbars in "Control" window
 createTrackbar("LowH", "Control", &iLowH, 179); //Hue (0 - 179)
 createTrackbar("HighH", "Control", &iHighH, 179);

 createTrackbar("LowS", "Control", &iLowS, 255); //Saturation (0 - 255)
 createTrackbar("HighS", "Control", &iHighS, 255);

 createTrackbar("LowV", "Control", &iLowV, 255);//Value (0 - 255)
 createTrackbar("HighV", "Control", &iHighV, 255);

 int iLastX = -1;
 int iLastY = -1;

 //Capture a temporary image from the camera
 Mat imgTmp;
 cap.read(imgTmp);

 //Create a black image with the size as the camera output
 Mat imgLines = Mat::zeros( imgTmp.size(), CV_8UC3 );;
 

    while (true)
    {
        Mat imgOriginal;

        bool bSuccess = cap.read(imgOriginal); // read a new frame from video



         if (!bSuccess) //if not success, break loop
        {
             cout << "Cannot read a frame from video stream" << endl;
             break;
        }

  Mat imgHSV;

  cvtColor(imgOriginal, imgHSV, COLOR_BGR2HSV); //Convert the captured frame from BGR to HSV
 
  Mat imgThresholded;

  inRange(imgHSV, Scalar(iLowH, iLowS, iLowV), Scalar(iHighH, iHighS, iHighV), imgThresholded); //Threshold the image
     
  //morphological opening (removes small objects from the foreground)
  erode(imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)) );
  dilate( imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)) );

  //morphological closing (removes small holes from the foreground)
  dilate( imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)) );
  erode(imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)) );

  //Calculate the moments of the thresholded image
  Moments oMoments = moments(imgThresholded);

  double dM01 = oMoments.m01;
  double dM10 = oMoments.m10;
  double dArea = oMoments.m00;

  // if the area <= 10000, I consider that the there are no object in the image and it's because of the noise, the area is not zero
  if (dArea > 10000)
  {
   //calculate the position of the ball
   int posX = dM10 / dArea;
   int posY = dM01 / dArea;       
       
   if (iLastX >= 0 && iLastY >= 0 && posX >= 0 && posY >= 0)
   {
    //Draw a red line from the previous point to the current point
    line(imgLines, Point(posX, posY), Point(iLastX, iLastY), Scalar(0,0,255), 2);
   }

   iLastX = posX;
   iLastY = posY;
  }

  imshow("Thresholded Image", imgThresholded); //show the thresholded image

  imgOriginal = imgOriginal + imgLines;
  imshow("Original", imgOriginal); //show the original image

        if ( (waitKey(30)%256) == 27) //wait for 'esc' key press for 30ms. If 'esc' key is pressed, break loop
       {
            cout << "esc key is pressed by user" << endl;
            break;
       }
    }

   return 0;
}



3.) Hinweise und weitere Links
a) Hinweise:

Die openCV waitKey() Funktion arbeitet offenbar (zumindest) nicht korrekt mit Raspian zusammen -
Man muss aus dem gelesenen Wert das LSB extrahieren, damit eine Taste per ASCII Code erkannt wird:

Code: Alles auswählen

 (waitKey(30)%256) == 27  // anstelle  waitKey(30) == 27


ein kleines #define behebt das Problem:
#define waitkey(n) (waitKey(n)%256)


b) weitere Links:

Object tracking:
https://www.youtube.com/watch?v=6Sw_KEe4a9c
https://www.youtube.com/watch?v=hQ-bpfdWQh8 Code: https://github.com/akaifi/MultiObjectTr ... sedOnColor
https://www.youtube.com/watch?v=j0POMSW ... freload=10 (kein Code bisher)

Face recognition:
http://docs.opencv.org/2.4/modules/cont ... ition.html

Re: Quick Guide für Raspberry Pi: C/C++ mit Geany für Newbies

Verfasst: 19. Jan 2017 21:52
von HaWe
Platzhalter

Re: Quick Guide für Raspberry Pi: C/C++ mit Geany für Newbies

Verfasst: 19. Jan 2017 21:54
von HaWe
Platzhalter

Re: Quick Guide für Raspberry Pi: C/C++ mit Geany für Newbies

Verfasst: 15. Mär 2017 21:55
von HaWe
Platzhalter

Re: Quick Guide für Raspberry Pi: C/C++ mit Geany für Newbies

Verfasst: 15. Mär 2017 21:55
von HaWe
Platzhalter

Re: Quick Guide für Raspberry Pi: C/C++ mit Geany für Newbies

Verfasst: 15. Mär 2017 21:56
von HaWe
GTK+, GTK++ :

1.) gtkIOStream: :

http://www.flatmax.org/gtkiostream/html/index.html
http://www.flatmax.org/gtkiostream/html ... ample.html

einfacher Programm-Rumpf:

Code: Alles auswählen

#include <gtkInterface.H>

int main(){
  gtk_init( &argc, &argv ); // init GTK   
  GtkInterface topWindow; // Create the top box       
  gtk_main(); // run GTK+                                                       
}


zusätzliche compile/build flags für gcc mit Geany:

Code: Alles auswählen

$(pkg-config gtk+-2.0 --cflags --libs)   -I/home/pi/gtkiostream-1.5.0/include


weitere Tutorials hierzu sind hier verlinkt:
Overview: https://www.raspberrypi.org/forums/view ... 7&t=173531


Nachteil:
für sehr einfache Anwendungen zwar einigermaßen schnell zu benutzen, aber dann wird's schnell schwierig, auch wegen ziemlich schlechtem Support von Seiten des Autors.