gocv icon indicating copy to clipboard operation
gocv copied to clipboard

static build: Error opening file

Open Rehtt opened this issue 2 years ago • 2 comments

Open the video file through the statically compiled (make install_static) program and report an error:

panic: Error opening file: 1.mp4

but the same code can run normally in a non-statically compiled (make install) program

Rehtt avatar Aug 07 '21 04:08 Rehtt

code :

package main

import (
	"fmt"
	"gocv.io/x/gocv"
	"golang.org/x/crypto/ssh/terminal"
	"image/color"
	"os"
	"strings"
	"time"
)

func main() {
	c, err := gocv.VideoCaptureFile("1.mp4")
	if err != nil {
		panic(err)
	}
	thisMat := gocv.NewMat()
	previousMat := gocv.NewMat()
	writerMat := gocv.NewMat()
	tmp := gocv.NewMat()
	w, err := gocv.VideoWriterFile("test1.mp4", c.CodecString(), c.Get(gocv.VideoCaptureFPS), int(c.Get(gocv.VideoCaptureFrameWidth)), int(c.Get(gocv.VideoCaptureFrameHeight)), true)
	count := int(c.Get(gocv.VideoCaptureFrameCount))
	f := 0
	t := time.Now()
	tt := gocv.NewMat()

	for c.Read(&thisMat) {
		if tt.Empty() {
			tt = gocv.NewMatWithSize(thisMat.Rows(), thisMat.Cols(), thisMat.Type())
		}
		thisMat.CopyTo(&tmp)
		gocv.CvtColor(thisMat, &thisMat, gocv.ColorBGRToGray)
		gocv.Threshold(thisMat, &thisMat, 200, 255, gocv.ThresholdBinary)
		if !previousMat.Empty() {
			gocv.AbsDiff(previousMat, thisMat, &writerMat)
			contours := gocv.FindContours(writerMat, gocv.RetrievalExternal, gocv.ChainApproxSimple)
			tt.CopyTo(&writerMat)
			for i := 0; i < contours.Size(); i++ {
				if gocv.ContourArea(contours.At(i)) > 3000 {
					gocv.DrawContours(&writerMat, contours, i, color.RGBA{0, 255, 0, 0}, 2)
				}
			}

			w.Write(writerMat)
		}
		thisMat.CopyTo(&previousMat)
		f++
		renderbar(f, count)
	}
	fmt.Println("\n完成\n用时:",  time.Now().Sub(t))
	if err = w.Close(); err != nil {
		panic(err)
	}

	//mat:=cv.NewMatWithSizeFromScalar(cv.NewScalar(255, 255, 255, 0.0),1080,1920,cv.MatTypeCV8UC3)
	////cv.Threshold(mat,&mat,200,255,cv.ThresholdBinary)
	//cv.IMWrite("t.jpg",mat)
	//fmt.Println(mat.GetIntAt(1,1))
}

//func show(index, count int) string {
//	w, _, err := terminal.GetSize(int(os.Stdout.Fd()))
//	if err != nil {
//		panic(err)
//	}
//
//}

func renderbar(count, total int) {
	fmt.Print("\x1b7")   // 保存光标位置 保存光标和Attrs <ESC> 7
	fmt.Print("\x1b[K") // 清空当前行的内容 擦除线<ESC> [2K
	w, _, _ := terminal.GetSize(int(os.Stdout.Fd()))
	barwidth := w - len("Progress: 100% []")
	done := int(float64(barwidth) * float64(count) / float64(total))
	fmt.Printf("Progress: ")
	fmt.Printf("[%s\u001B[33m%3d%%\u001B[0m%s]",
		strings.Repeat("=", done),
		count*100/total,
		strings.Repeat("-", barwidth-done),
	)
	fmt.Print("\x1b8") // 恢复光标位置 恢复光标和Attrs <ESC> 8
}

Rehtt avatar Sep 23 '21 09:09 Rehtt

Dear @Rehtt

It's because Video IO module in opencv used various backends and couldn't find the appropriate one. When you do make install_static, it will ignore ffmpeg (license issue). So it will return error when reading the input file.

Workaround that works for me

  1. I modify the MakeFile in section build_static to -Dwith_ffmpeg=ON, so i will use ffmpeg as IO backend
  2. on c_main.go, i added the flag -lavutil -lavcodec -lavformat -lswscale

Basically, you need to know about the dependency used by the function you will use and you need to link them properly

cmiiw @deadprogram

kennykarnama avatar Mar 30 '22 06:03 kennykarnama