gocv
gocv copied to clipboard
invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation]
Description
Hey, I am working with a Soccer Robot competition and use gocv as its main computer vision library. The robot use two camera and process a lot of data simultaneously using Goroutine (Let's say one for ball, one for goalpost, one for carpet, one for magenta robot etc)
As part of the process to do that, I need to do erode and dilate, and usually it works just fine, but sometimes when I run the project for quite a long time (1 minute+) a segmentation violation would happen
?:-1
<unknown>
?:-1
<unknown>
?:-1
<unknown>
?:-1
<unknown>
?:-1
<unknown>
?:-1
<unknown>
?:-1
<unknown>
?:-1
<unknown>
?:-1
<unknown>
?:-1
<unknown>
?:-1
<unknown>
?:-1
<unknown>
/Users/hariangr/go/pkg/mod/gocv.io/x/[email protected]/imgproc.cpp:137
C.Erode
/tmp/go-build/cgo-gcc-prolog:621
C._cgo_9685539a886c_Cfunc_Erode
/usr/local/go/src/runtime/asm_amd64.s:667
runtime.asmcgocall
?:-1
<unknown>
_cgo_gotypes.go:1497
gocv.io/x/gocv._Cfunc_Erode
/Users/hariangr/go/pkg/mod/gocv.io/x/[email protected]/imgproc.go:312
gocv.io/x/gocv.Erode.func1
/Users/hariangr/go/pkg/mod/gocv.io/x/[email protected]/imgproc.go:312
gocv.io/x/gocv.Erode
/Users/hariangr/Documents/MyFiles/Developer/Robotec/Beroda/golang/BrainFreeze/internal/wanda/haesve/dummy/narrow_dummy.go:56
harianugrah.com/brainfreeze/internal/wanda/haesve/dummy.(*NarrowHaesveDummy).Detect
/Users/hariangr/Documents/MyFiles/Developer/Robotec/Beroda/golang/BrainFreeze/internal/wanda/wanda.go:303
harianugrah.com/brainfreeze/internal/wanda.detectDummy
/usr/local/go/src/runtime/asm_amd64.s:1371
runtime.goexit
The thing that frustrate me the most is I can't caught the error using Recover. If error happen I am okay by skipping one or two frame, but closing the entire app is not okay.
The problem happen most in dilate (Especially if I set the kernel to something big like 9 or bigger) and erode (Either small or big kernel). The app would work just fine for a while (Either seconds or even minutes) then just crash
Steps to Reproduce
- Do HSV detection using Erode or Dilate
Your Environment
- Operating System and version: MacOs Big Sur 11.5
- OpenCV version used: 4.5.2
- How did you install OpenCV? Using the built in installer of gocv
- GoCV version used: 0.27.0
- Go version: go1.16.5 darwin/amd64
- Did you run the
env.sh
orenv.cmd
script before trying togo run
orgo build
? No
The app looks like this
And one of the detection class looks like this
package dummy
import (
"fmt"
"image/color"
"gocv.io/x/gocv"
"harianugrah.com/brainfreeze/pkg/models"
"harianugrah.com/brainfreeze/pkg/models/configuration"
)
type NarrowHaesveDummy struct {
conf *configuration.FreezeConfig
upperHsv gocv.Scalar
lowerHsv gocv.Scalar
}
func NewNarrowHaesveDummy(conf *configuration.FreezeConfig) *NarrowHaesveDummy {
upper := gocv.NewScalar(179, 255, 255, 1)
lower := gocv.NewScalar(166, 85, 69, 0)
return &NarrowHaesveDummy{
conf: conf,
upperHsv: upper,
lowerHsv: lower,
}
}
// Input adalah Mat yang sudah dalam format hsv
func (n *NarrowHaesveDummy) Detect(hsvFrame *gocv.Mat) (found bool, result []models.DetectionObject) {
detecteds := []models.DetectionObject{}
defer func() {
if r := recover(); r != nil {
found = false
result = detecteds
fmt.Println("recovered from ", r)
return
}
}()
if hsvFrame.Empty() {
return false, detecteds
}
w := hsvFrame.Cols()
h := hsvFrame.Rows()
filtered := gocv.NewMatWithSize(h, w, gocv.MatTypeCV8UC1)
defer filtered.Close()
gocv.InRangeWithScalar(*hsvFrame, n.lowerHsv, n.upperHsv, &filtered)
erodeMat := gocv.Ones(4, 4, gocv.MatTypeCV8UC1)
defer erodeMat.Close()
gocv.Erode(filtered, &filtered, erodeMat)
// dilateMat := gocv.Ones(21, 21, gocv.MatTypeCV8UC1)
// defer dilateMat.Close()
// gocv.Dilate(filtered, &filtered, dilateMat)
c := color.RGBA{75, 100, 0, 0}
hierarchyMat := gocv.NewMat()
defer hierarchyMat.Close()
pointVecs := gocv.FindContoursWithParams(filtered, &hierarchyMat, gocv.RetrievalExternal, gocv.ChainApproxNone)
defer pointVecs.Close()
if pointVecs.Size() == 0 {
return false, detecteds
}
for i := 0; i < pointVecs.Size(); i++ {
it := pointVecs.At(i)
area := gocv.ContourArea(it)
if area < n.conf.Wanda.MinimumHsvArea {
// Skip kalau ukurannya kekecilan
continue
}
if area > n.conf.Wanda.MaximumHsvArea {
continue
}
rect := gocv.BoundingRect(it)
gocv.Rectangle(hsvFrame, rect, c, 2)
gocv.PutText(hsvFrame, "Dummy", rect.Min, gocv.FontHersheyPlain, 1.2, c, 2)
d := models.NewDetectionObject(rect)
detecteds = append(detecteds, d)
}
return true, detecteds
}
Any help would very much appreciated
Hard to tell from your exact code, but I would try to avoid the modification in place.
Instead of
gocv.Erode(filtered, &filtered, erodeMat)
try
eroded := NewMat()
defer eroded.Close()
gocv.Erode(filtered, &eroded, erodeMat)
Or something like that. Hope that helps!