gocv icon indicating copy to clipboard operation
gocv copied to clipboard

Getting error: (-2:Unspecified error) in function cv::QRCodeDetector::decode

Open SoftExpert opened this issue 2 years ago • 3 comments

When calling method DetectAndDecode on a specific JPEG file, the app is terminated, in spite of redondant recovery code.

Description

Running the sample code on the provided image will terminate the application, despite recovery code. demo

Simply runing a compiled version of the code or just running with go run main.go will give the same result:

Searching QRCode in [demo.jpg]terminate called after throwing an instance of 'cv::Exception'
  what():  OpenCV(4.5.4) /tmp/opencv/opencv-4.5.4/modules/objdetect/src/qrcode.cpp:2487: error: (-2:Unspecified error) in function 'std::string cv::QRCodeDetector::decode(cv::InputArray, cv::InputArray, cv::OutputArray)'
> Invalid QR code source points (expected: 'contourArea(src_points) > 0.0'), where
>     'contourArea(src_points)' is 0
> must be greater than
>     '0.0' is 0

SIGABRT: abort
PC=0x7f57ee3db18b m=4 sigcode=18446744073709551610

goroutine 0 [idle]:
runtime: unknown pc 0x7f57ee3db18b
stack: frame={sp:0x7f57bb0e24b0, fp:0x0} stack=[0x7f57ba8e3670,0x7f57bb0e3270)
0x00007f57bb0e23b0:  0x0000000000000000  0x0000000000000000 
0x00007f57bb0e23c0:  0x0000000000000000  0x0000000000000000 
0x00007f57bb0e23d0:  0x0000000000000000  0x0000000000000000 
0x00007f57bb0e23e0:  0xfffffffffffffff8  0x0000000000000001 
0x00007f57bb0e23f0:  0x0000000000000000  0x0000000000000000 
0x00007f57bb0e2400:  0x0000000000000000  0x0000000000000030 
0x00007f57bb0e2410:  0x0000000000000007  0x0000000000000000 
0x00007f57bb0e2420:  0x0000000000000000  0x0000000000000000 
0x00007f57bb0e2430:  0xffffffffffff0000  0xffffffffffffff00 
0x00007f57bb0e2440:  0x0000000000000000  0x0000000000000000 
0x00007f57bb0e2450:  0x0000000000000000  0x0000000000000000 
0x00007f57bb0e2460:  0x0000000000000000  0x0000000000000000 
0x00007f57bb0e2470:  0x0000000000000000  0x0000000000000000 
0x00007f57bb0e2480:  0x0000000000000000  0x0000000000000000 
0x00007f57bb0e2490:  0x00007f57bb0e26d0  0x00007f57bb0e26d8 
0x00007f57bb0e24a0:  0x7273286165724172  0x73746e696f705f63 
0x00007f57bb0e24b0: <0x0000000000000000  0x0000000000000000 
0x00007f57bb0e24c0:  0x000000004542d000  0x0000000000000000 
0x00007f57bb0e24d0:  0x00000000c542d000  0x0000000000000000 
0x00007f57bb0e24e0:  0x00000000455b5000  0x0000000000000000 
0x00007f57bb0e24f0:  0x00000000455b5000  0x0000000000000000 
0x00007f57bb0e2500:  0x0000000043c40000  0x0000000000000000 
0x00007f57bb0e2510:  0x0000000000000000  0x0000000000000000 
0x00007f57bb0e2520:  0x00000000455b5000  0x0000000000000000 
0x00007f57bb0e2530:  0xfffffffe7fffffff  0xffffffffffffffff 
0x00007f57bb0e2540:  0xffffffffffffffff  0xffffffffffffffff 
0x00007f57bb0e2550:  0xffffffffffffffff  0xffffffffffffffff 
0x00007f57bb0e2560:  0xffffffffffffffff  0xffffffffffffffff 
0x00007f57bb0e2570:  0xffffffffffffffff  0xffffffffffffffff 
0x00007f57bb0e2580:  0xffffffffffffffff  0xffffffffffffffff 
0x00007f57bb0e2590:  0xffffffffffffffff  0xffffffffffffffff 
0x00007f57bb0e25a0:  0xffffffffffffffff  0xffffffffffffffff 
runtime: unknown pc 0x7f57ee3db18b
stack: frame={sp:0x7f57bb0e24b0, fp:0x0} stack=[0x7f57ba8e3670,0x7f57bb0e3270)
0x00007f57bb0e23b0:  0x0000000000000000  0x0000000000000000 
0x00007f57bb0e23c0:  0x0000000000000000  0x0000000000000000 
0x00007f57bb0e23d0:  0x0000000000000000  0x0000000000000000 
0x00007f57bb0e23e0:  0xfffffffffffffff8  0x0000000000000001 
0x00007f57bb0e23f0:  0x0000000000000000  0x0000000000000000 
0x00007f57bb0e2400:  0x0000000000000000  0x0000000000000030 
0x00007f57bb0e2410:  0x0000000000000007  0x0000000000000000 
0x00007f57bb0e2420:  0x0000000000000000  0x0000000000000000 
0x00007f57bb0e2430:  0xffffffffffff0000  0xffffffffffffff00 
0x00007f57bb0e2440:  0x0000000000000000  0x0000000000000000 
0x00007f57bb0e2450:  0x0000000000000000  0x0000000000000000 
0x00007f57bb0e2460:  0x0000000000000000  0x0000000000000000 
0x00007f57bb0e2470:  0x0000000000000000  0x0000000000000000 
0x00007f57bb0e2480:  0x0000000000000000  0x0000000000000000 
0x00007f57bb0e2490:  0x00007f57bb0e26d0  0x00007f57bb0e26d8 
0x00007f57bb0e24a0:  0x7273286165724172  0x73746e696f705f63 
0x00007f57bb0e24b0: <0x0000000000000000  0x0000000000000000 
0x00007f57bb0e24c0:  0x000000004542d000  0x0000000000000000 
0x00007f57bb0e24d0:  0x00000000c542d000  0x0000000000000000 
0x00007f57bb0e24e0:  0x00000000455b5000  0x0000000000000000 
0x00007f57bb0e24f0:  0x00000000455b5000  0x0000000000000000 
0x00007f57bb0e2500:  0x0000000043c40000  0x0000000000000000 
0x00007f57bb0e2510:  0x0000000000000000  0x0000000000000000 
0x00007f57bb0e2520:  0x00000000455b5000  0x0000000000000000 
0x00007f57bb0e2530:  0xfffffffe7fffffff  0xffffffffffffffff 
0x00007f57bb0e2540:  0xffffffffffffffff  0xffffffffffffffff 
0x00007f57bb0e2550:  0xffffffffffffffff  0xffffffffffffffff 
0x00007f57bb0e2560:  0xffffffffffffffff  0xffffffffffffffff 
0x00007f57bb0e2570:  0xffffffffffffffff  0xffffffffffffffff 
0x00007f57bb0e2580:  0xffffffffffffffff  0xffffffffffffffff 
0x00007f57bb0e2590:  0xffffffffffffffff  0xffffffffffffffff 
0x00007f57bb0e25a0:  0xffffffffffffffff  0xffffffffffffffff 

goroutine 1 [syscall]:
runtime.cgocall(0x4b2f60, 0xc00009da08)
        /usr/local/go/src/runtime/cgocall.go:156 +0x5c fp=0xc00009d9e0 sp=0xc00009d9a8 pc=0x41e2fc
gocv.io/x/gocv._Cfunc_QRCodeDetector_DetectAndDecode(0x166d110, 0x39ba050, 0x1674d90, 0x16876c0)
        _cgo_gotypes.go:6709 +0x4d fp=0xc00009da08 sp=0xc00009d9e0 pc=0x4aa00d
gocv.io/x/gocv.(*QRCodeDetector).DetectAndDecode.func1(0xc000059a68, {0x39ba050, {0x0, 0x425550, 0xf}}, 0xc000016180, 0xc00007c000)
        /home/user/go/pkg/mod/gocv.io/x/[email protected]/objdetect.go:219 +0xbd fp=0xc00009da60 sp=0xc00009da08 pc=0x4ac0fd
gocv.io/x/gocv.(*QRCodeDetector).DetectAndDecode(0x509820, {0x39ba050, {0x0, 0x1, 0x1}}, 0xc0000001a4, 0x200000003)
        /home/user/go/pkg/mod/gocv.io/x/[email protected]/objdetect.go:219 +0x25 fp=0xc00009daa8 sp=0xc00009da60 pc=0x4abfc5
main.GetQRCode({0x39ba050, {0x0, 0x0, 0x0}}, {0x4e95d6, 0x8})
        /home/user/go/src/goCVbug/main.go:93 +0x365 fp=0xc00009dbf8 sp=0xc00009daa8 pc=0x4ad425
main.IsWhitePage({0x4e95d6, 0x8}, 0x1)
        /home/user/go/src/goCVbug/main.go:66 +0x5ca fp=0xc00009de70 sp=0xc00009dbf8 pc=0x4acc4a
main.main()
        /home/user/go/src/goCVbug/main.go:13 +0x3f fp=0xc00009df80 sp=0xc00009de70 pc=0x4ac4bf
runtime.main()
        /usr/local/go/src/runtime/proc.go:255 +0x227 fp=0xc00009dfe0 sp=0xc00009df80 pc=0x44e1a7
runtime.goexit()
        /usr/local/go/src/runtime/asm_amd64.s:1581 +0x1 fp=0xc00009dfe8 sp=0xc00009dfe0 pc=0x476f41

rax    0x0
rbx    0x7f57bb0e4700
rcx    0x7f57ee3db18b
rdx    0x0
rdi    0x2
rsi    0x7f57bb0e24b0
rbp    0x7f57a8923520
rsp    0x7f57bb0e24b0
r8     0x0
r9     0x7f57bb0e24b0
r10    0x8
r11    0x246
r12    0x7f57a8922bb0
r13    0x7f57eebbefb0
r14    0x7f57a89234e0
r15    0x7f57bb0e27a0
rip    0x7f57ee3db18b
rflags 0x246
cs     0x33
fs     0x0
gs     0x0
exit status 2

The following code allows to reproduce the issue. It is a piece of code from a larger application; it is provided to help diagnose the issue.

package main

import (
	"fmt"
	"image"
	"image/jpeg"
	"os"

	"gocv.io/x/gocv"
)

func main() {
	b, bc, br, r, c, qrValue, err := IsWhitePage("demo.jpg", true)
	fmt.Printf("%v %v %v %v %v %v %v", b, bc, br, r, c, qrValue, err)
}

func IsWhitePage(imgPath string, detectQRCodes bool) (b bool, bc int, br float32, r int, c int, qrValue string, err error) {
	defer func() {
		if err := recover(); err != nil {
			fmt.Printf("ERROR checking WhitePage in [%s]; exception is %v", imgPath, err)
		}
	}()

	img := gocv.IMRead(imgPath, gocv.IMReadGrayScale)
	defer img.Close()

	sbdp := gocv.NewSimpleBlobDetectorParams()

	sbdp.SetMinThreshold(10)
	sbdp.SetMaxThreshold(200)
	sbdp.SetFilterByArea(true)
	sbdp.SetMinArea(20)
	sbdp.SetFilterByCircularity(false)
	sbdp.SetMinCircularity(0)
	sbdp.SetFilterByConvexity(false)
	sbdp.SetMinConvexity(0)
	sbdp.SetFilterByInertia(true)
	sbdp.SetMinInertiaRatio(0.01)

	bdp := gocv.NewSimpleBlobDetectorWithParams(sbdp)
	defer bdp.Close()

	kps := bdp.Detect(img)

	bc = len(kps)
	r = img.Rows()
	c = img.Cols()
	br = (float32(bc) / float32(r*c))

	if (br < 1e-6) || (bc < 100) {
		b = true
	}

	if !b && detectQRCodes {
		qImg := gocv.NewMat()
		defer qImg.Close()

		defer func() {
			if err := recover(); err != nil {
				fmt.Printf("ERROR checking QRCode in [%s]; exception is %v", imgPath, err)
			}
		}()

		fmt.Printf("Searching QRCode in [%s]", imgPath)
		_ = gocv.Threshold(img, &qImg, 128, 255, gocv.ThresholdBinary)
		qrValue, err = GetQRCode(qImg, imgPath)
	}

	return b, bc, br, r, c, qrValue, err
}

func GetQRCode(img gocv.Mat, srcFile string) (qrv string, err error) {
	qd := gocv.NewQRCodeDetector()
	defer qd.Close()

	var p gocv.Mat = gocv.NewMat()
	defer p.Close()

	var qs gocv.Mat = gocv.NewMat()
	defer qs.Close()

	defer func() {
		if err := recover(); err != nil {
			qrv = "QERR"
			fmt.Printf("ERROR reading QRCode in [%s]; exception is %v", srcFile, err)
		}
	}()

	err = os.WriteFile(fmt.Sprintf("%s.bin", srcFile), img.ToBytes(), 0644)
	ti, _ := img.ToImage()
	saveToFile(ti, fmt.Sprintf("%s.bw.jpg", srcFile))

	qrValue := qd.DetectAndDecode(img, &p, &qs)
	return qrValue, nil
}

func saveToFile(im image.Image, fn string) {
	var opt jpeg.Options
	opt.Quality = 100

	out, err := os.Create(fn)
	if err != nil {
		fmt.Println(err)
	}

	err = jpeg.Encode(out, im, &opt)
	if err != nil {
		fmt.Println(err)
	}
}

Steps to Reproduce

  1. Save the given code in a main.go file and prepare a standard go project with it
  2. Copy the attached JPEG file in the same folder and make sure the code matches the file name
  3. Run the example code

We are expecting the method to return an empty string, not the application to crash. The original code is being used on a large collection of JPEG files to detect white pages and search for QRCode values whenever there might be found (not all JPEG files will exhibit a QRCode). So far we have been able to sucessfully test several thousands of pages, but we hit a snag with the provided JPEG.

Your Environment

  • Operating System and version: ubuntu 20.04
  • OpenCV version used: 4.5.4
  • How did you install OpenCV? OpenCV was installed according to the Quick Install procedure described on the site https://gocv.io/getting-started/linux/
  • GoCV version used: 0.29.0
  • Go version: go1.17.3 linux/amd64
  • Did you run the env.sh or env.cmd script before trying to go run or go build? not needed

Thank you in advance for your help !

SoftExpert avatar Nov 23 '21 13:11 SoftExpert

Another crash that can be reproduced with the above example code:

Starting: /home/user/go/bin/dlv dap --check-go-version=false --listen=127.0.0.1:44571 --log-dest=3 from /home/user/go/src/goCVbug
DAP server listening at: 127.0.0.1:44571
Searching QRCode in [0620.jpg]
terminate called after throwing an instance of 'cv::Exception'
  what():  OpenCV(4.5.4) /tmp/opencv/opencv-4.5.4/modules/imgproc/src/convhull.cpp:143: error: (-215:Assertion failed) total >= 0 && (depth == CV_32F || depth == CV_32S) in function 'convexHull'
SIGABRT: abort
PC=0x7ff9dd3a218b m=8 sigcode=18446744073709551610

goroutine 0 [idle]:
runtime: unknown pc 0x7ff9dd3a218b
stack: frame={sp:0x7ff992fae6a0, fp:0x0} stack=[0x7ff9927b0650,0x7ff992fb0250)
0x00007ff992fae5a0:  0x0000000000000000  0x0000000000000000 
0x00007ff992fae5b0:  0x0000000000000000  0x0000000000000000 
0x00007ff992fae5c0:  0x0000000000000000  0x0000000000000000 
0x00007ff992fae5d0:  0xfffffffffffffff8  0x0000000000000001 
0x00007ff992fae5e0:  0x0000000000000000  0x0000000000000000 
0x00007ff992fae5f0:  0x0000000000000000  0x0000000000000030 
0x00007ff992fae600:  0x0000000000000007  0x0000000000000000 
0x00007ff992fae610:  0x0000000000000001  0x00007ff9dd7568b5
0x00007ff992fae620:  0x0000000000000000  0x0000000000000000 
0x00007ff992fae630:  0x0000000000000000  0x0000000000000000 
0x00007ff992fae640:  0x0000000000000000  0x0000000000000000 
0x00007ff992fae650:  0x0000000000000000  0xffffffffffffffff 
0x00007ff992fae660:  0x0000000000000000  0x0000000000000000 
0x00007ff992fae670:  0x0000000000000000  0x0000000000000000 
0x00007ff992fae680:  0x0000000000000000  0x0000000000000000 
0x00007ff992fae690:  0x00007ff992fae8c0  0x00007ff992fae8c8 
0x00007ff992fae6a0: <0x0000000000000000  0x335f5643203d3d20 
0x00007ff992fae6b0:  0x00007f8000007f80  0x00007f8000007f80 
0x00007ff992fae6c0:  0x0000000043910000  0x0000000000000000 
0x00007ff992fae6d0:  0x0000000043894000  0x0000000000000000 
0x00007ff992fae6e0:  0x0000000000000000  0x0000000000000000 
0x00007ff992fae6f0:  0x000000003a83126f  0x0000000000000000 
0x00007ff992fae700:  0xd6d5d4d3d2cac9c8  0xe4e3e2e1dad9d8d7 
0x00007ff992fae710:  0x0000000000000000  0x0000000000000000 
0x00007ff992fae720:  0xfffffffe7fffffff  0xffffffffffffffff 
0x00007ff992fae730:  0xffffffffffffffff  0xffffffffffffffff 
0x00007ff992fae740:  0xffffffffffffffff  0xffffffffffffffff 
0x00007ff992fae750:  0xffffffffffffffff  0xffffffffffffffff 
0x00007ff992fae760:  0xffffffffffffffff  0xffffffffffffffff 
0x00007ff992fae770:  0xffffffffffffffff  0xffffffffffffffff 
0x00007ff992fae780:  0xffffffffffffffff  0xffffffffffffffff 
0x00007ff992fae790:  0xffffffffffffffff  0xffffffffffffffff 
runtime: unknown pc 0x7ff9dd3a218b
stack: frame={sp:0x7ff992fae6a0, fp:0x0} stack=[0x7ff9927b0650,0x7ff992fb0250)
0x00007ff992fae5a0:  0x0000000000000000  0x0000000000000000 
0x00007ff992fae5b0:  0x0000000000000000  0x0000000000000000 
0x00007ff992fae5c0:  0x0000000000000000  0x0000000000000000 
0x00007ff992fae5d0:  0xfffffffffffffff8  0x0000000000000001 
0x00007ff992fae5e0:  0x0000000000000000  0x0000000000000000 
0x00007ff992fae5f0:  0x0000000000000000  0x0000000000000030 
0x00007ff992fae600:  0x0000000000000007  0x0000000000000000 
0x00007ff992fae610:  0x0000000000000001  0x00007ff9dd7568b5 
0x00007ff992fae620:  0x0000000000000000  0x0000000000000000 
0x00007ff992fae630:  0x0000000000000000  0x0000000000000000 
0x00007ff992fae640:  0x0000000000000000  0x0000000000000000 
0x00007ff992fae650:  0x0000000000000000  0xffffffffffffffff 
0x00007ff992fae660:  0x0000000000000000  0x0000000000000000 
0x00007ff992fae670:  0x0000000000000000  0x0000000000000000 
0x00007ff992fae680:  0x0000000000000000  0x0000000000000000 
0x00007ff992fae690:  0x00007ff992fae8c0  0x00007ff992fae8c8 
0x00007ff992fae6a0: <0x0000000000000000  0x335f5643203d3d20 
0x00007ff992fae6b0:  0x00007f8000007f80  0x00007f8000007f80 
0x00007ff992fae6c0:  0x0000000043910000  0x0000000000000000 
0x00007ff992fae6d0:  0x0000000043894000  0x0000000000000000 
0x00007ff992fae6e0:  0x0000000000000000  0x0000000000000000 
0x00007ff992fae6f0:  0x000000003a83126f  0x0000000000000000 
0x00007ff992fae700:  0xd6d5d4d3d2cac9c8  0xe4e3e2e1dad9d8d7
0x00007ff992fae710:  0x0000000000000000  0x0000000000000000 
0x00007ff992fae720:  0xfffffffe7fffffff  0xffffffffffffffff 
0x00007ff992fae730:  0xffffffffffffffff  0xffffffffffffffff 
0x00007ff992fae740:  0xffffffffffffffff  0xffffffffffffffff 
0x00007ff992fae750:  0xffffffffffffffff  0xffffffffffffffff 
0x00007ff992fae760:  0xffffffffffffffff  0xffffffffffffffff 
0x00007ff992fae770:  0xffffffffffffffff  0xffffffffffffffff 
0x00007ff992fae780:  0xffffffffffffffff  0xffffffffffffffff 
0x00007ff992fae790:  0xffffffffffffffff  0xffffffffffffffff 

goroutine 1 [syscall]:
runtime.cgocall(0x4f3010, 0xc00010d5b8)
	/usr/local/go/src/runtime/cgocall.go:156 +0x5c fp=0xc00010d580 sp=0xc00010d548 pc=0x41e63c
gocv.io/x/gocv._Cfunc_QRCodeDetector_DetectAndDecode(0x7ff99c001080, 0x4645540, 0x7ff970000ba0, 0x7ff970000c10)
	_cgo_gotypes.go:6709 +0x4d fp=0xc00010d5b8 sp=0xc00010d580 pc=0x4e3e0d
gocv.io/x/gocv.(*QRCodeDetector).DetectAndDecode.func1(0xc00010d858, {0x4645540, {0x0, 0x0, 0x0}}, 0xc00010d920, 0xc00010d900)
	/home/user/go/pkg/mod/gocv.io/x/[email protected]/objdetect.go:219 +0x12b fp=0xc00010d630 sp=0xc00010d5b8 pc=0x4e726b
gocv.io/x/gocv.(*QRCodeDetector).DetectAndDecode(0xc00010d858, {0x4645540, {0x0, 0x0, 0x0}}, 0xc00010d920, 0xc00010d900)
	/home/user/go/pkg/mod/gocv.io/x/[email protected]/objdetect.go:219 +0xa5 fp=0xc00010d6e0 sp=0xc00010d630 pc=0x4e70a5
main.GetQRCode({0x4645540, {0x0, 0x0, 0x0}}, {0x52c264, 0x8})
	/home/user/go/src/goCVbug/main.go:107 +0x2fc fp=0xc00010d970 sp=0xc00010d6e0 pc=0x4e8fbc
main.IsWhitePage({0x52c264, 0x8}, 0x1)
	/home/user/go/src/goCVbug/main.go:80 +0x9b4 fp=0xc00010ddf0 sp=0xc00010d970 pc=0x4e8654
main.main()
	/home/user/go/src/goCVbug/main.go:17 +0x51 fp=0xc00010df80 sp=0xc00010ddf0 pc=0x4e7931
runtime.main()
	/usr/local/go/src/runtime/proc.go:255 +0x1f3 fp=0xc00010dfe0 sp=0xc00010df80 pc=0x4519d3
runtime.goexit()
	/usr/local/go/src/runtime/asm_amd64.s:1581 +0x1 fp=0xc00010dfe8 sp=0xc00010dfe0 pc=0x47c3c1

rax    0x0
rbx    0x7ff992fb1700
rcx    0x7ff9dd3a218b
rdx    0x0
rdi    0x2
rsi    0x7ff992fae6a0
rbp    0x7ff9708ab6c0
rsp    0x7ff992fae6a0
r8     0x0
r9     0x7ff992fae6a0
r10    0x8
r11    0x246
r12    0x7ff9708a9980
r13    0x7ff9ddb85fb0
r14    0x7ff9708ab680
r15    0x7ff992fae990
rip    0x7ff9dd3a218b
rflags 0x246
cs     0x33
fs     0x0
gs     0x0
Process 60304 has exited with status 0
Detaching
dlv dap (59144) exited with code: 0

The image that produces the crash 0620

SoftExpert avatar Nov 24 '21 08:11 SoftExpert

The most upsetting part is the crash - there is no way to prevent it ! Can something be done to better catch the exception and to give more control over how to handle it ? Is it a bug in the gocv's implementation? Or a limitation in how the C bindings are handled in go ?

SoftExpert avatar Nov 24 '21 08:11 SoftExpert

Nobody has an idea on how to address this issue ?

SoftExpert avatar Jan 26 '22 07:01 SoftExpert