Step 1: Install OpenCV software
Follow the following steps mentioned in
https://gist.github.com/dynamicguy/3d1fce8dae65e765f7c4
Here we copy the commands:
# install dependencies
sudo apt-get update
sudo apt-get install -y build-essential
sudo apt-get install -y cmake
sudo apt-get install -y libgtk2.0-dev
sudo apt-get install -y pkg-config
sudo apt-get install -y python-numpy python-dev
sudo apt-get install -y libavcodec-dev libavformat-dev libswscale-dev
sudo apt-get install -y libjpeg-dev libpng-dev libtiff-dev libjasper-dev
sudo apt-get -qq install libopencv-dev build-essential checkinstall cmake pkg-config yasm libjpeg-dev libjasper-dev libavcodec-dev libavformat-dev libswscale-dev libdc1394-22-dev libxine-dev libgstreamer0.10-dev libgstreamer-plugins-base0.10-dev libv4l-dev python-dev python-numpy libtbb-dev libqt4-dev libgtk2.0-dev libmp3lame-dev libopencore-amrnb-dev libopencore-amrwb-dev libtheora-dev libvorbis-dev libxvidcore-dev x264 v4l-utils
# download opencv-2.4.11
wget http://downloads.sourceforge.net/project/opencvlibrary/opencv-unix/2.4.11/opencv-2.4.11.zip
unzip opencv-2.4.11.zip
cd opencv-2.4.11
mkdir release
cd release
# compile and install
cmake -G "Unix Makefiles" -D CMAKE_CXX_COMPILER=/usr/bin/g++ CMAKE_C_COMPILER=/usr/bin/gcc -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D WITH_TBB=ON -D BUILD_NEW_PYTHON_SUPPORT=ON -D WITH_V4L=ON -D INSTALL_C_EXAMPLES=ON -D INSTALL_PYTHON_EXAMPLES=ON -D BUILD_EXAMPLES=ON -D WITH_QT=ON -D WITH_OPENGL=ON -D BUILD_FAT_JAVA_LIB=ON -D INSTALL_TO_MANGLED_PATHS=ON -D INSTALL_CREATE_DISTRIB=ON -D INSTALL_TESTS=ON -D ENABLE_FAST_MATH=ON -D WITH_IMAGEIO=ON -D BUILD_SHARED_LIBS=OFF -D WITH_GSTREAMER=ON ..
make all -j4 # 4 cores
sudo make install
We may get some errors when trying to install some of the libraries in command line. Since if highly depends on the system, we cannot give a general solution here. At the same time, many people have experiences the same problems and it is easy to find the solution through Google.
Step 2: Add Include path and Libraries.
If everything works, now we should have opencv2 installed. The next step is to configure our IDE. In my case, I use the eclipse. The instruction can be found here:
http://docs.opencv.org/2.4/doc/tutorials/introduction/linux_eclipse/linux_eclipse.html
Step 3: Test OpenCV
In this step, we use the first code example in the book Learning OpenCV (https://www.amazon.com/Learning-OpenCV-Computer-Vision-Library/dp/0596516134).
#include "highgui/highgui_c.h" // In the book, we have
// #include "highgui.h"
// which is used in the old
// version of OpenCV
int main()
{
IplImage* img = cvLoadImage( "path-of-an-image-file" );
cvNamedWindow( "Example1", CV_WINDOW_AUTOSIZE );
cvShowImage( "Example1", img );
cvWaitKey( 0 );
cvReleaseImage( &img );
cvDestroyWindow( "Example1" );
}
If we can see a new window of image pop up, we are all good.
Tuesday, May 30, 2017
Sunday, May 28, 2017
Raspeberry Pi - Connect to Wifi and send ip information to email
There is problem with the current setting of my Raspeberry Pi. Every time when it is started, I need to log into my account and connect to wifi. In order to use ssh on my desktop, I also need the ip information of the Raspberry Pi.
To automate this part, we need to write some autostart program. Essentially, we want to write scripts that can be executed upon the start.
In ArchLinux, it can be doen through systemctl. The documentation can be found here:
https://wiki.archlinux.org/index.php/systemd
It takes a while to read through all the sections. Some Useful examples can be found here:
https://www.freedesktop.org/software/systemd/man/systemd.service.html
Here is what we need to do:
Step 1: Create the script that need to be executed upon the start.
In our case, we want to have something like
#!/bin/sh
ip link set wlan0 down
netctl start home_wifi
ifconfig | mail -v -s "IP information" user@gmail.com
After editing the script, make it executable: chmod + x your-script
Step 2: Create a new service
Go to the /etc/systemd/system folder and create a new file
my-autostart.service
[Unit]
Description=Send ip information through email
[Service]
ExecStart=/path/your-script
[Install]
WantedBy=multi-user.target
Save the edit and enable the service by
systemctl enable my-autostart.service
Caveate
Though it can work, the configuration of the service may not be completely correct. It is better to have more fine control on it.
Tuesday, May 23, 2017
Use Raspberry Pi as a server
With the help of gmail, we can use Raspberry Pi as a server. What we need are:
- mail: to send/reply email
- getmail: to get new email messages
The request consists of
- subject which contains [request@me]. This is the request identifier
- request message included in the email message. Each request starts with @begin and ends with @end. Each line in between has the form of attributeName = attributeValue. For example, request = take-picture indicates that this request is asking raspberry-pi to take a picture.
- Check new email messages by calling getmail -n
- Parse the new mail messages if there is any and get the request object
- Process the request
import re import subprocess import os from os import path import hashlib from datetime import datetime import time import subprocess import shlex import logging import glob _currDir = os.path.dirname( os.path.abspath( __file__ ) ) # setup logger logging.basicConfig(level = logging.DEBUG, format = '%(asctime)s %(name)s %(levelname)s %(message)s', datefmt = '%m-%d %H:%M', filename = path.join(_currDir, "_send-emil.log"), filemode ='w') console = logging.StreamHandler() console.setLevel(logging.INFO) formatter = logging.Formatter('%(name)s: %(levelname)s %(message)s') console.setFormatter(formatter) logging.getLogger('').addHandler(console) logging.info( "current directory: {}".format( _currDir ) ) # settings REQUEST_IDENTIFIER = '[request@me]' IDLE = 'the parser is idle' SUBJECT = 'hitted subject' BEGIN = 'beginning-of-request' IMG_FORMAT = 'jpg' RQ_TAKE_PICTURE = 'take-picture' ARG_NUM = 'number' MAIL_DIR = '/home/meretciel/mail/new' IMG_DIR = '/home/meretciel/workspace/camera' RECEIVERS = [ 'meretciel.fr@gmail.com' ] class EmailMessage( object ): _COMMAND_TEMPLATE_PLAIN = r'mail -v -s "{subject}" {receiver}' _COMMAND_TEMPLATE_ATTACHMENT = r'mail -v -s "{subject}" {attachment} {receiver}' def __init__( self, subject = None, message = None, receiver = None, attachment = None ): self._subject = subject self._message = message self._receiver = receiver self._attachment = attachment def _generateEmailCommand( self ): if isinstance( self._receiver, list ): receiver = ';'.join( self._receiver ) else: receiver = self._receiver if not self._attachment: return EmailMessage._COMMAND_TEMPLATE_PLAIN.format( message = self._message, subject = self._subject, receiver = receiver ) if isinstance( self._attachment, list): attachment = ' -a '.join( self._attachment ) attachment = ' -a ' + attachment else: attachment = ' -a ' + self._attachment return EmailMessage._COMMAND_TEMPLATE_ATTACHMENT.format( message = self._message, subject = self._subject, receiver = receiver, attachment = attachment ) def send( self ): ''' send email using mail command. We can also implement this in plain python ''' p1 = subprocess.Popen( shlex.split( r'echo {message}'.format( message = self._message ) ), stdout = subprocess.PIPE, ) p2 = subprocess.Popen( shlex.split( self._generateEmailCommand() ), stdin = subprocess.PIPE ) p2.communicate() def constructCommand( s_command ): l = [ x for x in s_command.split(' ') if x != '' ] return l def executeCommand( s_command ): logging.info( "execute command: {}".format( s_command ) ) subprocess.call( constructCommand( s_command ) ) def getEmail(): executeCommand( "getmail -n" ) def checkNewEmail(): ''' check if there is new ( unread ) emails. ''' ls_output = subprocess.check_output( constructCommand( "ls -lt {}".format( MAIL_DIR ) ) ) ls_output = str( ls_output, "utf-8" ) logging.debug( "ls_output: {}".format( ls_output ) ) ls_output = ls_output.split('\n') ls_output = ls_output[1:] # the first line is total output newFiles = [ x.split(' ')[-1] for x in ls_output ][::-1] newFiles = [ path.join( MAIL_DIR, x ) for x in newFiles if x != '' ] return newFiles def takePicture( number ): ''' ask raspiberry pi to take picture. ''' time = datetime.utcnow() baseFileName = path.join( IMG_DIR, hashlib.sha224( str( time ).encode( "utf-8" ) ).hexdigest() ) commandTemplate = r'/opt/vc/bin/raspistill -n -vf -w 640 -h 480 -e {IMG_FORMAT} {_} -o {baseFileName}%04d.{IMG_FORMAT}'.format( IMG_FORMAT = IMG_FORMAT, baseFileName = baseFileName, _ = "{time}") number = min( 10, int( number ) ) number = max( number, 1 ) if number == 1: command = commandTemplate.format( time = '' ) imgFileNames = [ "{baseFileName}-001.{IMG_FORMAT}".format( baseFileName = baseFileName, IMG_FORMAT = IMG_FORMAT ) ] else: _tl = 2000 # in milliseconds _totalTime = _tl * ( number - 1) _time = "-t {} -tl {}".format( _totalTime, _tl ) command = commandTemplate.format( time = _time ) imgFileNames = ["{baseFileName}{num}.{IMG_FORMAT}".format( baseFileName = baseFileName, num=str(i).zfill(4), IMG_FORMAT=IMG_FORMAT ) for i in range(number)] try: executeCommand( command ) return imgFileNames except Exception as e: logging.error("Error when taking picture") return [] class Request( object ): def __init__( self ): self._requestName = None self._args = {} def load( self, attrName, value ): if attrName == 'request': self._requestName = value else: self._args.update( { attrName : value } ) def process( self ): if self._requestName: logging.info( 'processing {}'.format( self ) ) if self._requestName.lower() == RQ_TAKE_PICTURE: number = self._args.get( ARG_NUM, 1 ) imgFiles = takePicture( number ) logging.debug( '<2> image files : {}'.format( imgFiles ) ) newEmail = EmailMessage( subject = 'New Images', message = '', receiver = RECEIVERS, attachment = imgFiles ) newEmail.send() for fn in imgFiles: logging.info( "removing the file: {}".format( fn ) ) os.remove( fn ) def __repr__( self ): return "Request( name={}, args={} )".format( self._requestName, str( self._args ) ) def _parseEmail( f, state, requests ): if state == IDLE: line = f.readline() while line: if 'Subject' in line and REQUEST_IDENTIFIER in line: state = SUBJECT break line = f.readline() return line, f, state, requests if state == SUBJECT: line = f.readline() while line: if '@begin' in line: state = BEGIN break line = f.readline() return line, f, state, requests if state == BEGIN: pattern = r'(?P<attrName>\w+)\s*=\s*(?P<value>.+)' line = f.readline() request = Request() while line: if '@end' in line: requests.append( request ) state = IDLE break res = re.search( pattern, line ) if res: attrName = res.group( 'attrName' ) value = res.group( 'value' ) request.load( res.group( 'attrName' ), res.group( 'value' ) ) line = f.readline() return line, f, state, requests def parseEmail( msgFile ): logging.info("parsing email file {}".format( msgFile ) ) with open( msgFile ) as f: state = IDLE line = '__start__' requests = [] while line: logging.info( "processing line : {}".format( line ) ) line, f, state, request = _parseEmail( f, state, requests ) return requests def removeNewMsgFiles( newMsgFiles ): for item in newMsgFiles: os.remove( item ) def getNewRequestFromEmail(): getEmail() newMsgFiles = checkNewEmail() logging.debug(" <1> New messages : {}".format( str( newMsgFiles ) ) ) requests = [] for newMsgFile in newMsgFiles: requests.extend( parseEmail( newMsgFile ) ) removeNewMsgFiles( newMsgFiles ) return requests if __name__ == '__main__': existingFiles = glob.glob( path.join( MAIL_DIR, r'*.alarmpi' ) ) for f in existingFiles: os.remove( f ) while True: logging.info( "waiting for request." ) requests = getNewRequestFromEmail() for request in requests: request.process() time.sleep( 10. )
--END--
Subscribe to:
Posts (Atom)