I have made a simple scala application that uses OpenCV-4.8.0 that extract face from image via Haar-Cascade (haarcascade_frontalface_default.xml
).
The above functionality working fine on local machine.
Now I’m trying to achieve same functionality through dockerization, for this I’ve followed, following steps.
Here is the build.sbt
, in which we are creating an Image via sbt-native-packager and then installed OpenCV-4.8.0 via dockerCommands
.
import com.typesafe.sbt.packager.docker._
ThisBuild / version := "0.1.0-SNAPSHOT"
ThisBuild / scalaVersion := "2.13.4"
lazy val root = (project in file("."))
.settings(
name := "human-verification-scala-service"
)
unmanagedBase := file("opencv4")
enablePlugins(JavaAppPackaging, DockerPlugin)
Docker / packageName := "human-verification-test"
Universal / javaOptions += "-Djava.library.path=/opencv4"
Docker / version := "0.0.1"
dockerExposedPorts := Seq(8083)
dockerChmodType := DockerChmodType.UserGroupWriteExecute
dockerPermissionStrategy := DockerPermissionStrategy.CopyChown
dockerAdditionalPermissions += (DockerChmodType.UserGroupPlusExecute, "/var/run/")
Docker / daemonUserUid := None
Docker / daemonUser := "root"
dockerBaseImage := "amazoncorretto:11-alpine3.18-jdk"
dockerCommands ++= Seq(
Cmd("RUN", "apk", "add", "--no-cache", "bash make cmake g++ wget unzip"),
Cmd("RUN", "apk", "add", "--no-cache", "linux-headers"),
Cmd("RUN", "wget", "-O", "opencv.zip", "https://github.com/opencv/opencv/archive/4.8.0.zip"),
Cmd("RUN", "unzip", "opencv.zip && rm opencv.zip"),
Cmd("RUN", "mkdir", "-p", "build && cd build && cmake ../opencv-4.8.0 && make -j4 && make install")
)
fork := true
libraryDependencies ++= Seq(
"com.typesafe" % "config" % "1.4.2",
"com.typesafe.akka" %% "akka-actor" % "2.6.0",
"com.typesafe.akka" %% "akka-stream" % "2.7.0",
"com.typesafe.akka" %% "akka-http" % "10.5.2",
"ch.qos.logback" % "logback-classic" % "1.4.11",
"com.typesafe.akka" %% "akka-http-spray-json" % "10.5.2",
"io.netty" % "netty-transport-native-epoll" % "4.1.99.Final" classifier "linux-x86_64"
)
→ Here in opencv4 directory we have .jar and .so files of OpenCV-4.8.0 for compiling code, and I’m creating it’s docker volume.
→ OpenCV is working fine in docker as I’ve tested it in another project as well.
Here is the code:
object CropImage extends App {
def getFace(imagePath: String): Mat = {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME)
val faceCascade = new CascadeClassifier("/opt/docker/opencv-4.8.0/data/haarcascades/haarcascade_frontalface_default.xml")
val image = Imgcodecs.imread(imagePath)
val gray = new Mat()
Imgproc.cvtColor(image, gray, Imgproc.COLOR_BGR2GRAY)
val faces = new MatOfRect()
faceCascade.detectMultiScale(gray, faces)
if (!faces.empty()) {
val faceRectArray = faces.toArray
val faceRect = faceRectArray(0)
val padding = 220
val startY = Math.max(0, faceRect.y - padding)
val endY = Math.min(image.rows(), faceRect.y + faceRect.height + padding)
val startX = Math.max(0, faceRect.x)
val endX = Math.min(image.cols(), faceRect.x + faceRect.width)
new Mat(image, new Rect(new Point(startX, startY), new Point(endX, endY)))
}
else {
new Mat()
}
}
getFace("/src/main/resources/MyImage.png")
}
→ /opt/docker/opencv-4.8.0/data/haarcascades/haarcascade_frontalface_default.xml
is available after installing OpenCV in docker image.
After doing docker:publishLocal
in sbt-shell it downloaded OpenCV and created the docker image.
Then I run image using docker-compose up
, here is docker-compose.yml
:
version: '3'
services:
scala-service:
image: human-verification-test:0.0.1
volumes:
- ./src/main/resources:/src/main/resources
- ./opencv4:/opencv4
ports:
- "8083:8083"
Unfortunately I’m getting an error:
scala-service_1 | # A fatal error has been detected by the Java Runtime Environment:
scala-service_1 | #
scala-service_1 | # SIGSEGV (0xb) at pc=0x00007f6a21b60ca9, pid=1, tid=81
scala-service_1 | #
scala-service_1 | # JRE version: OpenJDK Runtime Environment Corretto-11.0.21.9.1 (11.0.21+9) (build 11.0.21+9-LTS)
scala-service_1 | # Java VM: OpenJDK 64-Bit Server VM Corretto-11.0.21.9.1 (11.0.21+9-LTS, mixed mode, tiered, compressed oops, g1 gc, linux-amd64)
scala-service_1 | # Problematic frame:
scala-service_1 | # C [libopencv_java480.so+0x141ca9] Java_org_opencv_objdetect_CascadeClassifier_CascadeClassifier_11+0xf9
scala-service_1 | #
scala-service_1 | # Core dump will be written. Default location: Core dumps may be processed with "/usr/share/apport/apport -p%p -s%s -c%c -d%d -P%P -u%u -g%g -- %E" (or dumping to /opt/docker/core.1)
scala-service_1 | #
scala-service_1 | # An error report file with more information is saved as:
scala-service_1 | # /opt/docker/hs_err_pid1.log
humanverificationscalaservice_scala-service_1 exited with code 139
here is the hs_err_pid1.log
:
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j org.opencv.objdetect.CascadeClassifier.CascadeClassifier_1(Ljava/lang/String;)J+0
j org.opencv.objdetect.CascadeClassifier.<init>(Ljava/lang/String;)V+6
j blurriness.CheckBlurry$.getFace(Ljava/lang/String;Ljava/lang/String;)Lorg/opencv/core/Mat;+11
j blurriness.CheckBlurry$.isImageBlurry(Ljava/lang/String;Ljava/lang/String;)Lscala/Tuple2;+9
j faceverification.FaceVerification$.$anonfun$routes$7(Lscala/util/Try;)Lscala/Function1;+222
j faceverification.FaceVerification$$Lambda$684.apply(Ljava/lang/Object;)Ljava/lang/Object;+4
j akka.http.scaladsl.server.util.ApplyConverterInstances$anon$1.$anonfun$apply$1(Lscala/Function1;Lscala/Tuple1;)Lscala/Function1;+15
j akka.http.scaladsl.server.util.ApplyConverterInstances$anon$1$Lambda$325.apply(Ljava/lang/Object;)Ljava/lang/Object;+8
j akka.http.scaladsl.server.directives.FutureDirectives.$anonfun$onComplete$3(Lscala/Function1;Lakka/http/scaladsl/server/RequestContext;Lscala/util/Try;)Lscala/concurrent/Future;+9
Guide how can I resolve above error, and use haar-cascade
in docker container
.