Compare commits
1 commit
master
...
feature/th
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
71854e5f60 |
17 changed files with 86 additions and 388 deletions
|
|
@ -2,3 +2,4 @@
|
||||||
|
|
||||||
%include "gocv_core.i"
|
%include "gocv_core.i"
|
||||||
%include "gocv_calib3d.i"
|
%include "gocv_calib3d.i"
|
||||||
|
%include "gocv_imgproc.i"
|
||||||
|
|
|
||||||
|
|
@ -24,11 +24,11 @@ func GcvInitCameraMatrix2D(objPts, imgPts *mat64.Dense, dims [2]int,
|
||||||
imgPtsVec := NewGcvPoint2f32Vector(int64(nObjPts))
|
imgPtsVec := NewGcvPoint2f32Vector(int64(nObjPts))
|
||||||
|
|
||||||
for j := 0; j < nObjPts; j++ {
|
for j := 0; j < nObjPts; j++ {
|
||||||
objPtsVec.Set(j, NewGcvPoint3f32(mat64.Col(nil, j, objPts)...))
|
objPtsVec.Set(j, NewGcvPoint3f32(objPts.Col(nil, j)...))
|
||||||
}
|
}
|
||||||
|
|
||||||
for j := 0; j < nObjPts; j++ {
|
for j := 0; j < nObjPts; j++ {
|
||||||
imgPtsVec.Set(j, NewGcvPoint2f32(mat64.Col(nil, j, imgPts)...))
|
imgPtsVec.Set(j, NewGcvPoint2f32(imgPts.Col(nil, j)...))
|
||||||
}
|
}
|
||||||
|
|
||||||
_imgSize := NewGcvSize2i(dims[0], dims[1])
|
_imgSize := NewGcvSize2i(dims[0], dims[1])
|
||||||
|
|
@ -52,11 +52,11 @@ func GcvCalibrateCamera(objPts, imgPts, camMat, distCoeffs *mat64.Dense,
|
||||||
imgPtsVec := NewGcvPoint2f32Vector(int64(nObjPts))
|
imgPtsVec := NewGcvPoint2f32Vector(int64(nObjPts))
|
||||||
|
|
||||||
for j := 0; j < nObjPts; j++ {
|
for j := 0; j < nObjPts; j++ {
|
||||||
objPtsVec.Set(j, NewGcvPoint3f32(mat64.Col(nil, j, objPts)...))
|
objPtsVec.Set(j, NewGcvPoint3f32(objPts.Col(nil, j)...))
|
||||||
}
|
}
|
||||||
|
|
||||||
for j := 0; j < nObjPts; j++ {
|
for j := 0; j < nObjPts; j++ {
|
||||||
imgPtsVec.Set(j, NewGcvPoint2f32(mat64.Col(nil, j, imgPts)...))
|
imgPtsVec.Set(j, NewGcvPoint2f32(imgPts.Col(nil, j)...))
|
||||||
}
|
}
|
||||||
|
|
||||||
_camMat := Mat64ToGcvMat(camMat)
|
_camMat := Mat64ToGcvMat(camMat)
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ func TestGcvInitCameraMatrix2D(t *testing.T) {
|
||||||
-0.226950, 0.942377, -0.899869,
|
-0.226950, 0.942377, -0.899869,
|
||||||
-1.148912, 0.093725, 0.634745,
|
-1.148912, 0.093725, 0.634745,
|
||||||
})
|
})
|
||||||
objPts.Clone(objPts.T())
|
objPts.TCopy(objPts)
|
||||||
|
|
||||||
imgPts := mat64.NewDense(10, 2, []float64{
|
imgPts := mat64.NewDense(10, 2, []float64{
|
||||||
-0.384281, -0.299055,
|
-0.384281, -0.299055,
|
||||||
|
|
@ -38,15 +38,15 @@ func TestGcvInitCameraMatrix2D(t *testing.T) {
|
||||||
0.631444, -0.340257,
|
0.631444, -0.340257,
|
||||||
-0.647580, 0.502113,
|
-0.647580, 0.502113,
|
||||||
})
|
})
|
||||||
imgPts.Clone(imgPts.T())
|
imgPts.TCopy(imgPts)
|
||||||
|
|
||||||
camMat := GcvInitCameraMatrix2D(objPts, imgPts, [2]int{1920, 1080}, 1)
|
camMat := GcvInitCameraMatrix2D(objPts, imgPts, [2]int{1920, 1080}, 1)
|
||||||
assert.InDeltaSlice(t, []float64{1.47219772e+03, 0.00000000e+00, 9.59500000e+02},
|
assert.InDeltaSlice(t, []float64{1.47219772e+03, 0.00000000e+00, 9.59500000e+02},
|
||||||
mat64.Row(nil, 0, camMat), DELTA)
|
camMat.Row(nil, 0), DELTA)
|
||||||
assert.InDeltaSlice(t, []float64{0.00000000e+00, 1.47219772e+03, 5.39500000e+02},
|
assert.InDeltaSlice(t, []float64{0.00000000e+00, 1.47219772e+03, 5.39500000e+02},
|
||||||
mat64.Row(nil, 1, camMat), DELTA)
|
camMat.Row(nil, 1), DELTA)
|
||||||
assert.InDeltaSlice(t, []float64{0.00000000e+00, 0.00000000e+00, 1.00000000e+00},
|
assert.InDeltaSlice(t, []float64{0.00000000e+00, 0.00000000e+00, 1.00000000e+00},
|
||||||
mat64.Row(nil, 2, camMat), DELTA)
|
camMat.Row(nil, 2), DELTA)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGcvCalibrateCamera(t *testing.T) {
|
func TestGcvCalibrateCamera(t *testing.T) {
|
||||||
|
|
@ -62,7 +62,7 @@ func TestGcvCalibrateCamera(t *testing.T) {
|
||||||
-0.226950, 0.942377, -0.899869,
|
-0.226950, 0.942377, -0.899869,
|
||||||
-1.148912, 0.093725, 0.634745,
|
-1.148912, 0.093725, 0.634745,
|
||||||
})
|
})
|
||||||
objPts.Clone(objPts.T())
|
objPts.TCopy(objPts)
|
||||||
|
|
||||||
imgPts := mat64.NewDense(10, 2, []float64{
|
imgPts := mat64.NewDense(10, 2, []float64{
|
||||||
-0.384281, -0.299055,
|
-0.384281, -0.299055,
|
||||||
|
|
@ -76,7 +76,7 @@ func TestGcvCalibrateCamera(t *testing.T) {
|
||||||
0.631444, -0.340257,
|
0.631444, -0.340257,
|
||||||
-0.647580, 0.502113,
|
-0.647580, 0.502113,
|
||||||
})
|
})
|
||||||
imgPts.Clone(imgPts.T())
|
imgPts.TCopy(imgPts)
|
||||||
|
|
||||||
camMat := GcvInitCameraMatrix2D(objPts, imgPts, [2]int{1920, 1080}, 1)
|
camMat := GcvInitCameraMatrix2D(objPts, imgPts, [2]int{1920, 1080}, 1)
|
||||||
|
|
||||||
|
|
@ -85,12 +85,12 @@ func TestGcvCalibrateCamera(t *testing.T) {
|
||||||
camMat, rvec, tvec := GcvCalibrateCamera(
|
camMat, rvec, tvec := GcvCalibrateCamera(
|
||||||
objPts, imgPts, camMat, distCoeffs, [2]int{1920, 1080}, 14575)
|
objPts, imgPts, camMat, distCoeffs, [2]int{1920, 1080}, 14575)
|
||||||
|
|
||||||
assert.InDeltaSlice(t, []float64{-46.15296606, 0., 959.5}, mat64.Row(nil, 0, camMat), DELTA)
|
assert.InDeltaSlice(t, []float64{-46.15296606, 0., 959.5}, camMat.Row(nil, 0), DELTA)
|
||||||
assert.InDeltaSlice(t, []float64{0., -46.15296606, 539.5}, mat64.Row(nil, 1, camMat), DELTA)
|
assert.InDeltaSlice(t, []float64{0., -46.15296606, 539.5}, camMat.Row(nil, 1), DELTA)
|
||||||
assert.InDeltaSlice(t, []float64{0., 0., 1.}, mat64.Row(nil, 2, camMat), DELTA)
|
assert.InDeltaSlice(t, []float64{0., 0., 1.}, camMat.Row(nil, 2), DELTA)
|
||||||
|
|
||||||
assert.InDeltaSlice(t, []float64{-0.98405029, -0.93443411, -0.26304667}, mat64.Col(nil, 0, rvec), DELTA)
|
assert.InDeltaSlice(t, []float64{-0.98405029, -0.93443411, -0.26304667}, rvec.Col(nil, 0), DELTA)
|
||||||
assert.InDeltaSlice(t, []float64{0.6804739, 0.47530207, -0.04833094}, mat64.Col(nil, 0, tvec), DELTA)
|
assert.InDeltaSlice(t, []float64{0.6804739, 0.47530207, -0.04833094}, tvec.Col(nil, 0), DELTA)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGcvRodrigues(t *testing.T) {
|
func TestGcvRodrigues(t *testing.T) {
|
||||||
|
|
@ -101,7 +101,7 @@ func TestGcvRodrigues(t *testing.T) {
|
||||||
})
|
})
|
||||||
rmat := GcvRodrigues(rvec)
|
rmat := GcvRodrigues(rvec)
|
||||||
|
|
||||||
assert.InDeltaSlice(t, []float64{0.59922526, 0.57799222, -0.55394411}, mat64.Row(nil, 0, rmat), DELTA)
|
assert.InDeltaSlice(t, []float64{0.59922526, 0.57799222, -0.55394411}, rmat.Row(nil, 0), DELTA)
|
||||||
assert.InDeltaSlice(t, []float64{0.20413818, 0.558743, 0.80382452}, mat64.Row(nil, 1, rmat), DELTA)
|
assert.InDeltaSlice(t, []float64{0.20413818, 0.558743, 0.80382452}, rmat.Row(nil, 1), DELTA)
|
||||||
assert.InDeltaSlice(t, []float64{0.77411672, -0.5947531, 0.21682264}, mat64.Row(nil, 2, rmat), DELTA)
|
assert.InDeltaSlice(t, []float64{0.77411672, -0.5947531, 0.21682264}, rmat.Row(nil, 2), DELTA)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
16
gocv/gocv_imgproc.cpp
Normal file
16
gocv/gocv_imgproc.cpp
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
#include <opencv2/core/core.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "gocv_imgproc.hpp"
|
||||||
|
|
||||||
|
double GcvThreshold_(cv::Mat src, cv::Mat& dst, double thresh, double maxval, int type) {
|
||||||
|
std::cout << "src " << std::endl << src << std::endl;
|
||||||
|
std::cout << "thresh " << std::endl << thresh << std::endl;
|
||||||
|
std::cout << "maxval " << std::endl << maxval << std::endl;
|
||||||
|
std::cout << "type " << std::endl << type << std::endl;
|
||||||
|
|
||||||
|
double rtn;
|
||||||
|
rtn = cv::threshold(src, src, 1.0, 3.0, 0);
|
||||||
|
return rtn;
|
||||||
|
}
|
||||||
17
gocv/gocv_imgproc.go
Normal file
17
gocv/gocv_imgproc.go
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
package gocv
|
||||||
|
|
||||||
|
// #cgo CXXFLAGS: -std=c++11
|
||||||
|
// #cgo darwin pkg-config: opencv
|
||||||
|
// #cgo linux pkg-config: opencv
|
||||||
|
import "C"
|
||||||
|
import "github.com/gonum/matrix/mat64"
|
||||||
|
|
||||||
|
// GcvThreshold takes a 3D column vector, and apply cv::Threshold to it.
|
||||||
|
func GcvThreshold(src *mat64.Dense) (dst *mat64.Dense, rtn float64) {
|
||||||
|
gcvSrc := Mat64ToGcvMat(src)
|
||||||
|
gcvDst := NewGcvMat()
|
||||||
|
rtn = GcvThreshold_(gcvSrc, gcvDst, 1.0, 2.0, 0)
|
||||||
|
dst = GcvMatToMat64(gcvDst)
|
||||||
|
|
||||||
|
return dst, rtn
|
||||||
|
}
|
||||||
3
gocv/gocv_imgproc.hpp
Normal file
3
gocv/gocv_imgproc.hpp
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
|
||||||
|
double GcvThreshold_(cv::Mat src, cv::Mat& dst, double thresh, double maxval, int type);
|
||||||
5
gocv/gocv_imgproc.i
Normal file
5
gocv/gocv_imgproc.i
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
%{
|
||||||
|
#include "gocv_imgproc.hpp"
|
||||||
|
%}
|
||||||
|
|
||||||
|
%include "gocv_imgproc.hpp"
|
||||||
24
gocv/gocv_imgproc_test.go
Normal file
24
gocv/gocv_imgproc_test.go
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
package gocv
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/gonum/matrix/mat64"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGcvThreshold(t *testing.T) {
|
||||||
|
rvec := mat64.NewDense(3, 1, []float64{
|
||||||
|
3,
|
||||||
|
-0.3,
|
||||||
|
0.2,
|
||||||
|
})
|
||||||
|
rmat, _ := GcvThreshold(rvec)
|
||||||
|
|
||||||
|
assert.InDeltaSlice(t, []float64{0.59922526, 0.57799222, -0.55394411},
|
||||||
|
rmat.Row(nil, 0), 1e-5)
|
||||||
|
assert.InDeltaSlice(t, []float64{0.20413818, 0.558743, 0.80382452},
|
||||||
|
rmat.Row(nil, 1), 1e-5)
|
||||||
|
assert.InDeltaSlice(t, []float64{0.77411672, -0.5947531, 0.21682264},
|
||||||
|
rmat.Row(nil, 2), 1e-5)
|
||||||
|
}
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 105 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 5.1 KiB |
|
|
@ -23,11 +23,7 @@ const (
|
||||||
CV_BGR2BGRA = C.CV_BGR2BGRA
|
CV_BGR2BGRA = C.CV_BGR2BGRA
|
||||||
CV_RGBA2BGRA = C.CV_RGBA2BGRA
|
CV_RGBA2BGRA = C.CV_RGBA2BGRA
|
||||||
|
|
||||||
CV_BLUR_NO_SCALE = C.CV_BLUR_NO_SCALE
|
|
||||||
CV_BLUR = C.CV_BLUR
|
CV_BLUR = C.CV_BLUR
|
||||||
CV_GAUSSIAN = C.CV_GAUSSIAN
|
|
||||||
CV_MEDIAN = C.CV_MEDIAN
|
|
||||||
CV_BILATERAL = C.CV_BILATERAL
|
|
||||||
|
|
||||||
CV_8U = C.CV_8U
|
CV_8U = C.CV_8U
|
||||||
CV_8S = C.CV_8S
|
CV_8S = C.CV_8S
|
||||||
|
|
|
||||||
|
|
@ -142,11 +142,6 @@ func (img *IplImage) Get3D(x, y, z int) Scalar {
|
||||||
return Scalar(ret)
|
return Scalar(ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sets every element of an array to a given value. */
|
|
||||||
func (img *IplImage) Set(value Scalar) {
|
|
||||||
C.cvSet(unsafe.Pointer(img), (C.CvScalar)(value), nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set1D sets a particular element in the image */
|
/* Set1D sets a particular element in the image */
|
||||||
func (img *IplImage) Set1D(x int, value Scalar) {
|
func (img *IplImage) Set1D(x int, value Scalar) {
|
||||||
C.cvSet1D(unsafe.Pointer(img), C.int(x), (C.CvScalar)(value))
|
C.cvSet1D(unsafe.Pointer(img), C.int(x), (C.CvScalar)(value))
|
||||||
|
|
@ -528,15 +523,6 @@ func Not(src, dst *IplImage) {
|
||||||
/****************************************************************************************\
|
/****************************************************************************************\
|
||||||
* Array Statistics *
|
* Array Statistics *
|
||||||
\****************************************************************************************/
|
\****************************************************************************************/
|
||||||
// CvScalar cvAvg(const CvArr* arr, const CvArr* mask=NULL )
|
|
||||||
func (src *IplImage) Avg(mask *IplImage) Scalar {
|
|
||||||
return (Scalar)(C.cvAvg(unsafe.Pointer(src), unsafe.Pointer(mask)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// cvEqualizeHist(const CvArr* src, CvArr* dst)
|
|
||||||
func (src *IplImage) EqualizeHist(dst *IplImage) {
|
|
||||||
C.cvEqualizeHist(unsafe.Pointer(src), unsafe.Pointer(dst))
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************************\
|
/****************************************************************************************\
|
||||||
* Discrete Linear Transforms and Related Functions *
|
* Discrete Linear Transforms and Related Functions *
|
||||||
|
|
@ -545,25 +531,6 @@ func (src *IplImage) EqualizeHist(dst *IplImage) {
|
||||||
/****************************************************************************************\
|
/****************************************************************************************\
|
||||||
* Dynamic data structures *
|
* Dynamic data structures *
|
||||||
\****************************************************************************************/
|
\****************************************************************************************/
|
||||||
func (seq *Seq) Release() {
|
|
||||||
C.cvReleaseMemStorage(&seq.storage)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (seq *Seq) Total() int {
|
|
||||||
return (int)(seq.total)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (seq *Seq) HNext() *Seq {
|
|
||||||
return (*Seq)(seq.h_next)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (seq *Seq) VNext() *Seq {
|
|
||||||
return (*Seq)(seq.v_next)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (seq *Seq) Storage() *MemStorage {
|
|
||||||
return (*MemStorage)(seq.storage)
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************************\
|
/****************************************************************************************\
|
||||||
* Drawing *
|
* Drawing *
|
||||||
|
|
@ -599,48 +566,6 @@ func Circle(image *IplImage, pt1 Point, radius int, color Scalar, thickness, lin
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
|
||||||
CV_FONT_HERSHEY_SIMPLEX = int(C.CV_FONT_HERSHEY_SIMPLEX)
|
|
||||||
CV_FONT_HERSHEY_PLAIN = int(C.CV_FONT_HERSHEY_PLAIN)
|
|
||||||
CV_FONT_HERSHEY_DUPLEX = int(C.CV_FONT_HERSHEY_DUPLEX)
|
|
||||||
CV_FONT_HERSHEY_COMPLEX = int(C.CV_FONT_HERSHEY_COMPLEX)
|
|
||||||
CV_FONT_HERSHEY_TRIPLEX = int(C.CV_FONT_HERSHEY_TRIPLEX)
|
|
||||||
CV_FONT_HERSHEY_COMPLEX_SMALL = int(C.CV_FONT_HERSHEY_COMPLEX_SMALL)
|
|
||||||
CV_FONT_HERSHEY_SCRIPT_SIMPLEX = int(C.CV_FONT_HERSHEY_SCRIPT_SIMPLEX)
|
|
||||||
CV_FONT_HERSHEY_SCRIPT_COMPLEX = int(C.CV_FONT_HERSHEY_SCRIPT_COMPLEX)
|
|
||||||
CV_FONT_ITALIC = int(C.CV_FONT_ITALIC)
|
|
||||||
)
|
|
||||||
|
|
||||||
type Font struct {
|
|
||||||
font C.CvFont
|
|
||||||
}
|
|
||||||
|
|
||||||
//void cvInitFont(CvFont* font, int font_face, double hscale, double vscale, double shear=0, int thickness=1, int line_type=8 )
|
|
||||||
func InitFont(fontFace int, hscale, vscale, shear float32, thickness, lineType int) *Font {
|
|
||||||
font := new(Font)
|
|
||||||
C.cvInitFont(
|
|
||||||
&font.font,
|
|
||||||
C.int(fontFace),
|
|
||||||
C.double(hscale),
|
|
||||||
C.double(vscale),
|
|
||||||
C.double(shear),
|
|
||||||
C.int(thickness),
|
|
||||||
C.int(lineType),
|
|
||||||
)
|
|
||||||
return font
|
|
||||||
}
|
|
||||||
|
|
||||||
// void cvPutText(CvArr* img, const char* text, CvPoint org, const CvFont* font, CvScalar color)
|
|
||||||
func (this *Font) PutText(image *IplImage, text string, pt1 Point, color Scalar) {
|
|
||||||
C.cvPutText(
|
|
||||||
unsafe.Pointer(image),
|
|
||||||
C.CString(text),
|
|
||||||
C.cvPoint(C.int(pt1.X), C.int(pt1.Y)),
|
|
||||||
&this.font,
|
|
||||||
(C.CvScalar)(color),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
//CVAPI(void) cvLine( CvArr* img, CvPoint pt1, CvPoint pt2,
|
//CVAPI(void) cvLine( CvArr* img, CvPoint pt1, CvPoint pt2,
|
||||||
// CvScalar color, int thickness CV_DEFAULT(1),
|
// CvScalar color, int thickness CV_DEFAULT(1),
|
||||||
// int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0) );
|
// int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0) );
|
||||||
|
|
|
||||||
|
|
@ -1,75 +1,9 @@
|
||||||
package opencv
|
package opencv
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"runtime"
|
|
||||||
"syscall"
|
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestLoadImage2(t *testing.T) {
|
func TestLoadImage2(t *testing.T) {
|
||||||
// t.Errorf("aaa")
|
// t.Errorf("aaa")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInitFont(t *testing.T) {
|
|
||||||
// Will assert at the C layer on error
|
|
||||||
InitFont(CV_FONT_HERSHEY_DUPLEX, 1, 1, 0, 1, 8)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPutText(t *testing.T) {
|
|
||||||
_, currentfile, _, _ := runtime.Caller(0)
|
|
||||||
filename := path.Join(path.Dir(currentfile), "../images/lena.jpg")
|
|
||||||
|
|
||||||
image := LoadImage(filename)
|
|
||||||
if image == nil {
|
|
||||||
t.Fatal("LoadImage fail")
|
|
||||||
}
|
|
||||||
defer image.Release()
|
|
||||||
|
|
||||||
// Write 'Hello' on the image
|
|
||||||
font := InitFont(CV_FONT_HERSHEY_DUPLEX, 1, 1, 0, 1, 8)
|
|
||||||
color := NewScalar(255, 255, 255, 0)
|
|
||||||
|
|
||||||
pos := Point{image.Width() / 2, image.Height() / 2}
|
|
||||||
font.PutText(image, "Hello", pos, color)
|
|
||||||
|
|
||||||
filename = path.Join(path.Dir(currentfile), "../images/lena_with_text.jpg")
|
|
||||||
|
|
||||||
// Uncomment this code to create the test image "../images/lena_with_text.jpg"
|
|
||||||
// It is part of the repo, and what this test compares against
|
|
||||||
//
|
|
||||||
// SaveImage(filename, image, 0)
|
|
||||||
// println("Saved file", filename)
|
|
||||||
|
|
||||||
tempfilename := path.Join(os.TempDir(), "lena_with_text.jpg")
|
|
||||||
defer syscall.Unlink(tempfilename)
|
|
||||||
|
|
||||||
SaveImage(tempfilename, image, 0)
|
|
||||||
|
|
||||||
// Compare actual image with expected image
|
|
||||||
same, err := BinaryCompare(filename, tempfilename)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if !same {
|
|
||||||
t.Error("Actual file differs from expected file with text")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compare two files, return true if exactly the same
|
|
||||||
func BinaryCompare(file1, file2 string) (bool, error) {
|
|
||||||
f1, err := ioutil.ReadFile(file1)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
f2, err := ioutil.ReadFile(file2)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return bytes.Equal(f1, f2), nil
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -595,18 +595,6 @@ type Box2D struct {
|
||||||
angle float32
|
angle float32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (box *Box2D) Size() Size2D32f {
|
|
||||||
return box.size
|
|
||||||
}
|
|
||||||
|
|
||||||
func (box *Box2D) Center() Point2D32f {
|
|
||||||
return box.center
|
|
||||||
}
|
|
||||||
|
|
||||||
func (box *Box2D) Angle() float32 {
|
|
||||||
return box.angle
|
|
||||||
}
|
|
||||||
|
|
||||||
type LineIterator C.CvLineIterator
|
type LineIterator C.CvLineIterator
|
||||||
|
|
||||||
/************************************* CvSlice ******************************************/
|
/************************************* CvSlice ******************************************/
|
||||||
|
|
@ -617,12 +605,6 @@ const (
|
||||||
CV_WHOLE_SEQ_END_INDEX = C.CV_WHOLE_SEQ_END_INDEX
|
CV_WHOLE_SEQ_END_INDEX = C.CV_WHOLE_SEQ_END_INDEX
|
||||||
)
|
)
|
||||||
|
|
||||||
/* Equivalent to the C constant CV_WHOLE_SEQ */
|
|
||||||
func WholeSeq() Slice {
|
|
||||||
slice := C.cvSlice(C.int(0), C.CV_WHOLE_SEQ_END_INDEX)
|
|
||||||
return (Slice)(slice)
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************************* CvScalar *****************************************/
|
/************************************* CvScalar *****************************************/
|
||||||
|
|
||||||
type Scalar C.CvScalar
|
type Scalar C.CvScalar
|
||||||
|
|
@ -679,18 +661,6 @@ type Graph C.CvGraph
|
||||||
type Chain C.CvChain
|
type Chain C.CvChain
|
||||||
type Contour C.CvContour
|
type Contour C.CvContour
|
||||||
|
|
||||||
const (
|
|
||||||
CV_RETR_EXTERNAL = C.CV_RETR_EXTERNAL
|
|
||||||
CV_RETR_LIST = C.CV_RETR_LIST
|
|
||||||
CV_RETR_CCOMP = C.CV_RETR_CCOMP
|
|
||||||
CV_RETR_TREE = C.CV_RETR_TREE
|
|
||||||
|
|
||||||
CV_CHAIN_APPROX_NONE = C.CV_CHAIN_APPROX_NONE
|
|
||||||
CV_CHAIN_APPROX_SIMPLE = C.CV_CHAIN_APPROX_SIMPLE
|
|
||||||
CV_CHAIN_APPROX_TC89_L1 = C.CV_CHAIN_APPROX_TC89_L1
|
|
||||||
CV_CHAIN_APPROX_TC89_KCOS = C.CV_CHAIN_APPROX_TC89_KCOS
|
|
||||||
)
|
|
||||||
|
|
||||||
/****************************************************************************************\
|
/****************************************************************************************\
|
||||||
* Sequence types *
|
* Sequence types *
|
||||||
\****************************************************************************************/
|
\****************************************************************************************/
|
||||||
|
|
@ -724,15 +694,6 @@ const (
|
||||||
|
|
||||||
type AttrList C.CvAttrList
|
type AttrList C.CvAttrList
|
||||||
|
|
||||||
/****************************************************************************************/
|
|
||||||
/* Structural Analysis and Shape Descriptors */
|
|
||||||
/****************************************************************************************/
|
|
||||||
|
|
||||||
/* For use in ApproxPoly */
|
|
||||||
const (
|
|
||||||
CV_POLY_APPROX_DP = C.CV_POLY_APPROX_DP
|
|
||||||
)
|
|
||||||
|
|
||||||
/*****************************************************************************\
|
/*****************************************************************************\
|
||||||
* --- END --- *
|
* --- END --- *
|
||||||
\*****************************************************************************/
|
\*****************************************************************************/
|
||||||
|
|
|
||||||
|
|
@ -52,78 +52,3 @@ func Crop(src *IplImage, x, y, width, height int) *IplImage {
|
||||||
|
|
||||||
return dest
|
return dest
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns a Seq of countours in an image, detected according to the parameters.
|
|
||||||
Caller must Release() the Seq returned */
|
|
||||||
func (image *IplImage) FindContours(mode, method int, offset Point) *Seq {
|
|
||||||
storage := C.cvCreateMemStorage(0)
|
|
||||||
header_size := (C.size_t)(unsafe.Sizeof(C.CvContour{}))
|
|
||||||
var seq *C.CvSeq
|
|
||||||
C.cvFindContours(
|
|
||||||
unsafe.Pointer(image),
|
|
||||||
storage,
|
|
||||||
&seq,
|
|
||||||
C.int(header_size),
|
|
||||||
C.int(mode),
|
|
||||||
C.int(method),
|
|
||||||
C.cvPoint(C.int(offset.X), C.int(offset.Y)))
|
|
||||||
|
|
||||||
return (*Seq)(seq)
|
|
||||||
}
|
|
||||||
|
|
||||||
//cvDrawContours(CvArr* img, CvSeq* contour, CvScalar externalColor, CvScalar holeColor, int maxLevel, int thickness=1, int lineType=8
|
|
||||||
func DrawContours(image *IplImage, contours *Seq, externalColor, holeColor Scalar, maxLevel, thickness, lineType int, offset Point) {
|
|
||||||
C.cvDrawContours(
|
|
||||||
unsafe.Pointer(image),
|
|
||||||
(*C.CvSeq)(contours),
|
|
||||||
(C.CvScalar)(externalColor),
|
|
||||||
(C.CvScalar)(holeColor),
|
|
||||||
C.int(maxLevel),
|
|
||||||
C.int(thickness),
|
|
||||||
C.int(lineType),
|
|
||||||
C.cvPoint(C.int(offset.X), C.int(offset.Y)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// CvSeq* cvApproxPoly(const void* src_seq, int header_size, CvMemStorage* storage, int method, double eps, int recursive=0 )
|
|
||||||
func ApproxPoly(src *Seq, header_size int, storage *MemStorage, method int, eps float64, recursive int) *Seq {
|
|
||||||
seq := C.cvApproxPoly(
|
|
||||||
unsafe.Pointer(src),
|
|
||||||
C.int(header_size),
|
|
||||||
(*C.CvMemStorage)(storage),
|
|
||||||
C.int(method),
|
|
||||||
C.double(eps),
|
|
||||||
C.int(recursive))
|
|
||||||
return (*Seq)(seq)
|
|
||||||
}
|
|
||||||
|
|
||||||
// cvArcLength(const void* curve, CvSlice slice=CV_WHOLE_SEQ, int is_closed=-1 )
|
|
||||||
func ArcLength(curve *Seq, slice Slice, is_closed bool) float64 {
|
|
||||||
is_closed_int := 0
|
|
||||||
if is_closed {
|
|
||||||
is_closed_int = 1
|
|
||||||
}
|
|
||||||
return float64(C.cvArcLength(unsafe.Pointer(curve),
|
|
||||||
(C.CvSlice)(slice),
|
|
||||||
C.int(is_closed_int)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func ContourPerimeter(curve *Seq) float64 {
|
|
||||||
return ArcLength(curve, WholeSeq(), true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// double cvContourArea(const CvArr* contour, CvSlice slice=CV_WHOLE_SEQ, int oriented=0 )
|
|
||||||
func ContourArea(contour *Seq, slice Slice, oriented int) float64 {
|
|
||||||
return float64(C.cvContourArea(
|
|
||||||
unsafe.Pointer(contour),
|
|
||||||
(C.CvSlice)(slice),
|
|
||||||
C.int(oriented)))
|
|
||||||
}
|
|
||||||
|
|
||||||
/* points can be either CvSeq* or CvMat* */
|
|
||||||
func FitEllipse2(points unsafe.Pointer) Box2D {
|
|
||||||
box := C.cvFitEllipse2(points)
|
|
||||||
center := Point2D32f{float32(box.center.x), float32(box.center.y)}
|
|
||||||
size := Size2D32f{float32(box.size.width), float32(box.size.height)}
|
|
||||||
angle := float32(box.angle)
|
|
||||||
return Box2D{center, size, angle}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,8 @@
|
||||||
package opencv
|
package opencv
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
|
||||||
"path"
|
"path"
|
||||||
"runtime"
|
"runtime"
|
||||||
"syscall"
|
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -57,56 +55,3 @@ func TestCrop(t *testing.T) {
|
||||||
t.Fatalf("excepted width is 200, returned %d\n", crop.Height())
|
t.Fatalf("excepted width is 200, returned %d\n", crop.Height())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFindContours(t *testing.T) {
|
|
||||||
_, currentfile, _, _ := runtime.Caller(0)
|
|
||||||
filename := path.Join(path.Dir(currentfile), "../images/pic5.png")
|
|
||||||
|
|
||||||
image := LoadImage(filename)
|
|
||||||
if image == nil {
|
|
||||||
t.Fatal("LoadImage fail")
|
|
||||||
}
|
|
||||||
defer image.Release()
|
|
||||||
|
|
||||||
grayscale := CreateImage(image.Width(), image.Height(), IPL_DEPTH_8U, 1)
|
|
||||||
CvtColor(image, grayscale, CV_BGR2GRAY)
|
|
||||||
defer grayscale.Release()
|
|
||||||
|
|
||||||
edges := CreateImage(grayscale.Width(), grayscale.Height(), grayscale.Depth(), grayscale.Channels())
|
|
||||||
defer edges.Release()
|
|
||||||
Canny(grayscale, edges, 50, 200, 3)
|
|
||||||
|
|
||||||
seq := edges.FindContours(CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point{0, 0})
|
|
||||||
defer seq.Release()
|
|
||||||
|
|
||||||
contours := CreateImage(grayscale.Width(), grayscale.Height(), grayscale.Depth(), grayscale.Channels())
|
|
||||||
white := NewScalar(255, 255, 255, 0)
|
|
||||||
contours.Set(white)
|
|
||||||
|
|
||||||
black := NewScalar(0, 0, 0, 0)
|
|
||||||
red := NewScalar(0, 255, 0, 0)
|
|
||||||
|
|
||||||
for ; seq != nil; seq = seq.HNext() {
|
|
||||||
DrawContours(contours, seq, red, black, 0, 2, 8, Point{0, 0})
|
|
||||||
}
|
|
||||||
|
|
||||||
filename = path.Join(path.Dir(currentfile), "../images/pic5_contours.png")
|
|
||||||
// Uncomment this code to create the test image "../images/shapes_contours.png"
|
|
||||||
// It is part of the repo, and what this test compares against
|
|
||||||
//
|
|
||||||
//SaveImage(filename), contours, 0)
|
|
||||||
|
|
||||||
tempfilename := path.Join(os.TempDir(), "pic5_contours.png")
|
|
||||||
defer syscall.Unlink(tempfilename)
|
|
||||||
SaveImage(tempfilename, contours, 0)
|
|
||||||
|
|
||||||
// Compare actual image with expected image
|
|
||||||
same, err := BinaryCompare(filename, tempfilename)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if !same {
|
|
||||||
t.Error("Expected contour file != actual contour file")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
|
|
||||||
"github.com/lazywei/go-opencv/opencv"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
win := opencv.NewWindow("Go-OpenCV Webcam Face Detection")
|
|
||||||
defer win.Destroy()
|
|
||||||
|
|
||||||
cap := opencv.NewCameraCapture(0)
|
|
||||||
if cap == nil {
|
|
||||||
panic("cannot open camera")
|
|
||||||
}
|
|
||||||
defer cap.Release()
|
|
||||||
|
|
||||||
cwd, err := os.Getwd()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
cascade := opencv.LoadHaarClassifierCascade(path.Join(cwd, "haarcascade_frontalface_alt.xml"))
|
|
||||||
|
|
||||||
fmt.Println("Press ESC to quit")
|
|
||||||
for {
|
|
||||||
if cap.GrabFrame() {
|
|
||||||
img := cap.RetrieveFrame(1)
|
|
||||||
if img != nil {
|
|
||||||
faces := cascade.DetectObjects(img)
|
|
||||||
for _, value := range faces {
|
|
||||||
opencv.Circle(img,
|
|
||||||
opencv.Point{
|
|
||||||
value.X() + (value.Width() / 2),
|
|
||||||
value.Y() + (value.Height() / 2),
|
|
||||||
},
|
|
||||||
value.Width()/2,
|
|
||||||
opencv.ScalarAll(255.0), 1, 1, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
win.ShowImage(img)
|
|
||||||
} else {
|
|
||||||
fmt.Println("nil image")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
key := opencv.WaitKey(1)
|
|
||||||
|
|
||||||
if key == 27 {
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Add table
Reference in a new issue