I am working on an app that uses opencv to process video.
This is the opencv part of my function:
//Open the streams
var merged = VideoCapture()
merged.open(file.path)
var flicker = VideoCapture()
flicker.open("$cacheLocation/flicker.avi")
var grain = VideoCapture()
grain.open("$cacheLocation/oldgrain.avi")
//Check if all streams are opened
if (!merged.isOpened || !flicker.isOpened || !grain.isOpened){
Log.e("OpenCVHelper", "One or more streams did not open, ABORT!")
throw Exception()
}
val videoWriter = VideoWriter()
videoWriter.open("$location/$fileName", VideoWriter.fourcc('M', 'J', 'P', 'G'), merged.get(Videoio.CAP_PROP_FPS), Size(merged.get(Videoio.CAP_PROP_FRAME_WIDTH), merged.get(Videoio.CAP_PROP_FRAME_HEIGHT)))
//Setup variables
var totalFrames = merged.get(Videoio.CAP_PROP_FRAME_COUNT)
var grainFrames = grain.get(Videoio.CAP_PROP_FRAME_COUNT)
var flickerFrames = flicker.get(Videoio.CAP_PROP_FRAME_COUNT)
var grainCounter = 0
var flickerCounter = 0
//Setup mat's
var frameMat = Mat()
var rgbaFrame = Mat()
var whiteAlphaMat = Mat.ones(Size(merged.get(Videoio.CAP_PROP_FRAME_WIDTH), merged.get(Videoio.CAP_PROP_FRAME_HEIGHT)),0)
whiteAlphaMat.setTo(Scalar((255).toDouble()))
var videoTmpMat = mutableListOf<Mat>()
var videoRgbaMat = mutableListOf<Mat>()
var flickerMat = Mat()
var grainMat = Mat()
var tmp = Mat()
var alpha = Mat()
var rgb = mutableListOf<Mat>()
var rgba = mutableListOf<Mat>()
var flickerAlphaMat = Mat()
var grainAplhaMat = Mat()
for(frameCounter in 0..totalFrames.toInt()){
System.gc()
//Set the position of the readers
merged.set(Videoio.CAP_PROP_POS_FRAMES, frameCounter.toDouble())
grain.set(Videoio.CAP_PROP_POS_FRAMES, grainCounter.toDouble())
flicker.set(Videoio.CAP_PROP_POS_FRAMES, flickerCounter.toDouble())
//Create material of the current frame
merged.read(frameMat)
//Create an rgba mat of the frame
videoTmpMat.clear()
Core.split(frameMat, videoTmpMat)
videoRgbaMat.clear()
videoRgbaMat.add(videoTmpMat[0])
videoRgbaMat.add(videoTmpMat[1])
videoRgbaMat.add(videoTmpMat[2])
videoRgbaMat.add(whiteAlphaMat)
Core.merge(videoRgbaMat, rgbaFrame)
//Create the overlay materials
flicker.read(flickerMat)
grain.read(grainMat)
//Create rgba of the overlays
rgb.clear()
rgba.clear()
Imgproc.cvtColor(flickerMat, tmp, Imgproc.COLOR_BGR2GRAY)
Imgproc.threshold(tmp, alpha, (100).toDouble(), (255).toDouble(), Imgproc.THRESH_BINARY)
Core.split(flickerMat, rgb)
rgba.add(rgb[0])
rgba.add(rgb[1])
rgba.add(rgb[2])
rgba.add(alpha)
Core.merge(rgba, flickerAlphaMat)
//tmp = Mat()
//alpha = Mat()
//rgb = mutableListOf()
//rgba = mutableListOf()
rgb.clear()
rgba.clear()
Imgproc.cvtColor(grainMat, tmp, Imgproc.COLOR_BGR2GRAY)
Imgproc.threshold(tmp, alpha, (100).toDouble(), (255).toDouble(), Imgproc.THRESH_BINARY)
Core.split(grainMat, rgb)
rgba.add(rgb[0])
rgba.add(rgb[1])
rgba.add(rgb[2])
rgba.add(alpha)
Core.merge(rgba, grainAplhaMat)
//Apply blur to the frame
Imgproc.blur(rgbaFrame, rgbaFrame, Size((8).toDouble(),(8).toDouble()))
//Apply flicker to the frame
Core.addWeighted(rgbaFrame, 1.0, flickerAlphaMat, 0.5, 0.0, rgbaFrame)
//Apply grain to the frame
Core.addWeighted(rgbaFrame, 1.0, grainAplhaMat, 0.5, 0.0, rgbaFrame)
//Add a title
Imgproc.putText(rgbaFrame, "Made with Super8Life", Point(10.0, 1050.0), 7, 2.0, Scalar(255.0,255.0,255.0), 2);
//Write frame to file
videoWriter.write(rgbaFrame)
//Clear up memory
//frameMat.release()
//flickerAlphaMat.release()
//flickerMat.release()
//grainAplhaMat.release()
//grainMat.release()
//videoTmpMat.forEach {
// it.release()
//}
//videoRgbaMat.forEach {
// it.release()
//}
//whiteAlphaMat.release()
//Handle the counters
Log.d("OpenCVHelper", "Frame: $frameCounter")
//val percentage = frameCounter.toDouble() / totalFrames * 100.toDouble()
//Log.d("OpenCVHelper", "$percentage%")
if (grainCounter < grainFrames -1){
grainCounter ++;
} else {
grainCounter = 0;
}
if (flickerCounter < flickerFrames -1){
flickerCounter ++;
} else {
flickerCounter = 0;
}
}
videoWriter.release()
It eats up memory 4 of the 5 times of testing the app and that causes the app to crash.
I don't understand what I'm doing wrong? I have already moved the declaration of the Mat's outside the loop. Mat.release() doesn't do anything
thx a lot, Jules