Added functions:

- FindContours
- DrawContours
- Set
- EqualizeHist

and associated constants
This commit is contained in:
David Oram 2015-09-10 16:51:38 +12:00
parent 8f000e16ff
commit 02da2d4700
5 changed files with 84 additions and 22 deletions

BIN
images/pic5_contours.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

View file

@ -23,7 +23,11 @@ const (
CV_BGR2BGRA = C.CV_BGR2BGRA
CV_RGBA2BGRA = C.CV_RGBA2BGRA
CV_BLUR = C.CV_BLUR
CV_BLUR_NO_SCALE = C.CV_BLUR_NO_SCALE
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_8S = C.CV_8S

View file

@ -113,6 +113,11 @@ func (img *IplImage) GetROI() Rect {
return Rect(r)
}
/* Equalizes the histogram of a grayscale image */
func (img *IplImage) EqualizeHist(dest *IplImage) {
C.cvEqualizeHist(unsafe.Pointer(img), unsafe.Pointer(dest))
}
/*
Reshape changes shape of the image without copying data. A value of `0` means
that channels or rows remain unchanged.
@ -142,6 +147,11 @@ func (img *IplImage) Get3D(x, y, z int) Scalar {
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 */
func (img *IplImage) Set1D(x int, value Scalar) {
C.cvSet1D(unsafe.Pointer(img), C.int(x), (C.CvScalar)(value))
@ -531,6 +541,13 @@ func Not(src, dst *IplImage) {
/****************************************************************************************\
* Dynamic data structures *
\****************************************************************************************/
func (seq *Seq) Release() {
C.cvReleaseMemStorage(&seq.storage)
}
func (seq *Seq) Total() int {
return (int)(seq.total)
}
/****************************************************************************************\
* Drawing *

View file

@ -54,10 +54,12 @@ func Crop(src *IplImage, x, y, width, height int) *IplImage {
}
func CreateContourType() *ContourType {
return &ContourType{CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point{0, 0}}
return &ContourType{mode: CV_RETR_EXTERNAL, method: CV_CHAIN_APPROX_SIMPLE, offset: Point{0, 0}}
}
func (this *ContourType) FindContours(image *IplImage) []*Contour {
/* Returns a Seq of countours in an image, detected according to the parameters in ContourType.
Caller must Release() the Seq returned */
func (this *ContourType) FindContours(image *IplImage) *Seq {
storage := C.cvCreateMemStorage(0)
header_size := (C.size_t)(unsafe.Sizeof(C.CvContour{}))
var seq *C.CvSeq
@ -70,14 +72,18 @@ func (this *ContourType) FindContours(image *IplImage) []*Contour {
this.method,
C.cvPoint(C.int(this.offset.X), C.int(this.offset.Y)))
var contours []*Contour
for i := 0; i < (int)(seq.total); i++ {
contour := (*Contour)((*_Ctype_CvContour)(unsafe.Pointer(C.cvGetSeqElem(seq, C.int(i)))))
contours = append(contours, contour)
}
storage_c := (*C.CvMemStorage)(storage)
C.cvReleaseMemStorage(&storage_c)
return contours
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)))
}

View file

@ -1,10 +1,11 @@
package opencv
import (
"log"
"path"
"runtime"
"os"
"testing"
"syscall"
)
func TestResize(t *testing.T) {
@ -59,7 +60,7 @@ func TestCrop(t *testing.T) {
func TestFindContours(t *testing.T) {
_, currentfile, _, _ := runtime.Caller(0)
filename := path.Join(path.Dir(currentfile), "../images/shapes.png")
filename := path.Join(path.Dir(currentfile), "../images/pic5.png")
image := LoadImage(filename)
if image == nil {
@ -67,13 +68,47 @@ func TestFindContours(t *testing.T) {
}
defer image.Release()
grayscale_image := CreateImage(image.Width(), image.Height(), IPL_DEPTH_8U, 1)
CvtColor(image, grayscale_image, CV_BGR2GRAY)
defer grayscale_image.Release()
grayscale := CreateImage(image.Width(), image.Height(), IPL_DEPTH_8U, 1)
CvtColor(image, grayscale, CV_BGR2GRAY)
defer grayscale.Release()
cType := CreateContourType()
contours := cType.FindContours(grayscale_image)
for i, c := range contours {
log.Printf("Contour[%v] = %v", i, c)
edges := CreateImage(grayscale.Width(), grayscale.Height(), grayscale.Depth(), grayscale.Channels())
defer edges.Release()
Canny(grayscale, edges, 50, 200, 3)
contourType := CreateContourType()
seq := contourType.FindContours(edges)
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)(seq.h_next) {
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")
}
}