opencv: Switchover to use GoCV and OpenCV 3.3

Signed-off-by: deadprogram <ron@hybridgroup.com>
This commit is contained in:
deadprogram 2017-10-05 17:05:10 +02:00
parent e33300197b
commit 31131780d4
12 changed files with 156 additions and 69 deletions

View File

@ -13,26 +13,46 @@ matrix:
addons: addons:
apt: apt:
packages: packages:
- libcv-dev - libgmp-dev
- libcvaux-dev - build-essential
- libhighgui-dev - cmake
- libopencv-dev - git
- libgtk2.0-dev
- pkg-config
- libavcodec-dev
- libavformat-dev
- libswscale-dev
- libtbb2
- libtbb-dev
- libjpeg-dev
- libpng-dev
- libtiff-dev
- libjasper-dev
- libdc1394-22-dev
- libsdl2-dev - libsdl2-dev
- libsdl2-image-dev - libsdl2-image-dev
- libsdl2-2.0.0 - libsdl2-2.0.0
- libusb-dev - libusb-dev
- xvfb - xvfb
- unzip - unzip
- libgtk2.0-0
before_install: before_install:
- ./travis_build_opencv.sh
- export PKG_CONFIG_PATH=$(pkg-config --variable pc_path pkg-config):$HOME/usr/lib/pkgconfig
- export INCLUDE_PATH=$HOME/usr/include:${INCLUDE_PATH}
- export LD_LIBRARY_PATH=$HOME/usr/lib:${LD_LIBRARY_PATH}
- sudo ln /dev/null /dev/raw1394
- cd $HOME/gopath/src/gobot.io/x/gobot - cd $HOME/gopath/src/gobot.io/x/gobot
- go get github.com/axw/gocov/gocov - go get github.com/axw/gocov/gocov
before_cache:
- rm -f $HOME/fresh-cache
install: install:
- make deps - make deps
before_script: before_script:
- export DISPLAY=:99.0 - export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start - sh -e /etc/init.d/xvfb start
script: script:
- export CGO_CPPFLAGS="-I${HOME}/usr/include"
- export CGO_LDFLAGS="-L${HOME}/usr/lib -lopencv_core -lopencv_videoio -lopencv_imgproc -lopencv_highgui -lopencv_imgcodecs -lopencv_objdetect -lopencv_calib3d"
- echo "Ensuring code is well formatted"; ! gofmt -s -d . | read - echo "Ensuring code is well formatted"; ! gofmt -s -d . | read
- bash -c 'set -e; echo "" > coverage.txt; for d in $(go list ./...); do go test -covermode=set -coverprofile=p.out $d; if [ -f p.out ]; then cat p.out >> coverage.txt; rm p.out; fi; done' - bash -c 'set -e; echo "" > coverage.txt; for d in $(go list ./...); do go test -covermode=set -coverprofile=p.out $d; if [ -f p.out ]; then cat p.out >> coverage.txt; rm p.out; fi; done'
after_success: after_success:
@ -42,3 +62,8 @@ branches:
- gobot.io - gobot.io
- /^gobot-.*$/ - /^gobot-.*$/
secure: "HggklzWOwKqImvjQe1yvojCoTaUBDrOVXRjsrZaoTaKpUtmho1tpCMtKF1dbyT0T5Y68P6f9e/XyANWVeziJNZ+YmNkY+CNdNYHiNnpl8att3MuL4hpwKDPAqLK8H2G+71j3O/rBvf6oIJHtSEesR5Sbb+2fSmhNFtLrDgp5FZA=" secure: "HggklzWOwKqImvjQe1yvojCoTaUBDrOVXRjsrZaoTaKpUtmho1tpCMtKF1dbyT0T5Y68P6f9e/XyANWVeziJNZ+YmNkY+CNdNYHiNnpl8att3MuL4hpwKDPAqLK8H2G+71j3O/rBvf6oIJHtSEesR5Sbb+2fSmhNFtLrDgp5FZA="
# Caching so the next build will be fast as possible.
cache:
timeout: 1000
directories:
- $HOME/usr

View File

@ -50,7 +50,7 @@ deps:
github.com/eclipse/paho.mqtt.golang \ github.com/eclipse/paho.mqtt.golang \
github.com/hashicorp/go-multierror \ github.com/hashicorp/go-multierror \
github.com/hybridgroup/go-ardrone/client \ github.com/hybridgroup/go-ardrone/client \
github.com/lazywei/go-opencv \ github.com/hybridgroup/gocv \
github.com/mgutz/logxi/v1 \ github.com/mgutz/logxi/v1 \
github.com/nats-io/nats \ github.com/nats-io/nats \
github.com/sigurn/crc8 \ github.com/sigurn/crc8 \

View File

@ -7,11 +7,11 @@ package main
import ( import (
"path" "path"
"runtime" "runtime"
"time" //"time"
cv "github.com/lazywei/go-opencv/opencv"
"gobot.io/x/gobot" "gobot.io/x/gobot"
"gobot.io/x/gobot/platforms/opencv" "gobot.io/x/gobot/platforms/opencv"
"github.com/hybridgroup/gocv"
) )
func main() { func main() {
@ -22,20 +22,12 @@ func main() {
camera := opencv.NewCameraDriver(0) camera := opencv.NewCameraDriver(0)
work := func() { work := func() {
var image *cv.IplImage
camera.On(opencv.Frame, func(data interface{}) { camera.On(opencv.Frame, func(data interface{}) {
image = data.(*cv.IplImage) i := data.(gocv.Mat)
})
gobot.Every(500*time.Millisecond, func() {
if image != nil {
i := image.Clone()
faces := opencv.DetectFaces(cascade, i) faces := opencv.DetectFaces(cascade, i)
i = opencv.DrawRectangles(i, faces, 0, 255, 0, 5) opencv.DrawRectangles(i, faces, 0, 255, 0, 5)
window.ShowImage(i) window.ShowImage(i)
} window.WaitKey(1)
}) })
} }

View File

@ -5,7 +5,7 @@
package main package main
import ( import (
cv "github.com/lazywei/go-opencv/opencv" "github.com/hybridgroup/gocv"
"gobot.io/x/gobot" "gobot.io/x/gobot"
"gobot.io/x/gobot/platforms/opencv" "gobot.io/x/gobot/platforms/opencv"
) )
@ -15,8 +15,10 @@ func main() {
camera := opencv.NewCameraDriver(0) camera := opencv.NewCameraDriver(0)
work := func() { work := func() {
camera.On(camera.Event("frame"), func(data interface{}) { camera.On(opencv.Frame, func(data interface{}) {
window.ShowImage(data.(*cv.IplImage)) img := data.(gocv.Mat)
window.ShowImage(img)
window.WaitKey(1)
}) })
} }

View File

@ -6,14 +6,14 @@ For more info about OpenCV click [here](http://opencv.org/)
## How to Install ## How to Install
This package requires OpenCV version 2.4 to be installed on your system. Please note that it is not compatible with OpenCV 3.x at this time. This package requires OpenCV version 3.3 to be installed on your system.
### OSX ### OSX
To install OpenCV on OSX using Homebrew: To install OpenCV on OSX using Homebrew:
``` ```
$ brew tap homebrew/science && brew install opencv $ brew install opencv
``` ```
### Ubuntu ### Ubuntu
@ -44,7 +44,7 @@ Example using the camera.
package main package main
import ( import (
cv "github.com/lazywei/go-opencv/opencv" "github.com/hybridgroup/gocv"
"gobot.io/x/gobot" "gobot.io/x/gobot"
"gobot.io/x/gobot/platforms/opencv" "gobot.io/x/gobot/platforms/opencv"
) )
@ -54,8 +54,10 @@ func main() {
camera := opencv.NewCameraDriver(0) camera := opencv.NewCameraDriver(0)
work := func() { work := func() {
camera.On(camera.Event("frame"), func(data interface{}) { camera.On(opencv.Frame, func(data interface{}) {
window.ShowImage(data.(*cv.IplImage)) img := data.(gocv.Mat)
window.ShowImage(img)
window.WaitKey(1)
}) })
} }

View File

@ -5,13 +5,12 @@ import (
"time" "time"
cv "github.com/lazywei/go-opencv/opencv" "github.com/hybridgroup/gocv"
"gobot.io/x/gobot" "gobot.io/x/gobot"
) )
type capture interface { type capture interface {
RetrieveFrame(int) *cv.IplImage Read(img gocv.Mat) bool
GrabFrame() bool
} }
const ( const (
@ -40,9 +39,9 @@ func NewCameraDriver(source interface{}, v ...time.Duration) *CameraDriver {
start: func(c *CameraDriver) (err error) { start: func(c *CameraDriver) (err error) {
switch v := c.Source.(type) { switch v := c.Source.(type) {
case string: case string:
c.camera = cv.NewFileCapture(v) c.camera, _ = gocv.VideoCaptureFile(v)
case int: case int:
c.camera = cv.NewCameraCapture(v) c.camera, _ = gocv.VideoCaptureDevice(v)
default: default:
return errors.New("Unknown camera source") return errors.New("Unknown camera source")
} }
@ -74,13 +73,11 @@ func (c *CameraDriver) Start() (err error) {
if err := c.start(c); err != nil { if err := c.start(c); err != nil {
return err return err
} }
img := gocv.NewMat()
go func() { go func() {
for { for {
if c.camera.GrabFrame() { if ok := c.camera.Read(img); ok {
image := c.camera.RetrieveFrame(1) c.Publish(Frame, img)
if image != nil {
c.Publish(Frame, image)
}
} }
time.Sleep(c.interval) time.Sleep(c.interval)
} }

View File

@ -1,17 +1,15 @@
package opencv package opencv
import cv "github.com/lazywei/go-opencv/opencv" import (
"github.com/hybridgroup/gocv"
)
type testCapture struct{} type testCapture struct{}
func (c *testCapture) RetrieveFrame(i int) *cv.IplImage { func (c *testCapture) Read(img gocv.Mat) bool {
return &cv.IplImage{}
}
func (c *testCapture) GrabFrame() bool {
return true return true
} }
type testWindow struct{} type testWindow struct{}
func (w *testWindow) ShowImage(i *cv.IplImage) { return } func (w *testWindow) ShowImage(img gocv.Mat) { return }

View File

@ -1,26 +1,35 @@
package opencv package opencv
import ( import (
cv "github.com/lazywei/go-opencv/opencv" "image"
"image/color"
"github.com/hybridgroup/gocv"
) )
var classifier *gocv.CascadeClassifier
// loadHaarClassifierCascade returns open cv HaarCascade loaded // loadHaarClassifierCascade returns open cv HaarCascade loaded
func loadHaarClassifierCascade(haar string) *cv.HaarCascade { func loadCascadeClassifier(haar string) *gocv.CascadeClassifier {
return cv.LoadHaarClassifierCascade(haar) if classifier != nil {
return classifier
}
c := gocv.NewCascadeClassifier()
c.Load(haar)
classifier = &c
return classifier
} }
// DetectFaces loads Haar cascade to detect face objects in image // DetectFaces loads Haar cascade to detect face objects in image
func DetectFaces(haar string, image *cv.IplImage) []*cv.Rect { func DetectFaces(haar string, img gocv.Mat) []image.Rectangle {
return loadHaarClassifierCascade(haar).DetectObjects(image) return loadCascadeClassifier(haar).DetectMultiScale(img)
} }
// DrawRectangles uses Rect array values to return image with rectangles drawn. // DrawRectangles uses Rect array values to return image with rectangles drawn.
func DrawRectangles(image *cv.IplImage, rect []*cv.Rect, r int, g int, b int, thickness int) *cv.IplImage { func DrawRectangles(img gocv.Mat, rects []image.Rectangle, r int, g int, b int, thickness int) {
for _, value := range rect { for _, rect := range rects {
cv.Rectangle(image, gocv.Rectangle(img, rect, color.RGBA{uint8(r), uint8(g), uint8(b), 0}, thickness)
cv.Point{value.X() + value.Width(), value.Y()},
cv.Point{value.X(), value.Y() + value.Height()},
cv.NewScalar(float64(b), float64(g), float64(r), 0), thickness, 1, 0)
} }
return image return
} }

View File

@ -5,14 +5,14 @@ import (
"runtime" "runtime"
"testing" "testing"
cv "github.com/lazywei/go-opencv/opencv" "github.com/hybridgroup/gocv"
"gobot.io/x/gobot/gobottest" "gobot.io/x/gobot/gobottest"
) )
func TestUtils(t *testing.T) { func TestUtils(t *testing.T) {
_, currentfile, _, _ := runtime.Caller(0) _, currentfile, _, _ := runtime.Caller(0)
image := cv.LoadImage(path.Join(path.Dir(currentfile), "lena-256x256.jpg")) image := gocv.IMRead(path.Join(path.Dir(currentfile), "lena-256x256.jpg"), gocv.IMReadColor)
rect := DetectFaces("haarcascade_frontalface_alt.xml", image) rect := DetectFaces("haarcascade_frontalface_alt.xml", image)
gobottest.Refute(t, len(rect), 0) gobottest.Refute(t, len(rect), 0)
gobottest.Refute(t, DrawRectangles(image, rect, 0, 0, 0, 0), nil) DrawRectangles(image, rect, 0, 0, 0, 0)
} }

View File

@ -1,12 +1,12 @@
package opencv package opencv
import ( import (
cv "github.com/lazywei/go-opencv/opencv" "github.com/hybridgroup/gocv"
"gobot.io/x/gobot" "gobot.io/x/gobot"
) )
type window interface { type window interface {
ShowImage(*cv.IplImage) IMShow(gocv.Mat)
} }
// WindowDriver is the Gobot Driver for the OpenCV window // WindowDriver is the Gobot Driver for the OpenCV window
@ -22,7 +22,7 @@ func NewWindowDriver() *WindowDriver {
return &WindowDriver{ return &WindowDriver{
name: "Window", name: "Window",
start: func(w *WindowDriver) { start: func(w *WindowDriver) {
w.window = cv.NewWindow(w.Name(), cv.CV_WINDOW_NORMAL) w.window = gocv.NewWindow(w.Name())
}, },
} }
} }
@ -38,7 +38,6 @@ func (w *WindowDriver) Connection() gobot.Connection { return nil }
// Start starts window thread and driver // Start starts window thread and driver
func (w *WindowDriver) Start() (err error) { func (w *WindowDriver) Start() (err error) {
cv.StartWindowThread()
w.start(w) w.start(w)
return return
} }
@ -47,6 +46,11 @@ func (w *WindowDriver) Start() (err error) {
func (w *WindowDriver) Halt() (err error) { return } func (w *WindowDriver) Halt() (err error) { return }
// ShowImage displays image in window // ShowImage displays image in window
func (w *WindowDriver) ShowImage(image *cv.IplImage) { func (w *WindowDriver) ShowImage(img gocv.Mat) {
w.window.ShowImage(image) w.window.IMShow(img)
}
// WaitKey gives window a chance to redraw, and checks for keyboard input
func (w *WindowDriver) WaitKey(pause int) int {
return gocv.WaitKey(pause)
} }

View File

@ -6,7 +6,7 @@ import (
"strings" "strings"
"testing" "testing"
cv "github.com/lazywei/go-opencv/opencv" "github.com/hybridgroup/gocv"
"gobot.io/x/gobot" "gobot.io/x/gobot"
"gobot.io/x/gobot/gobottest" "gobot.io/x/gobot/gobottest"
) )
@ -44,7 +44,7 @@ func TestWindowDriverHalt(t *testing.T) {
func TestWindowDriverShowImage(t *testing.T) { func TestWindowDriverShowImage(t *testing.T) {
d := initTestWindowDriver() d := initTestWindowDriver()
_, currentfile, _, _ := runtime.Caller(0) _, currentfile, _, _ := runtime.Caller(0)
image := cv.LoadImage(path.Join(path.Dir(currentfile), "lena-256x256.jpg")) image := gocv.IMRead(path.Join(path.Dir(currentfile), "lena-256x256.jpg"), gocv.IMReadColor)
d.Start() d.Start()
d.ShowImage(image) d.ShowImage(image)
} }

58
travis_build_opencv.sh Normal file
View File

@ -0,0 +1,58 @@
#!/bin/bash
set -eux -o pipefail
OPENCV_VERSION=${OPENCV_VERSION:-3.3.0}
#GRAPHICAL=ON
GRAPHICAL=${GRAPHICAL:-OFF}
# OpenCV looks for libjpeg in /usr/lib/libjpeg.so, for some reason. However,
# it does not seem to be there in 14.04. Create a link
mkdir -p $HOME/usr/lib
if [[ ! -f "$HOME/usr/lib/libjpeg.so" ]]; then
ln -s /usr/lib/x86_64-linux-gnu/libjpeg.so $HOME/usr/lib/libjpeg.so
fi
# Same for libpng.so
if [[ ! -f "$HOME/usr/lib/libpng.so" ]]; then
ln -s /usr/lib/x86_64-linux-gnu/libpng.so $HOME/usr/lib/libpng.so
fi
# Build OpenCV
if [[ ! -e "$HOME/usr/installed-${OPENCV_VERSION}" ]]; then
TMP=$(mktemp -d)
if [[ ! -d "opencv-${OPENCV_VERSION}/build" ]]; then
curl -sL https://github.com/opencv/opencv/archive/${OPENCV_VERSION}.zip > ${TMP}/opencv.zip
unzip -q ${TMP}/opencv.zip
mkdir opencv-${OPENCV_VERSION}/build
rm ${TMP}/opencv.zip
fi
if [[ ! -d "opencv_contrib-${OPENCV_VERSION}/modules" ]]; then
curl -sL https://github.com/opencv/opencv_contrib/archive/${OPENCV_VERSION}.zip > ${TMP}/opencv-contrib.zip
unzip -q ${TMP}/opencv-contrib.zip
rm ${TMP}/opencv-contrib.zip
fi
rmdir ${TMP}
cd opencv-${OPENCV_VERSION}/build
cmake -D WITH_IPP=${GRAPHICAL} \
-D WITH_OPENGL=${GRAPHICAL} \
-D WITH_QT=${GRAPHICAL} \
-D BUILD_EXAMPLES=OFF \
-D BUILD_TESTS=OFF \
-D BUILD_PERF_TESTS=OFF \
-D BUILD_opencv_java=OFF \
-D BUILD_opencv_python=OFF \
-D BUILD_opencv_python2=OFF \
-D BUILD_opencv_python3=OFF \
-D CMAKE_INSTALL_PREFIX=$HOME/usr \
-D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib-${OPENCV_VERSION}/modules ..
make -j8
make install && touch $HOME/usr/installed-${OPENCV_VERSION}
cd ../..
touch $HOME/fresh-cache
fi