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_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

View file

@ -113,6 +113,11 @@ func (img *IplImage) GetROI() Rect {
return Rect(r) 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 Reshape changes shape of the image without copying data. A value of `0` means
that channels or rows remain unchanged. that channels or rows remain unchanged.
@ -142,6 +147,11 @@ 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))
@ -531,6 +541,13 @@ func Not(src, 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)
}
/****************************************************************************************\ /****************************************************************************************\
* Drawing * * Drawing *

View file

@ -54,10 +54,12 @@ func Crop(src *IplImage, x, y, width, height int) *IplImage {
} }
func CreateContourType() *ContourType { 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) storage := C.cvCreateMemStorage(0)
header_size := (C.size_t)(unsafe.Sizeof(C.CvContour{})) header_size := (C.size_t)(unsafe.Sizeof(C.CvContour{}))
var seq *C.CvSeq var seq *C.CvSeq
@ -70,14 +72,18 @@ func (this *ContourType) FindContours(image *IplImage) []*Contour {
this.method, this.method,
C.cvPoint(C.int(this.offset.X), C.int(this.offset.Y))) C.cvPoint(C.int(this.offset.X), C.int(this.offset.Y)))
var contours []*Contour return (*Seq)(seq)
for i := 0; i < (int)(seq.total); i++ { }
contour := (*Contour)((*_Ctype_CvContour)(unsafe.Pointer(C.cvGetSeqElem(seq, C.int(i)))))
contours = append(contours, contour) //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(
storage_c := (*C.CvMemStorage)(storage) unsafe.Pointer(image),
C.cvReleaseMemStorage(&storage_c) (*C.CvSeq)(contours),
(C.CvScalar)(externalColor),
return contours (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 package opencv
import ( import (
"log"
"path" "path"
"runtime" "runtime"
"os"
"testing" "testing"
"syscall"
) )
func TestResize(t *testing.T) { func TestResize(t *testing.T) {
@ -59,7 +60,7 @@ func TestCrop(t *testing.T) {
func TestFindContours(t *testing.T) { func TestFindContours(t *testing.T) {
_, currentfile, _, _ := runtime.Caller(0) _, 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) image := LoadImage(filename)
if image == nil { if image == nil {
@ -67,13 +68,47 @@ func TestFindContours(t *testing.T) {
} }
defer image.Release() defer image.Release()
grayscale_image := CreateImage(image.Width(), image.Height(), IPL_DEPTH_8U, 1) grayscale := CreateImage(image.Width(), image.Height(), IPL_DEPTH_8U, 1)
CvtColor(image, grayscale_image, CV_BGR2GRAY) CvtColor(image, grayscale, CV_BGR2GRAY)
defer grayscale_image.Release() defer grayscale.Release()
cType := CreateContourType()
contours := cType.FindContours(grayscale_image) edges := CreateImage(grayscale.Width(), grayscale.Height(), grayscale.Depth(), grayscale.Channels())
for i, c := range contours { defer edges.Release()
log.Printf("Contour[%v] = %v", i, c) 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")
}
} }